LoginSignup
12
10

More than 5 years have passed since last update.

uWSGI の spare2 cheaper algorithm を作った

Posted at

Python だけじゃなくて Ruby, php, Perl も扱えるアプリケーションサーバー uWSGI に、 cheaper というモードがあります。これは負荷などに応じてワーカー数を動的に調整する機能です。

デフォルトでは spare, backlog, busyness という制御アルゴリズムがありました。が、どれも気に入らなかったので spare2 というアルゴリズムを作成して、本家にマージされました。取り込まれたのは master ブランチ (開発版) なので、安定版の uWSGI 2.0 用にプラグイン も用意しました。

今回追加した spare2 アルゴリズムの解説と、既存の他のアルゴリズムがなぜ採用しにくかったかを説明します。 (他のアルゴリズムの詳細は ドキュメント を参照してください。)

spare2

サンプルの設定ファイルを元に解説します。

[uwsgi]
...
processes=10
cheaper-algo=spare2

cheaper=2
cheaper-initial=2
cheaper-step=2
cheaper-idle=30

process=10 は最大ワーカープロセス数です。 cheaper=2 が最小プロセス数になり、この間で調整されることになります。 cheaper-initial=2 が起動直後のワーカー数になります。

spare2 アルゴリズムは、 cheaper で指定された数の idle 状態のワーカー数を維持しようとします。
例えば idle 状態のワーカー数が 1 つになった場合、 2 - 1 = 1 個のワーカーを起動します。

cheaper-step=2 は一度に起動するプロセス数の上限です。 cheaper が大きいときに、 cheaper-step であまりたくさんのプロセスを一気に起動しないように調整することができます。

idle 状態のプロセス数が cheaper よりも大きい状態が cheaper-idle=30 秒間続けば、ワーカープロセスを1つ停止します。この値を長く設定することで、細かくワーカーが停止&再開するのを防ぐことができます。

spare

[uwsgi]
...
processes=10
cheaper-algo=spare

cheaper=2
cheaper-initial=2
cheaper-step=2
cheaper-overload=5

spare アルゴリズムは、 idle 状態のプロセスが1つもない状態 (=overload) と、 idle 状態のプロセスが2つ以上ある状態 (=idle) をカウントします。
片方をカウントアップする場合はもう片方がリセットされますが、 idle プロセスが1つだけの状態ではどちらもカウントされません。

overload カウントが cheaper-overload=5 に到達した場合、 cheaper-step=2 個のワーカープロセスを追加します。
idle カウントが cheaper-overload=5 に到達した場合、1個のワーカープロセスを停止します。

このアルゴリズムは、サーバーを負荷分散配下に追加した場合などに速やかにワーカー数を増やすには、 cheaper-overload を小さく、 cheaper-step を大きく設定する必要があります。それでも、全部のワーカープロセスが busy になるまで新規ワーカーを立ち上げないので、初期のレスポンスタイムが大幅に悪化しやすいです。

また、 cheaper-overload=1 にしてしまうと、ワーカー数の小刻みな増減が発生しやすくなってしまいます。例えばワーカー数が40くらいある場合、 idle プロセスが2つあるだけでワーカーが停止されるのは、やりすぎに感じます。

backlog

spare に似ていますが、 Linux で TCP の backlog に溜まった接続数を監視できるのを利用して、 overload 判定をします。

spare の弱点を引き継いでいる上に、 nginx と uWSGI を unix ソケットで接続している場合に利用できないので、論外です。

busyness

spare を複雑にしたのが busyness です。

cheaper-overload をタイムフレームとして、その間 idle 状態のワーカーがなかった割合を busyness とします。この busyness の最小値と最大値を設定しておいて、最小値を下回ったらワーカーを減らし、最大値を上回ったらワーカーを増やします。

その他、ワーカーを減らしにくくするためのオプションがあったり、 backlog を監視してタイムフレームを待たずにワーカーを追加するオプションがあったりとかなり複雑ですが、これもやはり最初にスムースにワーカー数を増やすのが難しく、突入負荷への対応に難があります。

12
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
10