初めまして、catooです。
この度会社のチームメンバーとモチベを上げるためにという議論の中でQiitaの投稿が上がったのでやってみようと思いまして記事を書こうと思い立ちました。
会社内での気づきを備忘録としてDevOps観点で書いていこうと思っています。
DevOpsしていくのにめっちゃめんどいなぁと思っている内容を記載します。
OpenSearch 環境
バージョン:Elasticsearch 6.4
サービスソフトウェア:R20220323-P1
OpenSearch における429 Too Many Requestsエラー
AWS Opensearch Serviceの「429 Too Many Requestsエラー」に対する考え方は以下のトラブルシュートにまとめられています。
HTTP 429 エラーまたは es_rejected_execution_exception には、次に示す変数が起因していることが考えられます。
データノードのインスタンスタイプと検索もしくは書き込みの制限
インスタンスメトリクスの高い値
アクティブスレッドとキュースレッド
HTTP 429 エラーは、クラスターへの検索および書き込みリクエストが原因で発生する場合があります。
書き込みや検索処理それぞれで429エラーの発生可能性があり、障害時には各変数をチェックして何が原因か調べていく必要があります。
ですが、実はこのOpensearchそこそこの定常トラフィックであってもこの429エラー発生します。
そのため、常に読み込みおよび書き込みに対しての拒否に対する対策を実施していく必要が有りました。
検索処理の429エラーのチェック
発生頻度が、書き込み拒否に比べて少ないのであまり対策をねっていないです、すみません。。。
書き込み拒否の429エラーのチェック
AWSのページを確認すると以下の通り
書き込み拒否としての 429 エラーメッセージは、一括キューエラーを示します。es_rejected_execution_exception[bulk] は、キューがいっぱいであること、および新しいリクエストが拒否されたことを示します。この一括キューのエラーが発生するのは、クラスターに対するリクエスト数が一括キューのサイズ (threadpool.bulk.queue_size) を超えた場合です。各ノードの一括キューは、使用している Elasticsearch のバージョンに応じて、50~200 のリクエストを保持できます。
実際に出ているエラーログを見てみると、queue capacity = 200なので最大値になっています。
{
"error": {
"root_cause": [
{
"type": "remote_transport_exception",
"reason": "[CHHsNVd][x.x.x.x:9300][indices:data/write/update[s]]"
}
],
"type": "es_rejected_execution_exception",
"reason": "rejected execution of org.elasticsearch.transport.TransportService$7@7d3ada18 on EsThreadPoolExecutor[name = CHHsNVd/write, queue capacity = 200, org.elasticsearch.common.util.concurrent.EsThreadPoolExecutor@34296b04[Running, pool size = 4, active threads = 4, queued tasks = 206, completed tasks = 2247916]]"
},
"status": 429
}
実際にやっている対策
運用しているシステムでは、その中でも下記ポイントついて一応対策しています。
・アプリケーションロジックに指数関数的な再試行ロジックを追加します。指数関数的な再試行ロジックにより、失敗したリクエストが自動的に再試行されます。
注: クラスターで継続的にリクエストの同時実行性が高い場合には、指数関数的な再試行ロジックは 429 エラーの解決には役立ちません。トラフィックが突然または時折急増する場合は、このベストプラクティスを組み込みます。
指数関数的な再試行ロジックではなく、単純な再試行ロジックを用いて対処しています。
現状では5回のリトライまでにほぼ成功応答が得られる状況を確認しました。
DynamoDBのAWSSDKには「指数関数的な再試行ロジック」が組み込まれていますが、
Opensearchについては、アプリケーション側に自身で組み込む必要がある点が工数増加の大きな点だと思いました。
後から対策しようとしたけど簡単にできなかったやつ
・ドキュメントのインデックス作成を高速化すると、書き込みキューがキャパシティー上限に達する可能性が低くなります。
この項目については、高速化する手段が限られているように思います。
調べても出てこないのでES関係のエンジニアと喋りましたが、解決方法は単発リクエスト/bulkリクエストのサイズを減らす方法かReplicaシャードを減らす方法の2種類しか有りませんでした。
システムでは単発リクエストで大した大きさのデータを送っていなかったので、Replicaシャードを削る方法しか取り得なかったのですが、Elasic社推奨の「保持期間ごとのインデックス」っていなかったので、インデックスの再作成が必要になったため対応不可と判断しました。
まとめ
AWS OpenSearch における429 Too Many Requestsエラーが頻発していたので色々検討したり調べたりした内容をまとめました。
基本的には再試行ロジックを組み込むことで対処可能なのですが、運用していくにつれてシャードの偏り等でも発生の可能性があるらしいのでそのあたりも様子見しながらシャードの管理を進める必要も出てきそうです。
要件変更等に対応しながら、アプリケーションからのリクエスト総数を見積もって調整していく運用の複雑さがやばすぎると思った。
このコンポーネントもうやめたい。