SOLR のインデクシングに関するヒント

トピック作成者:ks-solruserml-bot (2024/07/02 11:52 投稿)
10
CloseClose

(The bot translated the original post https://lists.apache.org/thread/xjz78hmjjplcj0gcv5qgyojptxjdny10 into Japanese and reposted it under Apache License 2.0. The copyright of posted content is held by the original poster.)

みなさん、

現在、Solrが書き込みパフォーマンスでボトルネックになっています(多くのCPUを使用し、書き込みがキューに溜まっています)。セットアップを大幅に変更せずに、それ以上の書き込みパフォーマンスを引き出す方法についてのヒントを探しています。

以下がセットアップです:

  • Solr 8.2(重要な変更があるかもしれませんが、変更履歴を見てもパフォーマンスに大きな影響があるとは思いません)
  • レプリカ設定(1つのノードがインデックス作成を担当し、他のノードは10分ごとにレプリケーション)。インデックスノードは8コア、16GのRAMを使用しています。
  • 9つの異なるコアがあります。それぞれのコアはディスク上で約100MBを占め、約90,000件のドキュメントが含まれています。
  • 更新はバッチサイズ1000で行われ、各コアごとに約9つのプロセスが並列で実行されています。
  • セットアップはかなりシンプルで、特別な文字列処理器は使用せず、デフォルトの設定に近い状態です。コア設定でいくつかのフィールドタイプが定義されており、保存されるIDもごく一部です。

問題点:

  • 現在、2つのコアと8GBのRAMを持つマシンで全ドキュメントの更新を処理するのに約3時間かかっています。

直感的な仮定:

  • インデックス全体のサイズがかなり小さい(ディスク上で合計約1GB以下)で、インデックスを作成するマシンもかなり強力であるため、インデックス作成(更新)はかなり高速であるはずです(おそらくすべてのドキュメントに対して10分未満)。しかし、実際にはそれよりもはるかに長くかかっており、何か間違っている可能性があります。

探していること:

  • 何がこの問題の原因となっているのかのアイデア
  • 書き込みパフォーマンスのための共通のチェック項目やヒント、おすすめの参考資料
  • 書き込みパフォーマンスの計測方法。たとえば、Solr側で時間がかかっている箇所をモニタリングする方法など、具体的に時間がかかっている箇所を絞り込む方法について

Solrの用語の誤用があれば申し訳ありません。

皆さんのヒントやご意見を、この場を借りてお伺いできれば幸いです。

Marius

返信投稿者:ks-solruserml-bot (2024/07/02 11:52 投稿)

これは、各Solrコア内のインデックス作成がシングルスレッドで行われていることを意味します。 インデックス作成の速度を向上させるには、複数のスレッドやプロセスを使用して複数のインデックスで並列にインデックスを作成する方法があります。 Solrにデータを送信するプロセス/スレッドの数を増やすときにSolrサーバーで利用可能なCPUパワーを増やすことができれば、その助けになるかもしれません。

よろしくお願いします。
Shawn

返信投稿者:ks-solruserml-bot (2024/07/02 11:52 投稿)
  • Shawnの言うように、各コアごとにマルチスレッド化してみてください。たとえば、2、3、4スレッドなどを試してみてください。
  • 異なるバッチサイズで実験してみてください。たとえば、500と2000を試してみてください。最適なバッチサイズはドキュメントに依存します。
  • 1000ドキュメントごとにコミットしないでください。代わりに、要件が許す限りまれにコミットしてみてください。たとえば、commitWithin=60000 を試して、1分ごとにコミットするようにします。

ヒント:SolrのメトリクスをDataDogなどのサービスにプッシュして、リクエスト数/秒、RAM、CPU、スレッド、GCなどの統計が表示されるダッシュボードを確認して、最後の質問に回答できるかもしれません。

Jan

返信投稿者:ks-solruserml-bot (2024/07/02 11:53 投稿)

必要に応じて、たとえば commitWithin=60000 を試して、1分ごとにコミットするようにします。

これが重要です。全プロセスが完了した後か、タイマーでコミットする場合、NRT(Real-Time Search)検索が必要ない限り、ほとんどの場合は誰もがそれを必要としないでしょう。コミットは負荷の大きな操作であり、1000ドキュメントをコミットする場合と100,000ドキュメントをコミットする場合とでほぼ同じ時間がかかります。

返信投稿者:ks-solruserml-bot (2024/07/02 11:53 投稿)

トピックに関する追加情報です。

  • Solrの設定を確認しましたが、かなりデフォルトの設定のようです(特にマージ、コミット戦略など)。
  • コミットは10分ごとに行っています。
  • SolrインスタンスにNewRelicを追加して、より多くのデータとグラフを収集しています。

最終的に私たちの目に留まったのは、Solrが過負荷のときに実行中のスレッドのスタックにあるいくつかの deleteByQuery 行です。一時的に deleteByQuery を削除すると、インデックス作成の速度が約10倍向上しました。

私たちはどのように deleteByQuery を使用していますか?

update(add=[{uid: foo-123, sku: 123, ...}, {uid: bar-124, sku: 124} ...],
deleteByQuery=["sku: 123 AND uid != foo-123", "sku: 123 AND uid != bar-124"])

UIDはインデックスのuniqueKeyです。"foo"または"bar"が変更された場合、以前のドキュメントを残したくないため、このようにしています。

理想的には、この場合、uniqueKeyを sku に変更すれば deleteByQuery は不要になりますが、deleteByQueryがどのようにしてパフォーマンスボトルネックを引き起こすのか、また、それを最適化する方法について興味深い点があるかもしれません。

Marius

返信投稿者:ks-solruserml-bot (2024/07/02 11:53 投稿)

こんにちは、Mariusさん、もしそう理解しているのであれば、各ドキュメントに対して deleteByQuery を行っているのですね。正しいでしょうか?

--
Vincenzo D'Amore

返信投稿者:ks-solruserml-bot (2024/07/02 11:53 投稿)

興味深い発見ですね。以前にも非常に遅い deleteByQuery の報告を見たことがあります。そのため、deleteByQuery は節度を持って使用し、更新ごとに複数の deleteByQuery リクエストを Solr に投げることは決して避けるべきです。

SKUのような本当にユニークなIDに切り替えるのは良いアイデアのようです。または、以前のIDを知っている場合は、delete-by-id を使用する方がはるかに高速です。deleteByQuery を使わざるを得ない場合でも、複数の deleteByQuery リクエストを1つにまとめることが効率的でしょう。つまり、(("sku: 123 AND uid != foo-123") OR ("sku: 124 AND uid != bar-124")...) のように一つのクエリにまとめることを試し、小さな個別のリクエストではなく、100件ずつまとめてバッチ処理することも検討してみてください。

Jan

返信投稿者:ks-solruserml-bot (2024/07/02 11:53 投稿)

こんにちは、Vincenzo
正しいです。

Marius

返信投稿者:ks-solruserml-bot (2024/07/02 11:54 投稿)

私はすべての低レベルの相互作用を理解しているわけではありませんが、deleteByQuery がいくつかの深刻な問題を引き起こすことを目にしています。deleteByQuery は、実際に削除操作を行う前にLuceneが完了を待機するブロッキング状態を作り出すようです。そして、削除操作の後に送信されたすべての操作もその削除操作の完了を待機します。次のような状況を想像してみてください:

1) 進行中のインデックス作成がセグメントのマージを開始し、そのマージには15分かかります。
2) deleteByQuery が送信されます。
3) さらにインデックスの変更が送信されます。

