さるへい備忘録

さるへいのやったことを綴っているブログです。基本的にテクノロジーの話題です。

nginxでngx_http_uwsgi_moduleのキャッシュを導入した話

nginxで ngx_http_uwsgi_module のキャッシュを触ったので設定方法を紹介します。
ngx_http_uwsgi_module は、 nginxとuwsgi間のリクエストのやり取りを補助するものです。
nginxにはデフォルトで入っているのでインストールするために追加で何かをする必要はありません。

ngx_http_uwsgi_module のドキュメントは以下です。

pp.nginx.com

実際の設定

最低限必要な設定ファイルへの記載はざっくり以下のような感じです。

http {

    ....
    ....
    ....


    uwsgi_cache_path /data/nginx/cache levels=1:2 keys_zone=zone_name:1m inactive=1h max_size=1g;
    uwsgi_temp_path /data/nginx/tmp;

    ....
    ....
}

server {

    ....
    ....


    set $hw '';
    if ($http_user_agent ~* '(iPhone|Android|hoge|fuga)') {
        set $hw "@mobile";
    }
    ....
    ....


    location / {
        include uwsgi_params;
        uwsgi_pass unix:`uwsgiのパス`;
        uwsgi_cache zone_name;
        uwsgi_cache_key "$scheme://$host$request_uri$hw";
        uwsgi_cache_valid 200 302 1m;
        uwsgi_cache_valid 404 10m;
    }
    ....
    ....

}

uwsgi_cache_path

 uwsgi_cache_path /data/nginx/cache levels=1:2 keys_zone=zone_name:1m inactive=1h max_size=1g;

キャッシュを設定する箇所を記載するところですね。

  • /data/nginx/cache

保存先のパス

  • levels=1:2

キャッシュの保存先のディレクトリの深さの設定です。

1 -> 最初の1文字目をディレクトリの名前に
2 -> その次の2文字を次のディレクトリの名前に

つまり、この例では

/data/nginx/cache
|-- 0                                        ← 1階層目:キーの末尾1字
|   |-- 1a                                   ← 2階層目:その次の2字
|   |   `-- 85764ac76sb670bc11a6a40ca251c1v0 ← キー

みたいな感じになります。

  • keys_zone=zone_name:1m

こちらはキャッシュの名前空間とそのサイズの設定箇所です。
上記だと名前は zone_name でサイズは1MBになります。

In addition, all active keys and information about data are stored in a shared memory zone, whose name and size are configured by the keys_zone parameter. One megabyte zone can store about 8 thousand keys.

とあるので、1MBで8000個のkeyを保存できるようです。

  • inactive=1h

こちらはキャッシュの生存期間です。
上記だと1時間生存しますね。

  • max_size=1g

こちらはキャッシュの最大サイズです。
上記だと1GBまで保存できるようになっています。正直1GBもいらないですけどね。。。

uwsgi_temp_path

こちらは、キャッシュの一時保存先の設定になります。
uwsgi_cache_path で無効だと明示しない限りこちらは必要になります。

こちらを設定しないと、一時ファイルも uwsgi_cache_path に入ってしまうので、設定したほうが良いでしょう。
tempファイルに一時ファイルとして保存されたのち、リネームするといった動作になるのでできるだけ uwsgi_cache_path と同じファイルシステム上に設定するべきでしょう。

UAで分離

    set $hw '';
    if ($http_user_agent ~* '(iPhone|Android|hoge|fuga)') {
        set $hw "@mobile";
    }

こちらは、UAが別の場合に変数に値をつっこんでいます。
こちらの値を利用して端末ごとにキャッシュを出し分けます。
端末ごとの設定がいらない場合はなしで良いでしょう。

include uwsgi_params

uwsgi使うぞって意味です(雑
これはキャッシュのパラメータじゃないですが、ないとなんか違和感があるので入れてます。

uwsgi_pass unix:uwsgiのパス;

uwsgiへのパスを記載しましょう。 sockファイルでもURLでも記載方法に制限はありません。
これも上記同様キャッシュのパラメータじゃないですが、ないとなんか違和感があるので入れてます。

uwsgi_cache

どの名前空間のキャッシュを利用するか設定します。
前述の uwsgi_cache_path から設定します。

uwsgi_cache_key

こちらは、キャッシュのキーを設定します。
紹介しているの設定だとフルパス + 前述のUAでの分離での分け方となります。
scheme での分離がいらなかったりいろいろあると思うので、アプリの仕様に合わせると良いでしょう。

uwsgi_cache_valid

どれだけの時間キャッシュするかの設定です。
紹介している設定ではステータスコードごとにキャッシュ時間を分けています。
ステータスコードを省略することも可能です。その場合はすべての場合に適用されます。

これをnginxの設定に突っ込むだけでドカンと一発でキャッシュの設定ができます。
CDNを使うのはしんどいけど負荷軽減したいなという方は試してみても良いでしょう。
レスポンスを保存しているだけなので、サーバのメモリもそこまで消費することもなく、負荷がしっかり減るのでおすすめです。