ある日突然ThreadpoolWriteThreads(MAX)が急増して止まらなくなった件

こんにちは、catooです。

前回は、Opensearch（ElasticSearch)の429エラーについて記載したのですが、
最近突然起こった障害について備忘録として記載しようと思います。

ある日、突然起こったこと
運用しているシステムは配信系のシステムなのですが、起こったことは主に2つ下記です。

### OpenSearch 環境
バージョン：Elasticsearch 6.4
サービスソフトウェア：R20220323-P1


## アプリログのWarningが大量発生
OpenSearch向けのリクエストが429エラーとしてしばしば弾かれることは前の記事にも記載しましたが、この日は一味違いました。
通常大量トラフィックの発生についても多くて1件程度の発生で収まっていた429エラーなのですが、この日はなんと<font color = red>30000件オーバー</font>も発生していました。
![スクリーンショット 2022-04-18 14.14.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/544590/9d340f12-3985-b56c-c804-3797bb57037e.png)

実際のところ、リトライのロジックにより本件は処理としては完了していたため、どうにか影響もなく収束していましたが、これ以上のトラフィックが継続して流れた場合に問題になる可能性があるため早急に対処が必要な状況でした。

## とあるメトリクスの異常について
Opensearchコンソールから全体の書き込みが緑であることを確認し、一段落
![スクリーンショット 2022-04-18 14.19.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/544590/1a3b6da7-fd8e-2c37-9402-2df97714f7dd.png)
次に、429のエラーがread/writeどちらで出ているか確認の為に下に行くと明らかにおかしいものが有りました。
![スクリーンショット 2022-04-11 16.22.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/544590/6b3f0beb-cf18-bde1-dbd4-8e23682ad86e.png)
16:00過ぎを堺にThreadpoolWriteThreadsが急増しているのがわかります。
これによって、「write」の429エラーが大量発生していることがわかりました。

また、個別に各ノードのThreadpoolWriteRejectedを確認してみると
![スクリーンショット 2022-04-18 14.26.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/544590/b670d3b8-ee88-a840-46c1-2fdddc1afdfe.png)
大量のノードのうち、Rejectedを行っているのは2台のデータノードのみということがこれにより判明しました。

## 障害の原因と対処について
### 障害の原因
データノードは、Opensearchのマネジメントサービスとして裏でEC2を利用しています。
下記、環境でピンと来る人は相当マニアックだと思いますが、選択したEBSボリュームが原因となっていました。
GP2を選択していたことにより、特定シャードへの書き込みが頻発した状況が継続していたことでI/O クレジットが枯渇し、16:00過ぎに突如パフォーマンスが劣化したという形になります。

#### 環境
m4.xlarge.search
EBS(gp2) 60GB

#### EBSのIOPSについて
通常GP2のEBSボリュームを選択していると、IOPSが与えられたボリュームの3倍を上限として割り当てられます。例えば今回は 60 GiB のボリュームでは 180 IOPS がベースライン (最低保障) 性能となります。
このベースラインである180IOPS以上のトラフィックが流れたとしても、I/O クレジットという概念によって基本的には一時的なバーストに耐えられる構成となっています。
細かいところは引用にてご確認ください。
>gp2 ボリュームには I/O クレジットという概念があり、これを消費することで少ない割当のボリュームであっても、最大 30分間は 3000 IOPS のパフォーマンスを発揮することができます。I/O クレジットを消費した場合は時間とともに回復します。

https://qiita.com/hayao_k/items/a46867062a1e09b53eaa#:~:text=IOPS%20%E3%81%AE%E7%A2%BA%E8%AA%8D%E6%96%B9%E6%B3%95&text=EBS%20%E3%81%AF%201%20%E5%88%86%E9%96%93%E3%81%94%E3%81%A8,IOPS%20%E3%82%92%E7%AE%97%E5%87%BA%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82

### 障害の対処
EBSボリュームをio2(プロビジョンドIOPS)に急遽変更し、IOPSの見積もりを固定値に修正してデプロイし直すことで発生が抑えることが可能でした。
変更しBlue/Greenでの置き換え完了後は発生しなくなった形となあります。

#### プロビジョンドIOPS見積もり方について
Opensearch向けの書き込みに関してはCloudwatchにより取得が可能なので最大値ではありますが、そこをベースにある程度見積もりが可能です。
Opensearchのドメイン項目からWriteIOPS/ReadIOPSを確認してください。
例だと大体、4783Write/60秒で約80IOPS(write)となります。

![スクリーンショット 2022-04-18 14.46.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/544590/498ed50b-a43b-9760-81c7-767307dac43e.png)

## 今後の対策
プロビジョンドIOPS見積もり方にて利用したWriteIOPS/ReadIOPSにキャップアラートを仕掛けて、
アラーム発行の際は、プロビジョンドIOPSの上方修正を検討するか、Reindexしてシャードを増やすなどの対策を取りたいと考えています。

## やりたいけどできなかったこと
通常のEC2では、EBSボリュームのIOクレジットの監視が可能です。
今回の事象でわかったことですが、データノードに関してEBSの選択肢としてGP2が存在しているため、GP2利用者は必然的にIOクレジットの成約にかかってしまいます。
しかしながあら現状のOpensearchでは、IOクレジットの傾向が見れないため今回の事象に傾向として気づくことはそもそも不可能でした。
一応要望として、AWSサポートケースには連絡しています。

## まとめ
今回突然ThreadpoolWriteThrea突然が上昇したケースを記載しました。
類似事象に該当した場合は、状況を確認してEBSボリュームを拡張したりプロビジョンドIOPSに変更したりしてみてください。

自分の手柄みたいに書いていますが、裏ではサポートケースで連携していたりしたので全部を私が見つけて進めたわけではありません。
サポートケース様様でした。

皆様すぐサポートケース切りましょう。

社内ではOpensearchに対して憎しみ余って愛があると周りから言われておりますが、かなり運用が難しいサービスなので実際に愛を持って対応していかないと心を病みそうです笑
止まってもよい場所にOpensearchを使うかお金を払ってio2のプロビジョンドIOPS側で容量設計するのが良いと思います。
事前にOpensearchにより適したインデックスの設計ができていればよかった面もあるのですが、そのあたりはまた別の機会に書きたいと思います。