Elasticsearchの原理分析-ノードの起動とシャットダウン
記事ディレクトリ
この章では、単一ノードの起動およびシャットダウンプロセスを分析します。 構成 を解析するプロセスを 確認する方法、環境、内部初期化モジュールを確認する方法、および時間のノード**「キル」**を処理する方法。
1.起動プロセスは何をしましたか
一般に、ノード起動プロセスのタスクは、次のタイプの作業を実行することです。
- 構成ファイルやコマンドラインパラメーターなど、構成を解析します。
- JVMバージョン、オペレーティングシステムカーネルパラメータなどの外部環境と内部環境を確認します。
- 内部リソースを初期化し、内部モジュールを作成し、検出器を初期化します。
- 各サブモジュールとキープアライブスレッドを開始します。
2.起動プロセスの分析
2.1開始スクリプト
起動スクリプトbin / elasticsearchを介してESを起動すると、スクリプトはexecを介してJavaプログラムをロードします。コードは次のように表示されます。
exec \ #执行命令
"$JAVA" \ #Java程序路径
$ES_JAVA_OPTS \ #JVM选项
-Des.path.home="$ES_HOME" \ #设置path.home路径
-Des.path.conf="$ES_PATH_CONF" \ #设置path.conf路径
-Des.distribution.flavor="$ES_DISTRIBUTION_FLAVOR" \
-Des.distribution.type="$ES_DISTRIBUTION_TYPE" \
-cp "$ES_CLASSPATH" \ #设置 java classpath
org.elasticsearch.bootstrap.Elasticsearch \ #指定main函数所在类
"$@" #传递给main函数命令行参数
ES_JAVA_OPTS変数はJVMパラメーターを保持し、その内容はconfig /jvm.options構成ファイルの分析から取得されます。
起動スクリプトの実行時に-dパラメーターが追加された場合:
bin/elasticsearch -d
次に、起動スクリプトはexecに<&-&を追加します。<&-の機能は、プロセスの0番目のfdである標準入力を閉じることです。&の機能は、プロセスをバックグラウンドで実行することです。
2.2コマンドラインパラメータと設定ファイルの解析
現在サポートされているコマンドラインパラメータは次のとおりです。次の表に示すように、デフォルトでは起動時に使用されません。
パラメータ | 意味 |
---|---|
-E | 構成をセットアップします。たとえば、クラスター名を設定するには、次のようにします。-E "cluster.name = my_cluster"。これは通常、コマンドラインではなく、構成ファイルを介して設定されます。 |
-V、-version | バージョン番号情報を印刷する |
-d、-daemonize | バックグラウンドスタート |
-h、-help | ヘルプ情報を印刷する |
-p、-pidfile | 起動時に指定されたパスにpidファイルを作成します。これにより、現在のプロセスのpidが保存されます。その後、pidファイルを表示してプロセスを閉じることができます。 |
-q、-quiet | コンソールの標準出力と標準エラー出力をオフにします |
-s、-silent | 端子出力の最小情報(デフォルトは通常) |
-v、-verbose | 端子出力詳細情報 |
実際のエンジニアリングアプリケーションでは、起動パラメータに-dと-pを追加することをお勧めします。次に例を示します。
bin/elasticsearch -d -p es.pid
ここで解析される次の2つの構成ファイルがあります。jvm.optionsは起動スクリプトで解析されます。
- elasticsearch.yml#Main構成ファイル
- log4j2.properties#Log構成ファイル
2.3ロードセキュリティ構成
セキュリティ構成とは何ですか?基本的には構成情報ですが、構成情報であるため、通常は構成ファイルに書き込まれます。ESのいくつかの構成ファイルについては、前の章で説明しました。ここでの「セキュリティ構成」は、構成ファイルがプレーンテキストで保存されているため、一部の機密情報を構成ファイルに配置するのに適していないことを解決するためのものです。ファイルシステムはユーザー権限に基づいて保護されていますが、それでも十分ではありません。したがって、ESはこれらの機密構成情報を暗号化し、それを別のファイルconfig /elasticsearch.keystoreに配置します。次に、構成を表示、追加、および削除するためのコマンドをいくつか提供します。
セキュリティ構成ファイルに配置するのに適した構成情報はどのようなものですか?たとえば、X-Packのセキュリティ関連の構成、LDAP base_dn、およびその他の情報(サーバーにログインするためのユーザー名とパスワードに相当)。
2.4内部環境を確認する
内部環境とは、ESソフトウェアパッケージ自体の整合性と正確性を指します。含める:
- Luceneのバージョンを確認します。ESの各バージョンではLuceneのバージョンを使用する必要があります。互換性のないjarパッケージを誰かが置き換えないように、ここでLuceneのバージョンを確認してください。
- jarの競合を確認し、競合が見つかった場合はプロセスを終了します。
2.5外部環境を確認する
ESの「ノード」は、実装時にノードモジュールとしてカプセル化されます。Nodeクラスの他の内部コンポーネントを呼び出し、外部に起動メソッドとシャットダウンメソッドを提供します。外部環境の検査はNode.start()で実行されます。
外部環境とは、実行時にJVMおよびオペレーティングシステムに関連するパラメータを指します。これらは、ESでは「BoostrapCheck」と呼ばれます。初期のESバージョンでは、ESはいくつかの不合理な構成を検出し、それをログに記録して実行を継続しました。しかし、ユーザーがこれらのログを見逃すことがあります。後で問題が検出されないようにするために、ESは起動フェーズでこれらの重要なパラメータをチェックします。パフォーマンスに影響する一部の構成はエラーとしてマークされるため、ユーザーはこれらのパラメータに十分注意を払うことができます。
これらのチェックはすべて、BoostrapChecksクラスに個別にカプセル化されています。現在、以下の検出項目があります。
2.5.1ヒープサイズチェック
場合JVM初期ヒープサイズ(XMS)が最大ヒープサイズ(Xmxの)とは異なる、そこ休止することができるJVMのヒープサイズが調整され、使用中。したがって、同じ値に設定する必要があります。
bootstrap.mempry_blockが有効になっている場合、JVMは起動時にペアの初期サイズをロックします。初期ヒープサイズが最大ヒープサイズと異なる場合、ヒープサイズが変更された後、すべてのJVMヒープがメモリにロックされるとは限りません。
このチェックに合格するには、ヒープサイズを構成する必要があります。
2.5.2ファイル記述子のチェック
UNIXベースのシステムでは、「ファイル」は通常の物理ファイルまたは仮想ファイルであり、ネットワークソケットもファイル記述子です。ESプロセスには、多くのファイル記述子が必要です。たとえば、各フラグメントには多くのセグメントがあり、各セグメントには多くのファイルがあります。また、他のノードとの多くのネットワーク接続も含まれます。
このチェックに合格するには、システムのデフォルト構成を調整する必要があります。Linuxでは、ulimit -n 65536(現在の端末でのみ有効)を実行するか、** / etc / security / limits.conf *ファイル(すべてのユーザーで有効)で「 --nofile65536 」を構成します。UbuntuでのLimits.confはデフォルトで無視され、pam_limits.soモジュールを有効にする必要があります。
Ubuntuのバージョンは比較的迅速に更新され、実稼働環境は頻繁な更新には適していないため、サーバーのオペレーティングシステムとしてCentOSを使用することをお勧めします。
* soft nofile 131072
* hard nofile 131072
2.5.3メモリロックチェック
ESを使用すると、プロセスは物理メモリのみを使用でき、スワップパーティションの使用を回避できます。実際、実稼働環境では、オペレーティングシステムのスワップパーティションを直接無効にすることをお勧めします。これで、メモリ不足のためにメモリをハードディスクにスワップする必要がある時代が到来しました。サーバーの場合、メモリが実際に使い果たされると、ハードディスクにスワップするとさらに問題が発生します。
bootstrap.memory_lockオプションを有効にして、ESがメモリをロックできるようにします。このチェックがオンになっていてロックが失敗すると、このチェックの実行は失敗します。
2.5.4スレッドチェックの最大数
ESは要求を各ノードで実行に分解し、各ステージは異なるスレッドプールを使用して実行します。したがって、ESプロセスは多くのスレッドを作成する必要があります。このチェックは、ESプロセスが十分なスレッドを作成する権限を持っていることを確認するためのものです。このチェックは、Linuxシステムでのみ実行されます。プロセスが作成できるスレッドの最大数を調整する必要があります。この値は少なくとも2048です。
このチェックに合格するには、** / etc / security / limits.confファイルのnprocを変更して構成を完了します。
* soft nproc 131072
* hard nproc 131072
そして/etc/security/limits.d/90-nproc.conf
* soft nproc 131072
* hard nproc 131072
2.5.5最大仮想メモリチェック
Luceneは、mmapを使用して、インデックスの一部をプロセスアドレススペースにマップします。最大仮想メモリチェックにより、ESプロセスに十分なアドレススペースがあることが保証されます。このチェックは、Linuxでのみ実行されます。
このチェックを渡すには、**の/ etc /セキュリティ/ limits.confをの変更することができますファイルとセットのように**無制限。
* soft as unlimited
* hard as unlimited
2.5.6最大ファイルサイズのチェック
セグメントファイルとトランザクションログファイルはローカルディスクに保存されており、非常に大きい場合があります。最大ファイルサイズ制限のあるオペレーティングシステムでは、書き込みエラーが発生する可能性があります。最大のファイルのサイズを無制限に設定することをお勧めします。
このチェックに合格するには、** / etc / security / limits.confファイルを変更し、 fsizeを無制限**に変更します。
* soft fsize unlimited
* hard fsize unlimited
2.5.7仮想メモリ領域の最大数の確認
ESプロセスは、多くのメモリマップ領域を作成する必要があります。このチェックは、カーネルが少なくとも262144のメモリマップ領域の作成を許可していることを確認するためのものです。このチェックはLinuxでのみ実行されます。
このチェックに合格するには、次のコマンドを実行できます(一時的に有効、再起動後は無効)。
sysctl -w vm.max_map_count = 262144
または、行vm.max_map_count = 262144 **を** / etc / sysctl.confファイルに追加してから、次のコマンドを(即時および永続的に)実行します。
vm.max_map_count=262144
sysctl -p
2.5.8OnErrorおよびOnOutOfMemoryErrorチェック
JVMで致命的なエラー(OnError)または(OnOutOfMemoryError)が発生した場合、JVMオプションのOnErrorおよびOnOutOfMemoryErrorは任意のコマンドを実行できます。
ただし、デフォルトでは、ESシステム呼び出しフィルターが有効になっており(seccomp)、フォークはブロックされます。したがって、OnErrorまたはOnOutOfMemoryErrorの使用は、システム呼び出しフィルターと互換性がありません。
このチェックに合格するには、OnErrorまたはOnOutOfMemoryErrorを有効にせずに、Java 8u92にアップグレードして、ExitOnOutOfMemoryErrorを使用します。
ESノードがデッド状態になり、メモリオーバーフロー後に回復できなくなり、クラスター全体に影響が及ぶのを防ぎます。プロセスがOOMと表示されると、プロセスはシャットダウンされ、ESクラスターを終了してアラームが発生し、再起動します。
config /jvm.optionsにJVM起動パラメーターを追加します。
-XX:+ExitOnOutOfMemoryError
2.6内部モジュールを起動します
環境チェックが完了したら、各サブモジュールを起動します。サブモジュールはNodeクラスで作成され、それぞれのstart()メソッドは、起動時に呼び出されます。次に例を示します。
- Discovery.start();
- clusterServer.start();
- nodeConnectionsService.start();
サブモジュールのstartメソッドは、基本的に、内部データの初期化、スレッドプールの作成、スレッドプールの開始、およびその他の操作です。
2.7キープアライブスレッドを開始します
keepAliveThread.start()メソッドを呼び出して、キープアライブスレッドを開始します。スレッド自体は、特定の作業を行いません。メインスレッドは、起動プロセスの実行後に終了します。キープアライブスレッドは唯一のユーザースレッドであり、その役割はプロセスの実行を維持することです。Javaプログラムでは、ユーザースレッドは1つだけです。ヨーグルトスレッドの数がゼロになったら、プロセスを終了します。
3.ノードシャットダウンプロセス
次に、単一ノードのシャットダウンプロセスについて説明します。構成を更新してESクラスターのバージョンをアップグレードするときに、ノードをシャットダウンするためにESプロセスを「強制終了」する必要があると想像してください。しかし、キル操作は安全ですか?この時点でノードが読み取りおよび書き込み操作を実行している場合、どのような影響がありますか?ノードがマスターの場合、マスターは何をすべきですか?クロージングプロセスはどのように達成されますか?キルノードはどのようなリスクをもたらしますか?
答えは次のとおりです。ESプロセスは、処理のためにSIGTERM信号(killコマンドのデフォルト信号)をキャプチャし、各モジュールのstopメソッドを呼び出し、サービスを停止して安全に終了する機会を提供します。
-
マスターノードがシャットダウンされます
クラスターの再起動中にマスターノードがシャットダウンされると、クラスターはマスターを再選択します。この期間中、クラスターはマスターがないという短期間の状態になります。クラスタ内のマスターノードが個別にデプロイされている場合、新しいマスターが選択された後、ゲートウェイとリカバリプロセスをスキップできます。そうでない場合、新しいマスターは古いマスターが保持しているシャードを再配布する必要があります。他のレプリカをマスターシャードに昇格させて割り当てます。新しいレプリカフラグメント。
-
データノードがシャットダウンされます
データノードが閉じている場合、読み取りおよび書き込み要求のTCP接続も閉じられ、クライアントの書き込み操作は失敗します。ただし、書き込みプロセスがエンジンリンクに到達した場合、書き込みは正常に終了しますが、クライアントは結果を認識できません。このとき、クライアントは再試行します。自動生成されたIDを使用すると、データの内容が繰り返されます。
要約すると、ローリングアップグレードの影響は、現在の書き込み要求の中断と、マスターノードの再起動によって引き起こされる可能性のあるフラグメント割り当てプロセスです。一般に、新しいプライマリシャードをアップグレードする方が高速であるため、クラスターの書き込みの可用性にはほとんど影響しません。
インデックス部分のプライマリシャードが割り当てられていない場合、自動生成されたIDを使用すると、書き込みが続行されると、クライアントは失敗の再試行に成功する可能性があります(要求は正常に割り当てられたプライマリシャードに到達します)が、データスキューはスライス間で発生し、スキューの程度は期間の数によって異なります。
4.プロセス分析を閉じる
ノードの起動プロセス中に、Bootstrap#setupメソッドにシャットダウンフックが追加されます。プロセスがシステムSIGTERM(デフォルト信号の強制終了)またはSIGINT信号を受信すると、ノードシャットダウンプロセスが呼び出されます。
各モジュールのサービスにはdoStopとdoCloseがあり、これらはこのモジュールの通常の終了プロセスを処理するために使用されます。ノードの一般的な終了プロセスはNode#cloaseにあります。closeメソッドの実装では、最初に各モジュールのdoStopを呼び出してから、各モジュールを再度トラバースしてdoCloseを実行します。主な実装コードは次のとおりです。
if(lifecycle.started()){
stop();//调用各个模块的dostop方法
}
List<Closeable> toClose = new ArrayList<>();
//在toClose中添加所需要关闭的Service,以nodeService为例
toClose.add(nodeService);
......
//调用各模块doClose方法
IOUtils.close(toClose);
各モジュールの終了には、特定のシーケンス関係があります。doStopを例にとると、次の表に示す順序で各モジュールのdoStopメソッドを呼び出します。
サービス | 前書き |
---|---|
ResourceWatcherService | 一般的なリソース監視サービス |
HttpServerTransport | HTTP伝送サービス、RESTインターフェースサービスを提供 |
スナップショットサービス | スナップショットサービス |
SnapshotShardsService | シャードレベルのスナップショットの開始と停止を担当します |
IndicesClusterStateService | クラスタステータス情報を受け取った後、インデックス関連の操作を処理します |
発見 | クラスタートポロジー管理 |
RoutingService | 再ルーティングの処理(ノード間でのシャードの移行) |
ClusterService | クラスター管理サービス。主にクラスタータスクを処理し、クラスターステータスを公開します |
NodeConnectionsService | ノード接続パイプラインサービス |
MonitorService | プロセスレベル、システムレベル、ファイルシステム、およびJVM監視サービスを提供します |
GatewayService | クラスタメタデータの永続性と回復を担当します |
SearchService | 検索リクエストの処理 |
TransportService | 基礎となる輸送サービス |
プラグイン | 現在のすべてのプラグイン |
IndicesService | インデックスの作成や削除などのインデックス操作を担当します |
まとめると、終了シーケンスはおおまかに次のようになります。
- スナップショットとHTTPServerを閉じ、ユーザーのREST要求に応答しなくなります。
- マシントポロジ管理を閉じて、ping要求に応答しなくなります。
- ネットワークモジュールを閉じて、ノードをオフラインにします。
- 各プラグインの終了プロセスを実行します。
- IndicatorsServiceを閉じます。
最後に、この期間中に解放する必要のあるリソースが最も長く、最も長いため、IndicatorServiceは閉じられます。
5.フラグメントの読み取りおよび書き込み中にシャットダウンを実行します
以下は、読み取りおよび書き込み実行プロセス中に閉じられたノードを分析します。
5.1書き込み中は閉じています
スレッドがデータを書き込むと、エンジンに書き込みロックが追加されます。IndicesServiceのdoStopメソッドは、このノードのすべてのインデックスにインデックスを付け、removeIndexを実行します。エンジンのflushAndCloseが実行されると(最初にフラッシュしてからエンジンを閉じる)、エンジンに書き込みロックも追加されます。書き込みロックが書き込み操作に追加されているため、書き込みロックは書き込みが完了するまで待機します。したがって、データ書き込みプロセスが中断されることはありません。ただし、ネットワークモジュールが閉じているため、クライアント接続は切断されます。ESサーバーの書き込みプロセスはまだ続行されていますが、クライアントは障害を処理する必要があります。
5.2読み取りプロセスを閉じます
スレッドがデータを読み取ると、エンジンに読み取りロックが追加されます。flushAndCloseの書き込みロックは、読み取りプロセスの完了を待ちます。ただし、接続が閉じているため、クライアントに送信できず、クライアントは読み取りに失敗します。
次の図は、エンジンのflushAndCloseのプロセスを示しています。
ノードのシャットダウンプロセス中に、IndicatorServiceのdoStopがエンジンのタイムアウトを設定します。flushAndが待機している場合、CountDownLatch.awaitはデフォルトで次のプロセスを1日間続行します。
6.マスターノードがシャットダウンされます
マスターノードがシャットダウンされると、想像どおりの特別な処理はありません。ノードはシャットダウンプロセスを正常に実行します。TransportSericeモジュールがシャットダウンされると、クラスターは新しいマスターを再選択します。したがって。ローリングリスタート中は、所有されていない状態で一定期間があります。
7.まとめ
- 一般的に、ノードの起動プロセスは初期化とチェックです。各サブモジュールは非同期で起動した後、ローカルデータをロードするか、マスターを選択し、クラスターに参加するなど、次の章で個別に紹介します。
- ノードは、シャットダウン時に未完了のデータを処理する機会がありますが、書き込み後にクライアントに通知するのに遅すぎることはありません。スレッドプールでまだ実行されていないタスクを含め、特定のタイムアウト期間内に実行される可能性があります。
クラスターの状態が赤から緑に変化する時間は、主にプライマリシャードとセカンダリシャードの一貫性を維持するために費やされます。クラスタの状態が黄色のときにクライアントに書き込みを許可することもできますが、データのセキュリティがいくらか犠牲になります。
/etc/security/limits.conf
文件描述符配置
* soft nofile 131072
* hard nofile 131072
最大线程数检查
* soft nproc 131072
* hard nproc 131072
/etc/security/limits.d/90-nproc.conf
* soft nproc 1024
最大虚拟内存检查
* soft as unlimited
* hard as unlimited
最大文件大小检查
* soft fsize unlimited
* hard fsize unlimited
虚拟内存区域最大数量检查
/etc/sysctl.conf
vm.max_map_count=262144
件描述符配置
* soft nofile 131072
* hard nofile 131072
最大线程数检查
* soft nproc 131072
* hard nproc 131072
/etc/security/limits.d/90-nproc.conf
* soft nproc 1024
最大虚拟内存检查
* soft as unlimited
* hard as unlimited
最大文件大小检查
* soft fsize unlimited
* hard fsize unlimited
虚拟内存区域最大数量检查
/etc/sysctl.conf
vm.max_map_count=262144
8.フォローしてください
WeChatパブリックアカウントを検索:強力なJavaアーキテクチャへの道