20

私が抱えていた問題

一部のサイトの読み込みに時間がかかるという問題がありました (「長い時間」とは、最大 16 秒を意味します)。場合によっては完全にタイムアウトし、Nginx 504 エラーが発生することがあります。通常、サイトがタイムアウトしたときに、サイトを再度リロードすると、すぐに読み込まれます。私が問題を抱えていたサイトは、トラフィック量が非常に少ない. 貧弱なコードが原因で発生する可能性のある速度低下を排除するために、Django 管理者インデックス ページを読み込んでサイトをテストしています。この特定のサイトは、スタッフ専用のイントラネット タイプのサイトであるため、Django 管理者のみを使用していることにも注意してください。

ホスティングのセットアップ

私がホストしているすべてのサイトは、2 つの Rackspace クラウド サーバー上にあります。最初のサーバーは 1024 MB の RAM を搭載したアプリ サーバーで、2 番目のサーバーは 2048 MB の RAM を搭載したデータベース サーバーです。アプリ サーバーは Nginx を使用して各サイトを提供しています。Nginx はすべての静的ファイルを提供し、その他すべてを各サイトの Django Gunicorn ワーカーにプロキシします。

データベース サーバーの RAM と CPU 負荷を見ると、データベース サーバー上ですべて問題ないように見えます。

$ free -m
             total       used       free     shared    buffers     cached
Mem:          1999       1597        402          0        200       1007
-/+ buffers/cache:        389       1610
Swap:         4094          0       4094


Top shows a CPU load average of: 0.00, 0.01, 0.05

何が起こっているのかをトラブルシューティングするために、アプリ サーバーのメモリ使用量を出力する簡単なスクリプトを作成しました。

匿名化されたサイト ドメインの出力例:

Celery:     23 MB
Gunicorn:  566 MB
Nginx:       8 MB
Redis:     684 KB
Other:      73 MB

             total       used       free     shared    buffers     cached
Mem:           993        906         87          0         19         62
-/+ buffers/cache:        824        169
Swap:         2047        828       1218

Gunicorn memory usage by webste:
site01.example.com    31 MB
site02.example.com    19 MB
site03.example.com     7 MB
site04.example.com     9 MB
site05.example.com    47 MB
site06.example.com    25 MB
site07.example.com    14 MB
site08.example.com    18 MB
site09.example.com    27 MB
site10.example.com    15 MB
site11.example.com    14 MB
site12.example.com     7 MB
site13.example.com    18 MB
site14.example.com    18 MB
site15.example.com    10 MB
site16.example.com    25 MB
site17.example.com    13 MB
site18.example.com    18 MB
site19.example.com    37 MB
site20.example.com    30 MB
site21.example.com    23 MB
site22.example.com    28 MB
site23.example.com    80 MB
site24.example.com    15 MB
site25.example.com     5 MB

Gunicorn 設定ファイルの例:

pidfile = '/var/run/gunicorn_example.com.pid'
proc_name = 'example.com'
workers = 1
bind = 'unix:/tmp/gunicorn_example.com.sock'

Nginx 構成の例:

upstream example_app_server {
    server unix:/tmp/gunicorn_example.com.sock fail_timeout=0;
}

server {

    listen       80;
    server_name  example.com;
    access_log   /var/log/nginx/example.com.access.log;
    error_log    /var/log/nginx/example.com.error.log;

    location = /favicon.ico {
        return  404;
    }

    location  /static/ {
        root  /srv/sites/example/;
    }

    location  /media/ {
        root  /srv/sites/example/;
    }

    location  / {
        proxy_pass            http://example_app_server;
        proxy_redirect        off;
        proxy_set_header      Host             $host;
        proxy_set_header      X-Real-IP        $remote_addr;
        proxy_set_header      X-Forwarded-For  $proxy_add_x_forwarded_for;
        client_max_body_size  10m;
    }

}

ご覧のとおり、大量のメモリがスワップされているため、問題を修正するために、アプリ サーバーの RAM をアップグレードしました。これにより、サイトの速度が完全に修正されました。問題を修正することはできましたが、思ったよりも時間がかかり、サイトの速度低下の原因を基本的に推測していたように感じます. これらすべてが私の質問につながります...

