ESクラスタの高可用性実装
9918 ワード
ESクラスタの高可用性は、読み取り高可用性、書き込み高可用性、および変更(クラスタ状態の変更)が発生した場合に高可用性に分けられる.一部のクラスタ状態の変化は、読み取りと書き込みの高可用性に影響を与えるため、実際には正確ではありません.読み取り高さとは、複数のレプリカの場合、あるレプリカに問題が発生した場合にシステム全体の読み取りに影響を与えないことを意味します.書き込み高さは、複数のコピーの場合、あるコピーに問題が発生した場合、システム全体の書き込みに影響を与えず、translogによってデータが失われないことを保証します.クラスタ状態の変化の高利用可能性は、自動処理ノードの加入と離脱、自動同期変化のクラスタ状態、クラスタに障害が発生した場合に主副shardなどを自動的に切り替えてクラスタの高利用可能性を維持することを含む.読み書きの高さはここでは説明しないが、クラスタ状態が変化したときの高さを3つの部分で説明する.
1、クラスタ状態同期
cluster stateはグローバル情報であり、クラスタ全体のすべてのスライスのメタ情報(ルール、位置、サイズなどの情報)を含み、各セクションの情報の同期を維持します.クラスタのステータスの詳細は、ブログを表示します.https://www.jianshu.com/p/f46074d95daa. cluster stateはESのmasterノードによって維持され(プライマリノードのみがクラスタ状態を変えることができる)、dataノードの状態更新の変化を受信すると、これらの情報を他のノードに順次ブロードキャストする.現在、クラスタのcluster stateは60 M程度ですが、クラスタの状態が変化すると、プライマリノードは全体のcluster stateをブロードキャストしますか?クラスタ状態を同期すると、ESは追加の処理を行います.は、変化するcluster state情報のみがブロードキャストされる . cluster state伝達前または圧縮 具体的なプロセスは、1、プライマリノードが変更されたクラスタ状態を処理し、変更された状態publishを他のすべてのノードに与える.2、他のノードは、プライマリノードpublishのメッセージを受信し、プライマリノードに受信情報(acknowledge.it)を確認するが、変更をローカルのクラスタ状態(not applay it)3に同期させず、プライマリノードが構成された時間(discovery.zen.commit_timeoutデフォルト30 s)に指定された数のノード(discovery.zen.minimum_master_nodes)を受信していない場合、その変更の状態はrejectedされる.4、マスターノードが指定された時間内に指定された数のノードの確認情報を受信した場合、その状態の変更がコミットされ、他のノードに送信される.5、他のノードが情報を受信すると、それを適用してローカルのクラスタ状態に変更し、適用した後にメインノードに適用成功情報を送信する.6.メインノードは、タイムアウトするまで、すべてのノードから送信されたアプリケーション成功メッセージを待機する(discovery.zen.publish_timeoutデフォルト30 s).
2、ノードの加入と離脱
2.1、ノード加入
新しいノードが追加されるとdiscoveryを通過します.zen.ping.unicast.hosts構成のノードはクラスタ状態を取得し、masterノードを見つけてjoin request(discovery.zen.join_timeout)を送信します.プライマリノードはreqestを受信すると、クラスタ状態を新しいノードに同期します.
2.2、非主ノードが離れる
1つのノードでpingが3回も通じない場合(ping_intervalのデフォルトは1 s、ping_timeoutのデフォルトは30 s)、プライマリノードはノードがダウンタイムしたと判断し、ノードをクラスタから蹴り出す.
2.3、主ノードが離れる
プライマリノードに障害が発生すると、クラスタ内の他のノードが現在のmaster eligibleノードをpingし、そこから新しいプライマリノードを選択します.ノードはnodeを設定することができる.masterはfalseになって自分がプライマリノードになることを阻止します.discoveryを構成する.zen.minimum_master_Nodesはクラスタのsplit brainの発生を防止する.この構成は、クラスタ内のmaster eligibleの個数をチェックすることによって、プライマリノードが選択されたか否かを判断する.その個数は(number_master eligible/2)+1に設定することが好ましく、プライマリノードに問題が発生した場合、1つのクラスタが2つのクラスタに分裂することを防止する.最小番号のactive master eligible nodeがmasterノードに選択されます.選挙の詳細はブログを参照してください.https://www.jianshu.com/p/9454ac19921d
3、スライスコピーの同期
詳細は以下を参照してください.https://www.easyice.cn/archives/243.
ElasticsearchはAllocation IDsの概念を使用し、これは異なるスライスを区別する唯一の識別(UUIDS)である.Allocation IDsはshardレベルメタ情報に格納され、各shardには独自のAllocation IDがあり、クラスタレベルメタ情報にはin-sync allocation IDsと呼ばれる最新shardと考えられるAllocation IDの集合が記録される.ネットワークまたは他の理由でプライマリサブshardが同期していない場合、コピーのshardはin-sync allocation IDsから蹴り出されます.例:小さなクラスタ:プライマリノード1つ、データノード2つ.簡単な例を維持するために、1つのプライマリスライスと1つのセカンダリスライスのみのインデックスを作成します.最初は、1つのデータノードがプライマリスライスを所有し、もう1つのデータノードがセカンダリスライスを所有します.cluster state apiを使用してクラスタ状態のin-syncスライス情報を調べ、「filter_path」queryパラメータを使用して興味のある結果をフィルタします.
クラスタ状態は、プライマリスライスとセカンダリスライスの両方が起動していることを示し、プライマリスライスはデータノード「CX-rFmo」に割り当てられ、セカンダリスライスはデータノード「AzYoyz」に割り当てられる.彼らはすべて唯一のallocation idを持っていて、同時に、in_にも現れますsync_allocationsコレクションにあります.プライマリスライスが存在するノードを閉じると何が起こるか見てみましょう.これは、スライス上のデータを変更しないため、2つのスライスコピーは同期を維持する必要があります.プライマリスライスがない場合、サブスライスもプライマリスライスとして提示されるべきであり、これらはクラスタ状態に反映される.
1つのデータノードのみのため、サブスライスは未割当て状態にとどまる.2番目のノードを再起動すると、サブスライスはこのノードに自動的に割り当てられます.このシーンをより面白くするために、私は2番目のノードを起動しません.逆に、新しいアップグレードされたプライマリ・スライスにドキュメントをインデックスします.スライスコピーは現在相違しているため、アクティブでないどのスライスコピーが古くなったかは、プライマリノードによってin-syncセットから削除されます.
同期されたスライスコピーが1つしか残っていません.コピーが使用不可になった場合、システムがどのように処理するかを見てみましょう.このため、現在の一意のデータノードを閉じ、古いスライスコピーを持つ前のデータノードを起動します.その後、cluster health apiはcluser healthをredと表示し、クラスタステータスはプライマリスライスが割り当てられていないことを示します.
cluster allocation explain APIを見てみましょう.これは割り当ての問題をデバッグする良いツールです.パラメータなしのexplainコマンドを実行すると、システムが見つけた最初の未割当てスライスの説明が表示されます.
explain APIは、プライマリスライスが割り当てられていない理由を示し、各ノードに基づいたより詳細な割り当て情報も提供します.この例では、プライマリノードは、クラスタの現在使用可能なノードで同期された(in-sync)スライスコピーを見つけることができない.
このAPIはまた、ノード「CY−rFmo」で使用可能なスライスコピーが古いことを示す(store.in_sync=false).in-syncスライスのコピーを持つノードを起動すると、クラスタがgreenに再変更されます.もしそのノードが永遠に戻ってきたら?reroute APIは、サブコマンドallocateを提供します.stale_primaryは、古いスライスをプライマリスライスに割り当てるために使用されます.このコマンドを使用すると、指定したスライスコピーに欠落しているデータが失われます.同期スライスが一時的に使用できない場合、このコマンドを使用すると、同期コピーで最近更新されたデータが表示されます.クラスタに少なくともいくつかのデータを実行させる最後の措置と見なすべきです.すべてのスライスコピーが存在しない場合、Elasticsearchは、スライスに関連付けられたすべての以前のデータが失われることを意味する空のスライスコピーを使用してプライマリスライスを割り当てるように強制することもできる.言うまでもなく、allocate_empty_primaryコマンドは最悪の場合にのみ使用でき、その意味はよく理解されています.
4、その他の紹介
4.1、Pending Task
クラスタに問題が発生した場合、cat healthでpending taskが表示されます.pending taskはいったい何ですか.クラスタメタデータレベルの変更タスクを処理できるのはmasterノードのみです.ほとんどの場合、masterは処理できますが、クラスタメタデータの変更速度がmasterノードの処理速度を超えると、これらのメタデータ操作のタスクがキューにキャッシュされます.すなわちpending tasksです.pending task APIには、キュー内で保留中のすべてのクラスタメタデータが変更されたタスクが表示されます.cluster stateが大きすぎる場合、いくつかの変更はcluster stateを更新しやすく、cluster stateを更新すると多くのcpuが消費され、他のノードに転送されるネットワーク帯域幅が消費され、多くの時間がかかります.
ESクラスタを高可用性にするには
1、クラスタ状態同期
cluster stateはグローバル情報であり、クラスタ全体のすべてのスライスのメタ情報(ルール、位置、サイズなどの情報)を含み、各セクションの情報の同期を維持します.クラスタのステータスの詳細は、ブログを表示します.https://www.jianshu.com/p/f46074d95daa. cluster stateはESのmasterノードによって維持され(プライマリノードのみがクラスタ状態を変えることができる)、dataノードの状態更新の変化を受信すると、これらの情報を他のノードに順次ブロードキャストする.現在、クラスタのcluster stateは60 M程度ですが、クラスタの状態が変化すると、プライマリノードは全体のcluster stateをブロードキャストしますか?クラスタ状態を同期すると、ESは追加の処理を行います.
2、ノードの加入と離脱
2.1、ノード加入
新しいノードが追加されるとdiscoveryを通過します.zen.ping.unicast.hosts構成のノードはクラスタ状態を取得し、masterノードを見つけてjoin request(discovery.zen.join_timeout)を送信します.プライマリノードはreqestを受信すると、クラスタ状態を新しいノードに同期します.
2.2、非主ノードが離れる
1つのノードでpingが3回も通じない場合(ping_intervalのデフォルトは1 s、ping_timeoutのデフォルトは30 s)、プライマリノードはノードがダウンタイムしたと判断し、ノードをクラスタから蹴り出す.
2.3、主ノードが離れる
プライマリノードに障害が発生すると、クラスタ内の他のノードが現在のmaster eligibleノードをpingし、そこから新しいプライマリノードを選択します.ノードはnodeを設定することができる.masterはfalseになって自分がプライマリノードになることを阻止します.discoveryを構成する.zen.minimum_master_Nodesはクラスタのsplit brainの発生を防止する.この構成は、クラスタ内のmaster eligibleの個数をチェックすることによって、プライマリノードが選択されたか否かを判断する.その個数は(number_master eligible/2)+1に設定することが好ましく、プライマリノードに問題が発生した場合、1つのクラスタが2つのクラスタに分裂することを防止する.最小番号のactive master eligible nodeがmasterノードに選択されます.選挙の詳細はブログを参照してください.https://www.jianshu.com/p/9454ac19921d
3、スライスコピーの同期
詳細は以下を参照してください.https://www.easyice.cn/archives/243.
ElasticsearchはAllocation IDsの概念を使用し、これは異なるスライスを区別する唯一の識別(UUIDS)である.Allocation IDsはshardレベルメタ情報に格納され、各shardには独自のAllocation IDがあり、クラスタレベルメタ情報にはin-sync allocation IDsと呼ばれる最新shardと考えられるAllocation IDの集合が記録される.ネットワークまたは他の理由でプライマリサブshardが同期していない場合、コピーのshardはin-sync allocation IDsから蹴り出されます.例:小さなクラスタ:プライマリノード1つ、データノード2つ.簡単な例を維持するために、1つのプライマリスライスと1つのセカンダリスライスのみのインデックスを作成します.最初は、1つのデータノードがプライマリスライスを所有し、もう1つのデータノードがセカンダリスライスを所有します.cluster state apiを使用してクラスタ状態のin-syncスライス情報を調べ、「filter_path」queryパラメータを使用して興味のある結果をフィルタします.
GET /_cluster/state?filter_path=metadata.indices.my_index.in_sync_allocations.*,routing_table.indices.my_index.*
result:
{
"metadata": {
"indices": {
"my_index": {
"in_sync_allocations": {
"0": [
"HNeGpt5aS3W9it3a7tJusg",
"wP-Z5fuGSM-HbADjMNpSIQ"
]
}
}
}
},
"routing_table": {
"indices": {
"my_index": {
"shards": {
"0": [
{
"primary": true,
"state": "STARTED",
"allocation_id": { "id": "HNeGpt5aS3W9it3a7tJusg" },
"node": "CX-rFmoPQF21tgt3MYGSQA",
...
},
{
"primary": false,
"state": "STARTED",
"allocation_id": { "id": "wP-Z5fuGSM-HbADjMNpSIQ" },
"node": "AzYoyzzSSwG6v_ypdRXYkw",
...
}
]
}
}
}
}
}
クラスタ状態は、プライマリスライスとセカンダリスライスの両方が起動していることを示し、プライマリスライスはデータノード「CX-rFmo」に割り当てられ、セカンダリスライスはデータノード「AzYoyz」に割り当てられる.彼らはすべて唯一のallocation idを持っていて、同時に、in_にも現れますsync_allocationsコレクションにあります.プライマリスライスが存在するノードを閉じると何が起こるか見てみましょう.これは、スライス上のデータを変更しないため、2つのスライスコピーは同期を維持する必要があります.プライマリスライスがない場合、サブスライスもプライマリスライスとして提示されるべきであり、これらはクラスタ状態に反映される.
{
"metadata": {
"indices": {
"my_index": {
"in_sync_allocations": {
"0": [
"HNeGpt5aS3W9it3a7tJusg",
"wP-Z5fuGSM-HbADjMNpSIQ"
]
}
}
}
},
"routing_table": {
"indices": {
"my_index": {
"shards": {
"0": [
{
"primary": true,
"state": "STARTED",
"allocation_id": { "id": "wP-Z5fuGSM-HbADjMNpSIQ" },
"node": "AzYoyzzSSwG6v_ypdRXYkw",
...
},
{
"primary": false,
"state": "UNASSIGNED",
"node": null,
"unassigned_info": {
"details": "node_left[CX-rFmoPQF21tgt3MYGSQA]",
...
}
}
]
}
}
}
}
}
1つのデータノードのみのため、サブスライスは未割当て状態にとどまる.2番目のノードを再起動すると、サブスライスはこのノードに自動的に割り当てられます.このシーンをより面白くするために、私は2番目のノードを起動しません.逆に、新しいアップグレードされたプライマリ・スライスにドキュメントをインデックスします.スライスコピーは現在相違しているため、アクティブでないどのスライスコピーが古くなったかは、プライマリノードによってin-syncセットから削除されます.
{
"metadata": {
"indices": {
"my_index": {
"in_sync_allocations": {
"0": [
"wP-Z5fuGSM-HbADjMNpSIQ"
]
}
}
}
},
"routing_table": {
... // same as in previous step
}
}
同期されたスライスコピーが1つしか残っていません.コピーが使用不可になった場合、システムがどのように処理するかを見てみましょう.このため、現在の一意のデータノードを閉じ、古いスライスコピーを持つ前のデータノードを起動します.その後、cluster health apiはcluser healthをredと表示し、クラスタステータスはプライマリスライスが割り当てられていないことを示します.
{
"metadata": {
"indices": {
"my_index": {
"in_sync_allocations": {
"0": [
"wP-Z5fuGSM-HbADjMNpSIQ"
]
}
}
}
},
"routing_table": {
"indices": {
"my_index": {
"shards": {
"0": [
{
"primary": true,
"state": "UNASSIGNED",
"recovery_source": { "type": "EXISTING_STORE" },
"unassigned_info": {
"allocation_status": "no_valid_shard_copy",
"at": "2017-01-26T09:20:24.054Z",
"details": "node_left[AzYoyzzSSwG6v_ypdRXYkw]"
},
...
},
{
"primary": false,
"state": "UNASSIGNED",
"recovery_source": { "type": "PEER" },
"unassigned_info": {
"allocation_status": "no_attempt",
"at": "2017-01-26T09:14:47.689Z",
"details": "node_left[CX-rFmoPQF21tgt3MYGSQA]"
},
...
}
]
}
}
}
}
}
cluster allocation explain APIを見てみましょう.これは割り当ての問題をデバッグする良いツールです.パラメータなしのexplainコマンドを実行すると、システムが見つけた最初の未割当てスライスの説明が表示されます.
GET /_cluster/allocation/explain
explain APIは、プライマリスライスが割り当てられていない理由を示し、各ノードに基づいたより詳細な割り当て情報も提供します.この例では、プライマリノードは、クラスタの現在使用可能なノードで同期された(in-sync)スライスコピーを見つけることができない.
{
"index" : "my_index",
"shard" : 0,
"primary" : true,
"current_state" : "unassigned",
"unassigned_info" : {
"reason" : "NODE_LEFT",
"at" : "2017-01-26T09:20:24.054Z",
"last_allocation_status" : "no_valid_shard_copy"
},
"can_allocate" : "no_valid_shard_copy",
"allocate_explanation" : "cannot allocate because all found copies of the shard are either stale or corrupt",
"node_allocation_decisions" : [
{
"node_id" : "CX-rFmoPQF21tgt3MYGSQA",
"node_name" : "CX-rFmo",
"transport_address" : "127.0.0.1:9301",
"node_decision" : "no",
"store" : {
"in_sync" : false,
"allocation_id" : "HNeGpt5aS3W9it3a7tJusg"
}
}
]
}
このAPIはまた、ノード「CY−rFmo」で使用可能なスライスコピーが古いことを示す(store.in_sync=false).in-syncスライスのコピーを持つノードを起動すると、クラスタがgreenに再変更されます.もしそのノードが永遠に戻ってきたら?reroute APIは、サブコマンドallocateを提供します.stale_primaryは、古いスライスをプライマリスライスに割り当てるために使用されます.このコマンドを使用すると、指定したスライスコピーに欠落しているデータが失われます.同期スライスが一時的に使用できない場合、このコマンドを使用すると、同期コピーで最近更新されたデータが表示されます.クラスタに少なくともいくつかのデータを実行させる最後の措置と見なすべきです.すべてのスライスコピーが存在しない場合、Elasticsearchは、スライスに関連付けられたすべての以前のデータが失われることを意味する空のスライスコピーを使用してプライマリスライスを割り当てるように強制することもできる.言うまでもなく、allocate_empty_primaryコマンドは最悪の場合にのみ使用でき、その意味はよく理解されています.
4、その他の紹介
4.1、Pending Task
クラスタに問題が発生した場合、cat healthでpending taskが表示されます.pending taskはいったい何ですか.クラスタメタデータレベルの変更タスクを処理できるのはmasterノードのみです.ほとんどの場合、masterは処理できますが、クラスタメタデータの変更速度がmasterノードの処理速度を超えると、これらのメタデータ操作のタスクがキューにキャッシュされます.すなわちpending tasksです.pending task APIには、キュー内で保留中のすべてのクラスタメタデータが変更されたタスクが表示されます.cluster stateが大きすぎる場合、いくつかの変更はcluster stateを更新しやすく、cluster stateを更新すると多くのcpuが消費され、他のノードに転送されるネットワーク帯域幅が消費され、多くの時間がかかります.
ESクラスタを高可用性にするには