クリスマスまで残り数日ですね。皆さん、プレゼントの準備は整っていますか?
本来は自分の足と目で探すべきなのでしょうが、私はすっかりアマゾンに頼りっきりです。
今日は Splunk の同時実行サーチ数についてお話したいと思います。
よく聞く話
Splunk を本気で使い始めるとスケジュールサーチを実装するようになると思いますが、そのスケジュールサーチがスキップされたり、コンティニューされたりした経験がある方もいらっしゃるかと思います。
そのような場合、Splunk の内部ログには以下のようなメッセージが出力されます。
The maximum number of concurrent historical scheduled searches on this cluster has been reached
日本語で簡単に訳すと、「同時実行サーチ数の上限に達したためスキップしました」というニュアンスになりますので、これを見ると、同時実行サーチ数を増やせばよいのではないかと考えるのが普通だと思います。
また、ある程度 Splunk を使ったことがある方であれば、Splunk には同時実行サーチ数という制限があるため、できるだけ多くのサーチを実行する目的で、最初から同時実行サーチ数を多めに設定しようと考えるケースもしばしば見かけます。
ちょっと考えてみよう
しかし、そもそも設定を増やせば増やすほど多くのサーチが実行できるのであれば、最初からデフォルト値が非常に大きな数字になっているはずです。デフォルトの設定は「Search Head の CPU 数 + 6」となっており、例えば 24 CPU の Search Head であれば 30 という、比較的控えめな値になっています。なぜなのでしょうか?
これは Search Head 自身の CPU のオーバーユースを防ぐことに加え、主に Indexer に許容量以上のサーチがディスパッチされないようにするためです。サーチがどのように CPU を利用するのかについては、「Splunk のパフォーマンス: ロードアベレージ」で説明していますので、そちらを参照してください。
上記ページでも説明していますが、単位時間内に投入されるサーチの量を Indexer 側の処理能力で割った数値を「利用率」と呼びます。この利用率が 0.7 を超えると、目立った待ち行列が発生し始めます。そして、この値が 1 に近づくにつれて、待ち行列の長さは急激に長くなっていきます。
ラーメン屋をイメージしてもらうと分かりやすいでしょう。利用率が 0.7 未満であれば、ほぼ待ち時間なくラーメンを食べられますが、0.7 を超えると常に一定数の人が店の外に並び始めます。さらに利用率が 1 以上になると、もはや来店客をさばききれなくなり、行列は永遠に伸び続ける状態となります。
CPU を利用するサーチにも、まったく同じことが当てはまります。利用率が 0.7 未満であれば、ほぼ待ち時間なく CPU を利用できますが、0.7 を超え始めると徐々に CPU が空くのを待つようになります。
同時実行サーチ数を増やすということは
同時実行サーチ数を増やすということは、ラーメン屋の店員や座席を増やす行為ではありません。ラーメン屋のキャパシティを増やさずに、来店客だけを増やすのと同じです。
お店が空いていれば問題ありませんが、すでに店の外に人が並んでいる状態で来店客だけを増やせば、どうなるかは想像に難くありません。普段なら 15 分で食べて帰れたラーメンが 2 時間待ちになるように、CPU 待ちが発生すれば、5 秒で終わるサーチが 30 秒かかるといったことが起こり得ます。
それでも利用率が 1 未満であれば、一定の待ち行列を維持しながら何とか回転します。しかし、利用率が 1 を超えた時点で待ち行列は無限に伸び続け、後からやってくるサーチは、いつ終わるのか見通しすら立たなくなります。
利用率の計算方法については、「Splunk のパフォーマンス: ロードアベレージ」で説明しています。利用率の計算には 1 サーチあたりの平均 CPU 利用時間が必要ですが、Splunk のログにはサーチの実行時間は含まれているものの、サーチがどれだけ CPU を使用したかを直接示すデータは含まれていません。同記事では、Indexer の CPU 利用時間を推定し、利用率を計算する SPL を紹介しています。SPL の実行結果に含まれる rho(ロー)というフィールドが利用率です。
同時実行サーチ数を増やす場合は、必ず現在の Indexer の CPU 利用率を確認してください。もし現在の利用率が限りなく 1 に近い場合には、同時実行サーチ数を増やしてはいけません。
こうして悲劇は起こった
同時実行サーチ数を深く考えずに増やした結果、実際に起こった事例を 1 つ紹介します。
このユーザーは「とにかく同時実行サーチ数を大きくすれば、たくさんサーチが実行できる」と考え、6 台構成の Search Head クラスターにおいて、各 Search Head の同時実行サーチ数を 150 に設定していました。6 台構成のクラスターのため、クラスター全体では 900 サーチを同時に実行できる設定です。
通常利用時には同時に 900 サーチが動くことはありませんでしたが、Splunk のバージョンアップ作業中に KV Store のアップデートが失敗するという不運が重なりました。
通常のスケジュールサーチは、ある時間帯に実行できなかった場合、その時間帯の実行をスキップします。一方、継続スケジュールサーチを設定すると、実行できなかった場合に過去分を継続してリトライします。これは、サマリインデックスの作成など、スキップが許容できないサーチで利用されるもので、Enterprise Security では継続スケジュールサーチが多用されています。継続スケジュールサーチでは、どの時間帯までサーチを実行したかを KV Store に記録する必要があります。
このユーザーも ES を利用していましたが、KV Store が利用できなくなったことで、継続スケジュールサーチの実行が停止してしまいました。KV Store の復旧には 1 週間以上かかり、その間、すべての継続スケジュールサーチが滞留する状態となっていました。
ようやく KV Store が復旧すると、それまで滞留していた継続スケジュールサーチが一気に動き始めます。Search Head クラスターは最大 900 サーチを同時実行できる設定のため、900 個のサーチが 72 CPU しかない Indexer に流れ込みました。その結果、Indexer の CPU 利用率は 1 を超え、待ち行列は無限に伸び続けます。
メモリが逼迫し、OS レベルで OOM Kill が発生、Indexer が再起動されます。継続スケジュールサーチは終了しない限り再実行されるため、再起動した Indexer に再び大量のサーチが流れ込み、再起動を繰り返すという完全な悪循環に陥りました。
この状態から復旧するためには、同時実行サーチ数を適正な値まで減らす必要がありました。
サーチスループットを上げるには
単位時間あたりのサーチ実行数を増やす必要がある場合、Indexer の CPU 利用率が低い水準であれば、Search Head 側の同時実行サーチ数を増やす余地があります。しかし通常は、Indexer の CPU 数に見合った Search Head が構成されているため、Indexer が 128 CPU なのに Search Head が 16 CPU しかないといった、極端にアンバランスな環境を除き、デフォルト設定を変更すべきではありません。
サーチのスループットを上げるためのベストプラクティスは、サーチの平均実行時間を短くすることです。これを実現する方法は大きく以下の 2 つがあります。
- 時間のかかっているサーチの実装を見直し、実行時間を短縮する
- Indexer の台数を増やし、サーチの実行時間を短くする
コンピュータ上の仕事量を増やすには、ジョブを軽くするか、リソースを追加するしかありません。考えてみれば、極めて当然のアプローチです。リソースが逼迫している状況では、単なる設定値を変更するだけで対応できるものではないということです。
今回は Splunk の同時実行サーチ数についてお話しました。次回は、どうすればサーチを速くできるのかについてご紹介したいと思います。