🙌

SidekiqのAutoscaleにはQueue Latencyを指標に使うと良い

に公開

Sidekiqのworkerをautoscale設定を入れるに当たってどんなメトリクスを指標にすれば良いか、悩んだことはないだろうか。
私はかなり悩んだ。既存のCPUベースのautoscaleはQueueの処理を捌くためにあまり適切ではないということは分かっていたが、他に適切な指標がすぐには思いつかなかったのである。
ただ困ったときは公式ドキュメントを読むという自信の指針に従い公式ドキュメントを読むと、Queue latencyを使えば良いとはっきり書いてあったのだった。
公式に書いてあるのでわざわざ書くことにそれほど意味はないかもしれないが、同じように悩んでいる人の役に立てば幸いと思い、ここに記録することにした。

課題

SidekiqのWorkerをどのようなメトリクスをベースにautoscaleさせるかを検討していた。
SidekiqはJobサービスであるためその本質はどれだけ多くのJobを捌けるかにある。Autoscaleの設定をするにあたって、最初におもいつくのはCPU利用率だがこれはシステムの特性上適切ではない。複数のJobを処理という性質上重要なのはどれだけ多くのJobを捌けるか、つまりWorkerは適切に用意できるかという点にあり、CPU利用率は特定のJobの負荷は計測できてもQueueに積まれたJobが捌かれているかという点にはおいては不適なのである。
つぎにQueue(worker)の利用率を考えたがこれもあまり適切ではない。というのも、Queueの利用率が高くなってworkerを増やしたとしても増やした瞬間に利用率が下がりすぐにスケールインが始まり、またスケールアウトをするという状況が考えられる。(もちろん間に冷却期間はあるはずで、そこまで頻繁ではないにしても)。またEnqueueが多くてもすぐに捌けていればそれは特に問題にはならない。問題なのは長期滞留しているJobが増えてしまうことだ。それを適切に管理することができる指標が何かないか、と悩んでいた。

そういう状況で対処方法を検討していたら公式に対応が書いてあることが確認出来た

Queue Latencyを指標にする

Instead, you should autoscale your Sidekiq containers using queue latency. Your business requirements will have an implicit (or hopefully explicit) expectation how long each job can reasonably wait before being processed. This expectation makes queue latency the perfect metric for autoscaling. (And if you’re using latency-based queue names, you’ve already identified those latency expectations!)

https://github.com/sidekiq/sidekiq/wiki/Scaling-Sidekiq#autoscale-your-sidekiq-containers

上記の通り自分が悩んでいたことについての回答そのものが書いてあるのである。
たしかにQueue Latencyなら他の指標と違ってスケールアウトとスケールインを繰り返す心配はない。

公式としては以下のものを使うと良いという推奨まである。

Several services exist for autoscaling Sidekiq based on queue latency:

Heroku: Judoscale, HireFire
Render: Judoscale
AWS: CloudWatch*, Judoscale
Kubernetes: HPA*
(*) You’ll need to measure queue latency yourself and report it to CloudWatch or HPA.

自前での実装が必要

ただし、上記のサービスは使っていないためどうやら自前で計測をしていく必要がある。ここについては、すでに https://github.com/discourse/prometheus_exporter を使ってMetricsをDatadogに取得しており問題がない状態だった。ただしそのMetricsはCloudwatchに送ってはおらず、Datadogに送信している。そのため、CloudwatchをベースにしたAutoscaleは使えない。ちょっと困った事になった。

Datadog Actionsを利用した、Autoscaleの実装

Datadogにはworkflowという機能があり、これを利用するばアラートがなったときに特定の処理をすることが出来る。まさに今回のユースケースにちょうど良かったのである。

https://docs.datadoghq.com/ja/service_management/workflows/

ドキュメントを読みながらAWSのIAM設定などを行いテストなどをしながら、本番に備えることにした。

QueueLatencyの効果について

本番環境でついにJobのつまりが発生した際に挙動を確認していたが、特に予想外のことも発生せずに想定通りにスケールアウトとスケールインをさせることができた。
もう少し予想外の事が起きるかと思ったが、全くそんなことはなく無事にQueueのつまりを解消することができたのだった。

結論

Queue Latencyを指標にすることで適切にSidekiqのAutoscaleをスムーズに行うことができた。また、何かしら困ったときはとりあえず公式ドキュメントを読むと良いという事が改めて身にしみた一件でもあった。

Discussion