背景
Opensearchのパフォーマンスが悪化したため、reindex APIを利用して大きくなりすぎたシャードの分割を行いました。
アドベントカレンダー参加を兼ねて、最終的に安定して実行できた内容を備忘録的に残してあります。
目的
シャードの分割をされる際にエラーが出てうまくいかなかった際、
一助にしていただけると幸いです。
前提条件
データ容量 40GiB
データ件数 200万件
移行前シャード数 プライマリ:1 / レプリカ:3で安定稼働
内容
以下、時系列順の作業内容です。
1.専用マスターノードの追加
4xlargeのデータノードを2台追加するよりも、
largeの専用マスターノードを3台追加する方がクラスタ全体で安定します。
データノードが10台以下の環境では不要と思っていましたが、
高負荷な状況ではコスパよくほぼ必須です。
2.データノードの追加
既存のindexingやsearchがreindexに干渉しないよう、
移行後のシャード数に合わせたデータノードを追加します。
シャード数2のindexへ移行する場合、単純に2台追加します。
中身は空の状態で一時的にシャード数が不均衡になり、
前述の専用マスターノードがいないと負荷が跳ね上がります。
3.移行先indexの作成
移行先のindexを作成します。
bulkのコストを抑えるため、自動更新の停止とレプリカ数の調整を行います。
PUT {index_dest}/_settings
{
"index": {
"refresh_interval": -1,
"number_of_replicas": 0
}
}
4.シャード割り当ての確認
移行先のindexが割り当てられたノードに、負荷の高いindexが割り当てられていないことを確認します。
シャードの不均衡がなく、既存処理のリクエストが対象ノードへ影響しない状態が理想です。
完全に倉庫番です。
5.データ容量を1GiB削減
B/Gデプロイを強制させてきれいなインスタンスに入れ替えます。
6.reindexの実行
scrollタイムアウトはデフォルトで5分です。
少なすぎるためscrollを指定して調整します。
バッチあたりのドキュメント数はデフォルトで1000です。
多すぎるためsizeを指定して調整します。
requests_per_secondはバッチ実行後に秒間平均で指定した値になるまで次のバッチを遅延します。
デフォルトは-1(遅延しない)です。
POST _reindex?wait_for_completion=false&scroll=1h&requests_per_second=50
{
"conflicts": "proceed",
"source": {
"index": "{index_source}",
"size": 100
},
"dest": {
"index": "{index_dest}"
}
}
7.負荷に合わせて実行速度調整
事前に負荷のかかる時間帯が分かっている場合、rethrottleでバッチ実行間隔を調整します。
POST _reindex/{task_id}/_rethrottle?requests_per_second=1
task_idはreindexのレスポンスを保存するかtask APIから取得します。
GET _tasks?detailed=true&actions=indices:data/write/reindex
8.可能な限りリクエストを停止する
reindexと同時にリクエストを流す場合、全体の負荷が上がるだけでなく実行自体も遅くなります。
可能であればメンテナンス計画し、難しい場合でも流量を抑えると効果的です。
9.それでもエラーで停止したら
公式のパフォーマンストラブル解決記事が、内容がまとまっていて原因調査の際に非常に参考になります!
採用PR
弊社で一緒に働く仲間を募集しています。
全てのオタクを幸せにしたい方、是非ご覧ください!