AWS OpenSearchを会社で運用してきて色々知見がたまってきたので、ここにまとめておきます
文字列検索の扱い方
マッピングを設定する際に、tokenizerとanalyzerを設定する。
無難なのはngram。使う場合は検索対象の文字を決めるためにtoken_charsの設定に注意。
用途に合わせて色々使い分けられるとよし。
https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-tokenizers.html
https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-analyzers.html
検索のバッドノウハウ
- 計算系の処理(scriptでのソート、検索などCPUリソースを大いに消費する検索クエリなど)はできるが、やるとCPUを圧迫して詰まりの原因になるので、しないほうが無難。
- multimatchは複数列に同時に全文検索投げられて便利だが、検索文字列が多いと非常に遅くなるので、termsが使えるならそっちをつかったほうがいい。
大量データを持つリソースの一覧検索ではScroll APIを使う
OpenSearchの通常の _search クエリでは、10000件までしか結果を絞り込めない(offset, limit指定しても取ってこれない)。
もし10000件目以降のデータをページャーやもっと見るなどで取ってくる必要がある場合、Scroll APIを使う必要があります。
Scroll APIは、(ざっくりな説明ですが)リクエストごとにscroll_idを生成し、結果セットを一時的に保持しつつ検索できるAPIです。これによって10000件目以降のデータを取得することができます。
またScroll APIには個々のscrollに対して生存期間を設定できます。用途に応じて 10s , 30s 、 1m など適切に設定するのがよいかと思います。
Scroll APIがパフォーマンス面で懸念がある場合、一覧の最後or最初のIDをafter/before指定して、ソート順的に該当IDより後/前のものをoffsetで取ってくるのもあり。
max_open_scroll_context
Scroll API を使う場合、 max_open_scroll_contextも必要に応じて設定しておくといい。
max_open_scroll_context は何かというと、OpenSearchインスタンス内で作成できるScrollの最大数のこと。
ElasticSearchだと _cluster/settings APIを叩くことで設定が可能だが、AWS OpenSearchではこちらのAPIが開放されていないため、AWS側に設定を依頼する必要がある。
OpenSearch 7系では max_open_scroll_context のデフォルト値が500となっているため、scrollの生存期間内に500回異なるアクセスがあるAPIでOpenSearchを使う場合、 max_open_scroll_context を適切に設定していないとOpenSearchへの検索リクエストがエラーになってしまいます。
シャードの設定
要見積もり。1シャード30GBになるように見積もる。下記がめちゃくちゃ参考になる。
https://kazuhira-r.hatenablog.com/entry/2020/01/02/182732
サービス停止なしでの列追加対応
PUT /my-index-000001/_mapping APIでマッピングにカラムを追加後、データを投入する。
同期元のDBで対象カラムにデータがまだ入ってない、入っていても件数が少ない場合、reindex API などを使ってデータを再投入するより、この方式のほうがお手軽にカラム追加できる。
元データからのデータ同期の仕方
トランザクションアウトボックスパターンなどでユーザ操作後に自動でOpenSearchに流れるようにするのが理想。
過去データの一括投入には気合が必要。全データ同期を全自動で並列処理で実行してくれるシステムを構築できると理想的。
参考:
https://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/cloud-design-patterns/transactional-outbox.html
https://engineering.mercari.com/blog/entry/20211221-transactional-outbox/