質問

  1. トラフィックの少ないサイトでサイトの速度が遅いのは、サイトが非アクティブになったためにサイトが非アクティブになり、Gunicorn がサイトが非アクティブになった後に再度サイトをロードする必要があるためではないことをどのように判断できますか? サイトが非アクティブにならないようにする設定はありますか?
  2. メモリを大量に消費しているサイトがいくつかあるようです。サイトが使用しているメモリの量を減らすために使用できるツールは何ですか? Python プロファイリング ツールを使用する必要がありますか?
  3. スタック内のどのレベルでボトルネックが発生しているかを判断するために必要なツールと手順は何ですか?
  4. Gunicorn プロセスがスワップされているのか、それとも他のプロセスがスワップされているのかを判断する最良の方法は何ですか?
  5. 私がホストしているサイトのほとんどは大量のトラフィックを獲得していないため、Gunicorn ワーカーを 1 つだけ使用しています。サイトにある Gunicorn ワーカーの数を決定および調整するための、より科学的な方法はありますか?
  6. 同じサーバーで複数のサイトをホストする場合、メモリの使用量を減らすように構成する方法はありますか?
4

3 に答える 3

4

これは、RAMが1GBしかないサーバーでホストするサイトがたくさんあります。ほぼ100%のメモリ使用率であり、現在の数値はおそらく「スタンバイ」数値です。各プロセスのRAM使用量は、要求を処理するプロセスで膨らむ可能性があります。すぐに、このインスタンスにRAMを追加する必要があります。さらに、一部のサイトを別のサーバーに移動することをお勧めします。

あなたの質問に関して:

  1. サイトが「非アクティブ」になり、Gunicornがサイトを再度ロードする必要があるという考えはどこで得られましたか?それはゴミです。Gunicornプロセスが実行されている限り(つまり、手動で終了したり、サイトのエラーによって終了したりしない限り)、1時間でも1か月でも、完全に初期化されてすぐに使用できます。

  2. あなたはここの葉をハッキングしていて、根はそのままにしておきます。各Gunicornプロセスのメモリ使用量に異常はありません。実行するにはRAMが必要です。あなたの問題は、非常に電力が不足しているサーバーで実行しすぎていることです。ここであなたを救う最適化はありません。より多くのRAMまたはより多くのサーバーが必要です。おそらく両方。

  3. 必要なし。繰り返しますが、問題はすでに特定されています。あなたが投稿した数字からすると、実はかなりはっきりしています。

  4. どのプロセスがスワップされているかを確実に知る方法はありません。それは毎秒変化し、どれがアクティブに実行されていて、より多くのRAMが必要で、どれが非アクティブであるか、または単にアクティブではないかによって異なります。サーバーがこのようにリソースに縛られている場合、特にすべてのサーバーがアクティブでリソースを争っている場合は、次にどのプロセスを調整するかを判断するために半分の時間を費やしています。

  5. はい。Gunicornは2*コア+1を推奨しています。つまり、デュアルコアシステムでは、これは5です。クアッドコア9。ただし、この1つのシステムでこれらのサイトごとに5人のワーカーを実行する方法はありません。それぞれに1人のワーカーを確実に実行することさえできません。

  6. それは「もの」に依存します。ただし、複数のサイトが同じサーバーでホストされている場合、それらのサーバーは仕様上獣です。あなたが持っているような小さな、おそらくVPSインスタンスでは、特に1GBのRAMしかない場合、1つのサイトがほとんど制限になります。二、多分。

于 2012-05-01T19:46:22.463 に答える
1

1) 非アクティブの意味がわかりませんか? のように、nginxによって無効にされていますか? それとも動作が遅すぎるだけですか?

2 と 3) django-debug-toolbar と django-debug-logging は、開始するのに適した場所です。これで問題が解決しない場合は、サーバー レベルのプロファイリングに移行して、問題の原因となっているプロセスを確認します。

4) top を使用:どのプロセスが Linux でスワッピングしているかを調べるには?

5) はい - ベンチマーク。ベンチマーク ツール (apachebench など) を選択し、現在の構成に対してテストを実行します。何かを微調整します。テストを再度実行します。パフォーマンスの問題がなくなるまで繰り返します。最良の結果を得るには、実際のトラフィックと同様のトラフィックを使用してください (URL 配布、GET/POST などに関して)。

6) はい、nginx レベルとアプリ レベルの両方で。おそらく、各サイトのプロファイリングを行い、そのメモリ使用量を改善することで最大のメリットが得られます (2 を参照)。

于 2012-05-08T06:42:17.977 に答える
1

それにかんする:

5に対するあなたの答えに関して、Gunicornが推奨するのはやり過ぎだと思います.

最近、ワーカーの数を使ってアドホック テストを行ったところ、十分な RAM があると仮定すると、2*コア + 1 という経験則がかなり正確であることがわかりました。その数に近づくまでリクエスト/秒がほぼ直線的に増加し、OS がスラッシングし始めると減少することがわかりました。

結果はワークロードに大きく依存するため、さまざまな値を試して、パフォーマンスがどこでピークに達するかを確認してください。

于 2012-05-09T10:48:30.510 に答える