この場合、ステップ2はマージの完了を待機し、ステップ3はステップ2の完了を待機します。自動的なセグメントのマージには15分以上かかることがよくあります。

ステップ2がIDをクエリして deleteById を使用するように変更すると、ステップ2とステップ3はマージと並行して実行されます。

私のインデックス作成プロセスが長時間停止する原因を解明するのにかなりの頭を悩ませました。

よろしくお願いします。
Shawn

返信投稿者:ks-solruserml-bot (2024/07/02 11:54 投稿)

SKUを主キーとして使用していない理由は何ですか? 同じSKUの複数のバージョンを必要とする必要がありますか?
私の理解では、SKUを主キーとして使用できれば、ほとんどの deleteByQuery は不要です。

--
Vincenzo D'Amore

返信投稿者:ks-solruserml-bot (2024/07/02 11:54 投稿)

その件には技術的な理由があるかもしれないと思います。それを解明する必要があります。また、それはそれほど単純ではありません。たとえば、uniqueKey は実際には2つのIDの組み合わせで構成されており、それらの間の関係はグルーピングの目的で重要です。

しかし、SKUに切り替えることに賛成ですね。それは理にかなっていると思います。

トピックへ返信するには、ログインが必要です。

KandaSearch

Copyright © 2006-2024 RONDHUIT Co, Ltd. All Rights Reserved.

投稿の削除

この投稿を削除します。よろしいですか?