Elasticsearch クラスターでインデックスを作成する際、実際のデータボリュームに基づいてプライマリシャードの数を設定します。データボリュームを過大に見積もり、プライマリシャードを多く設定しすぎた場合、実際のビジネスデータ量が少ないときは、プライマリシャードの数を減らす必要があります。これにより、クラスターリソースの過剰な消費を防ぎ、クエリや書き込みのパフォーマンス低下を回避できます。このトピックでは、_shrink API を使用して、既存のインデックスをより少ないプライマリシャードを持つ新しいインデックスに縮小する方法について説明します。
背景情報
Elasticsearch を使用する際は、クラスター内のシャードの総数と各インデックスのシャード数をモニターしてください。シャード数が多いほど、より多くのファイルハンドルとクラスターリソースを消費します。同様に、不適切なシャード構成は、クエリと書き込みの両方のパフォーマンスに影響を与えます。
インデックス作成時に実際のデータボリュームを予測できない場合、プライマリシャードを過剰に設定してしまうことがあります。インデックスの再作成を使用してプライマリシャードを削減するには、時間がかかりすぎます。Elasticsearch は、プライマリシャードを迅速に縮小するための _shrink API を提供しています。shrink 操作は、元のインデックスのシャードを直接削減するものではありません。代わりに、次の手順に従います。
元のインデックスと同じ構成で、より少ないプライマリシャードを持つ新しいインデックスを作成します。元のインデックスのすべてのシャードを単一のノードに再配置します。そのノードには、元のインデックスのプライマリシャードに保存されているデータの合計サイズよりも大きいディスク領域を確保してください。
元のインデックスのセグメントから新しいインデックスへのハードリンクを作成します。
新しいインデックスを回復します。これは、閉じたインデックスを開くのと似ています。
次の表は、インデックスの再作成 API と _shrink API のパフォーマンステスト結果を比較したものです。
テスト環境:
データノード:5 ノード、各ノードは 8 vCPU、16 GiB メモリ。
インデックスデータ:182 GiB。
シャード数:元のインデックスに 30 のプライマリシャード、ターゲットインデックスに 5 のプライマリシャード、レプリカシャードはゼロ。
テスト結果
方法
所要時間
リソース使用量
インデックスの再作成
3 時間 22 分
クラスターの書き込み QPS が高くなります。データノードのリソース使用量が高いです。
_shrinkAPI15 分
shrink 操作を実行しているノードは、高いコンピューティングリソースを使用します。
前提条件
ご利用の Elasticsearch クラスターが正常であり、通常の負荷状態であること。
クラスター内のデータノードの数と利用可能なディスク容量に基づいて、削除するプライマリシャードの数を評価します。詳細については、「シャードの評価」をご参照ください。
元のインデックスのステータスが green であること。
元のインデックスに含まれるドキュメントが 2,147,483,519 件以下であること。
ご利用の Elasticsearch クラスターに、新しいインデックスと同じ名前のインデックスが存在しないこと。
操作手順
ご利用の Elasticsearch クラスターの Kibana コンソールにログインし、Kibana のホームページに移動します。
左側のナビゲーションメニューで、[開発ツール] をクリックします。
[コンソール] で、次のコマンドを実行して、元のインデックスへの書き込みを無効にし、レプリカシャードの数を 0 に設定し、すべてのシャードをクラスター内の 1 つのノードに再配置します。
この例では、元のインデックスとして shrink5 を使用します。この名前を実際のインデックス名に置き換えてください。
PUT shrink5/_settings { "index.routing.allocation.require._name": "es-cn-zvp25yhyy000y****-1ab7****-0001", "index.blocks.write": true, "index.number_of_replicas": 0 }パラメーター
説明
index.routing.allocation.require._name
シャードを再配置するノードの 名前。ノード 名は
GET _cat/nodes?vを実行して取得します。説明_shrinkAPI を呼び出す前に、元のインデックスのすべてのシャードをクラスター内の 1 つのノードに再配置する必要があります。index.blocks.write
インデックスへの書き込みを無効にします。このパラメーターを true に設定します。
説明_shrinkAPI を呼び出す前に、元のインデックスへの書き込みを無効にする必要があります。index.number_of_replicas
インデックスのレプリカシャードの数。
_shrinkAPI を呼び出してプライマリシャードを縮小します。この例では、元のインデックス shrink5 を 30 プライマリシャードから 5 プライマリシャードに縮小し、shrink_hk5e_cn という名前の新しいインデックスを作成します。必要に応じてインデックス名を置き換えてください。
POST shrink5/_shrink/shrink_hk5e_cn { "settings": { "index.blocks.write": null, "index.number_of_shards": 5, "index.number_of_replicas": 0, "index.routing.allocation.require._name": null } }パラメーター
説明
index.blocks.write
インデックスへのデータ書き込み操作を無効にするかどうかを指定します。
_shrinkAPI を使用してプライマリシャードの数を減らした後、新しいインデックスの index.blocks.write を null に設定して、元のインデックスから継承された構成をクリアします。index.number_of_shards
新しいインデックスのプライマリシャードの数。
重要shrink をトリガーした後、shrink ノードの CPU 使用率と 1 分間の負荷が増加します。shrink はオフピーク時間に実行してください。
元のインデックスは、新しいインデックスよりも多くのプライマリシャードを持つ必要があります。元のインデックスのプライマリシャード数は、新しいインデックスのプライマリシャード数で割り切れる必要があります。たとえば、元のインデックスに 8 つのプライマリシャードがある場合、新しいインデックスは 4、2、または 1 にすることができます。元のインデックスに 15 のプライマリシャードがある場合、新しいインデックスは 5、3、または 1 にすることができます。元のインデックスのプライマリシャード数が素数の場合、新しいインデックスは 1 にする必要があります。
index.number_of_replicas
新しいインデックスのレプリカシャードの数。
index.routing.allocation.require._name
シャードを再配置するノードの名前。
_shrinkAPI を使用してプライマリシャードの数を減らした後、新しいインデックスの index.routing.allocation.require._name パラメーターを null に設定して、元のインデックスからコピーされた構成をクリアするか、元のインデックスを削除します。結果の表示
_cat recoveryAPI を呼び出して、shrink の進捗を確認します。shrink に関連する回復が残っておらず、クラスターが正常な状態になると、shrink は完了です。shrink の進捗確認
GET _cat/recovery?v&active_only応答の index 列に shrink を待機しているインデックスが表示されなくなった場合、shrink に関連する回復は残っていません。
クラスターのヘルス状態の確認
GET _cluster/health応答に
"status" : "green"が含まれている場合、クラスターは正常です。
よくある質問
Q:なぜシンボリックリンクではなくハードリンクを使用するのですか?
A:ハードリンクはインデックスの独立性を保証するためです。シンボリックリンクを使用した場合、新しいインデックスにデータを書き込んだ後に元のインデックスを削除すると、新しいインデックスのデータも削除されてしまいます。ハードリンクはこれを防ぎます。