NGINXでキャッシュを行う

NGINXでリバースプロキシする際、キャッシュを行いパフォーマンスを上げることができます。

メリット
・upstreamサーバへのリクエストを減らすことができる。
・NGINXとupstreamサーバ間のトラフィック削減
・レスポンス速度が早くなる

デメリット
・キャッシュの更新を考えた場合に処理が複雑になる可能性がある。
・NGINXサーバでディスク使用量の増加
・NGINXサーバでIO負荷がかかる

設定方法

現在の一時ファイルについての設定確認

# nginx -V 2>&1 | sed 's/ --/\n --/g' | fgrep proxy-temp-path
# fgrep -nr proxy_temp_path /etc/nginx/

設定

http {
  #proxy_temp_path /var/cache/nginx/proxy_temp;
  proxy_cache_path /var/cache/nginx/cache_1 levels=1:2 keys_zone=cache_zone_1:16m max_size=100m inactive=120m;

  upstream backend {
    server 192.168.0.101;
    server 192.168.0.102;
  }

  server {
    listen 80;
    server_name _;

    location / {
      proxy_pass http://backend;

      proxy_set_header Host $http_host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;

      proxy_ignore_headers X-Accel-Expires Cache-Control Expires;

      proxy_cache cache_zone_1;
      proxy_cache_key "$scheme$proxy_host$request_uri";
      proxy_cache_valid 200 60m;
      proxy_cache_valid any 5m;

      add_header X-Cache-Status $upstream_cache_status;
    }
  }
}

proxy_cache_pathディレクティブ

/var/cache/nginx/cache_1:キャッシュファイル保存場所
キャッシュを行う場合、一旦レスポンスをproxy_temp_pathで指定した一時ファイルに保存してからのrenameとなるため同じデバイスになるよう注意
実ディレクトリは/var/cache/nginxまで存在していればcache_1は自動で作成されます。

levels=1:2:キャッシュを保存する階層
キャッシュファイル名はproxy_cache_keyをmd5したものになり、階層はファイル名の一部が利用されます。
md5が3858f62230ac3c915f300c664312c63fだった場合のファイルパス
/var/cache/nginx/cache_1/f/63/3858f62230ac3c915f300c664312c63f

keys_zone=cache_zone_1:16m:キャッシュゾーンの名前とメモリサイズ。
メモリサイズは1つのキャッシュにつき128バイト使われる(64bit環境)
この例だと16mになっているので約130000ファイル保存できます。
※よく使われるサイズの単位
g:ギガバイト
m:メガバイト
k:キロバイト

max_size=100m:キャッシュファイルの総容量
nginxは定期的にcache managerと呼ばれるプロセスを起動し、容量を監視しています。この時最大容量を超えていた場合は最も長い期間アクセスされなかったファイルから削除されます。
※最大容量を超えた瞬間ではなく、定期的にチェックされる=一時的に最大容量を超えた状態になる。

inactive=120m:最後にアクセスされてからキャッシュファイルが削除されるまでの時間
120mの場合、最後にアクセスされてから120分アクセスがないと削除されます。
※よく使われる時間の単位
M:月
d:日
h:時間
m:分
s:秒

proxy_cacheディレクティブ

proxy_cache_pathで設定したキャッシュゾーンの名前を指定

proxy_cache_keyディレクティブ

キャッシュのキーとして使用する値を指定

proxy_cache_validディレクティブ

ステータスごとのキャッシュの有効期限の指定
ステータスを指定しない場合は200,301,302のレスポンスのみがキャッシュされる。anyを指定した場合は明示的に指定していないすべてのステータスコードに設定することができる。

proxy_ignore_headersディレクティブ

backendからのレスポンスで無視するヘッダーを指定する
Cache-Control及びExpiresを指定することでproxy_cache_validの設定が生きる
キャッシュ設定の優先順位
X-Accel-Expiresヘッダ > Cache-Controlヘッダ > proxy_cache_valid

※Set-Cookieヘッダがある場合、通常はキャッシュされませんがproxy_ignore_headersで無視してキャッシュする事も可能です。
ただしこの場合proxy_hide_headerも指定しておかないと他人にもcookieがセットされてしまいます。

add_headerディレクティブ

サンプルの場合X-Cache-Statusというレスポンスヘッダ名でキャッシュのステータスを返しています。

簡単にNGINXのキャッシュ設定について説明しました。
NGINXの設定は奥が深いので色々試してみましょう。

コメント