検索クエリの速度が遅い
ソーシャル情報の検索エンジン( ark.com )の作業中に、Elasticsearchを選択しました。レビューによると、セットアップと使用が非常に簡単で、優れた検索機能があり、一般に天国のマナのように見えたからです。 そのため、インデックスが約10億文書というある程度のサイズに成長するまで、レプリカを考慮したサイズはすでに1.5 TBを超えていました。
通常の
Term query
さえ、数十秒かかることがあり
Term query
。 ESに関するドキュメントは私たちが望むほど多くありません。この問題のグーグルは、2年前の検索エンジンの完全に関連のないバージョンでの結果をもたらしました(私たちは0.90.13で動作します-これも十分に古いものではありませんが、余裕はありませんクラスター全体を下げ、更新し、現時点で再起動します-ローリング再起動のみ)。
遅いインデックス作成速度
2番目の問題は、Elasticsearchが処理できるよりも多くのドキュメントを毎秒(約100k)インデックス付けすることです。 タイムアウト、書き込みIOの大きな負荷、400単位のキューを処理します。 Marvelで見ると、すべてが本当に怖いように見えます。
これらの問題を解決する方法-アンダーカット
Elasticsearchクラスターのスケール
初期状況:
- 5つのデータノード、http対応:
- 100 GBのRAM
- 16コア
- 4 TB HDD(7200 RPM、シーゲイト)
- 指数:
- 500から10億のドキュメント、わずか5個
- 50〜400のプライマリシャードの数(ここでは、さまざまなインデックス付け戦略をテストしました-この設定は非常に重要です)
- レプリカ-2〜5
- 最大1.5テラバイトのインデックスサイズ
Elasticsearchのインデックス作成速度を上げる
この問題はそれほど複雑ではないことが判明し、インターネット上にはもう少し情報があります。
チェックするチェックリスト:
-
refresh_interval
検索データが更新される頻度、より頻繁に、より多くの書き込みIOが必要 -
index.translog.flush_threshold_ops
データをディスクにダンプする操作のindex.translog.flush_threshold_ops
-
index.translog.flush_threshold_size
ディスクにフラッシュする前にインデックスに追加するデータの量
詳細なドキュメントはこちら: www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-update-settings.html
まず、refresh_intervalを30秒に増やし、実際にスループットを1秒あたりほぼ5000ドキュメントに増やしました。 その後、5000回の操作でflush_threshold_opsを設定し、サイズは最大500 mbです。 必要に応じて、レプリカ、シャードなどの数をいじることができますが、それほど違いはありません。 また、データベースへの並列クエリの数を増やす必要がある場合、ほとんどの場合これは必要ありませんが、スレッドプールに注意してください。
Elasticsearchでクエリの速度を上げる
次に、難しい部分に進みます。 インデックスのサイズとクラスターの再起動に必要な定数(バージョンの更新、マシンの更新)を把握し、次のような投稿も考慮に入れます: gibrown.wordpress.com/2014/02/06/scaling-elasticsearch-part-2-indexingインデックス内のシャードのサイズが1〜2 GBを超えないこと。 RF3を考慮して、インデックス(15億のドキュメントをカウント)、レプリカを考慮せずにドキュメントの5億が約300 GBを占めることを考慮して、インデックスに400の断片を作成し、すべてがうまくいくと計算しました-再起動速度は十分ですhigh:50〜60 GBのデータブロックを読み取る必要がなく、それらを複製する必要もないため、小さな断片の回復がブロックされ、小さな断片の検索速度が向上します。
最初は、インデックス内のドキュメントの数は少なく(1億から2億)、クエリ速度は100から200ミリ秒でした。 しかし、ほとんどすべてのシャードが少なくとも少数のドキュメントで満たされるとすぐに、クエリのパフォーマンスが大幅に低下し始めました。 このすべてを、一定のインデックス付けのためにIOの高負荷と組み合わせると、まったく満たすことができませんでした。
この場合、2つのエラーを作成しました。
1.多数のシャードを作成しました(理想的な状況1コア-1シャード)
2.日付ノードもhttpがオンになっているバランサーノードでした-データのシリアル化と逆シリアル化には時間がかかります
そのため、実験を始めました。
Elaticsearchにバランスノードを追加する
最初の明白なステップは、Elasticsearchにいわゆる
balancer nodes
を追加することでした。 他のシャードによるクエリ結果を集約できます。ディスクへの読み書きを行わないため、IOでオーバーロードされることはありません。データノードをオフロードします。
展開には、chefと対応するelasticsearchクックブックを使用するため、次の設定を使用して、追加のロールをいくつか作成します。
name "elasticsearch-balancer" description "Installs and launches elasticsearch" default_attributes( "elasticsearch" => { "node" => { "master" => false, "data" => false } } ) run_list("services::elasticsearch")
4つのバランサーを正常に起動しました。 状況は少し改善されました-喫煙ハードディスクで過負荷のノードは観察されなくなりましたが、クエリ速度はまだ低かったです。
Elasticsearchのデータノードの数を増やす
シャードの数(400)が生産性の向上に影響することはありませんが、1台のマシンにシャードが多すぎるため、それを悪化させるだけであることを思い出しました。 簡単な計算の後、5台のマシンで80個のシャードのみが適切にサポートされることがわかります。 レプリカの数を考えると、1200個あります。
マシンの一般的なフリート(80ノード)で十分な数のノードを追加でき、それらの主な問題はHDDのサイズ(128 GBのみ)であるため、一度に約15台のマシンを追加することにしました。 これにより、別の240個のシャードをより効率的に使用できます。
さらに、いくつかの興味深い設定に出会いました。
*
index.store.type
デフォルトではniofsに設定され、ベンチマークではmmapfsのパフォーマンスよりも低いパフォーマンス-mmapfsに切り替えました(デフォルト値は1.xです)
*
indices.memory.index_buffer_size
-30%に増加し、反対にJavaヒープの下のRAMの量は30 GBに減少しました(50%でした)。mmapfsではオペレーティングシステムのキャッシュにさらに多くのRAMが必要になるため
そしてもちろん、私たちの場合、空き領域に基づいてシャードの場所を制御できるようにすることが不可欠でした。
curl -XPUT localhost:9200/_cluster/settings -d '{ "transient" : { "cluster.routing.allocation.disk.threshold_enabled" : true } }'
シャードを転送し、新しい設定で古いサーバーを再起動して数日後、 キャッシュクエリ(フィルターではなく用語クエリ)を500ミリ秒以内に実行しました。 この状況はまだ完全ではありませんが、データノードを追加し、コアの数をシャードの数に調整すると状況が修正されることがわかります。
クラスターをスケーリングする際に他に考慮すべきこと
クラスターの再起動をローリングするときは、シャードを転送する機能をオフにしてください:
cluster.routing.allocation.enable = none
、古いバージョンでは設定が少し異なります。
あなたがそれを読んでいる間に何か質問があれば、私はそれを喜んで議論します。