Nginx キャッシュ設定:Webサイト表示速度を改善するテクニック集
Webサイトのパフォーマンスは、ユーザーエクスペリエンス、検索エンジンのランキング、コンバージョン率に大きく影響します。表示速度が遅いWebサイトは、ユーザーを苛立たせ、直帰率を高め、結果としてビジネス機会の損失につながる可能性があります。そこで重要になるのが、Webサーバーのキャッシュ機能です。中でも、Nginxは高性能なWebサーバーとして広く利用されており、効果的なキャッシュ設定を行うことで、Webサイトのパフォーマンスを大幅に向上させることができます。
本記事では、Nginxのキャッシュ設定について、基礎から応用まで網羅的に解説します。基本的な概念から具体的な設定方法、パフォーマンスチューニングのヒントまで、Webサイトの表示速度を改善するためのテクニックを余すことなくご紹介します。
目次
- キャッシュの基本概念
- 1.1 キャッシュとは?
- 1.2 キャッシュの種類:ブラウザキャッシュ、CDNキャッシュ、サーバーキャッシュ
- 1.3 Nginxキャッシュの役割とメリット
- Nginxキャッシュの設定方法:基本編
- 2.1
proxy_cache_path
ディレクティブ:キャッシュストレージの定義 - 2.2
proxy_cache_key
ディレクティブ:キャッシュキーの定義 - 2.3
proxy_cache
ディレクティブ:キャッシュの有効化 - 2.4 基本的なキャッシュ設定例:静的コンテンツと動的コンテンツ
- 2.1
- Nginxキャッシュの設定方法:応用編
- 3.1
proxy_cache_valid
ディレクティブ:キャッシュ有効期間の設定 - 3.2
proxy_cache_bypass
ディレクティブ:キャッシュのバイパス条件 - 3.3
proxy_no_cache
ディレクティブ:キャッシュしない条件 - 3.4
proxy_cache_lock
ディレクティブ:キャッシュスタンプedeの防止 - 3.5 キャッシュpurge(キャッシュ削除)の設定:
ngx_cache_purge
モジュール
- 3.1
- キャッシュ制御ヘッダーとの連携
- 4.1
Cache-Control
ヘッダー:クライアントとサーバー間のキャッシュ制御 - 4.2
Expires
ヘッダー:キャッシュの有効期限 - 4.3
ETag
ヘッダーとLast-Modified
ヘッダー:条件付きGETリクエスト - 4.4 キャッシュ制御ヘッダーの最適な設定方法
- 4.1
- 動的コンテンツのキャッシュ
- 5.1 SSI(Server Side Includes)による部分的なキャッシュ
- 5.2 Redisなどの外部キャッシュストレージとの連携
- 5.3 レイヤー化されたキャッシュ戦略
- キャッシュパフォーマンスの監視とチューニング
- 6.1 Nginxのステータスモジュール(
ngx_http_stub_status_module
)の利用 - 6.2 キャッシュヒット率の監視と分析
- 6.3 キャッシュストレージのサイズの最適化
- 6.4 キャッシュキーの最適化
- 6.5 キャッシュのウォームアップ
- 6.1 Nginxのステータスモジュール(
- キャッシュ設定のトラブルシューティング
- 7.1 キャッシュが有効にならない原因と対策
- 7.2 キャッシュキーが適切でない場合の対処法
- 7.3 キャッシュストレージの容量不足の解消
- 7.4 セキュリティ上の考慮事項
- まとめ:Nginxキャッシュ設定のベストプラクティス
1. キャッシュの基本概念
1.1 キャッシュとは?
キャッシュとは、頻繁にアクセスされるデータを一時的に保存し、次回以降のアクセス時に高速に提供する仕組みです。Webサイトにおいては、画像、CSS、JavaScript、HTMLなどのコンテンツをキャッシュすることで、Webサーバーへの負荷を軽減し、ユーザーへのレスポンス速度を向上させることができます。
1.2 キャッシュの種類:ブラウザキャッシュ、CDNキャッシュ、サーバーキャッシュ
Webサイトのキャッシュには、主に以下の3つの種類があります。
- ブラウザキャッシュ: ユーザーのブラウザにコンテンツを保存する仕組みです。同じWebサイトに再度アクセスした場合、ブラウザはサーバーにリクエストを送らず、キャッシュされたコンテンツを表示します。これにより、非常に高速な表示が可能になります。
- CDNキャッシュ: CDN(Content Delivery Network)は、世界中に分散されたサーバーネットワークです。WebサイトのコンテンツをCDNにキャッシュすることで、ユーザーは最寄りのサーバーからコンテンツを受け取ることができ、地理的な要因による遅延を軽減できます。
- サーバーキャッシュ: Webサーバー自体にコンテンツをキャッシュする仕組みです。Nginxはこのサーバーキャッシュとして機能し、バックエンドサーバーへのリクエストを減らし、レスポンス速度を向上させます。
1.3 Nginxキャッシュの役割とメリット
Nginxは、リバースプロキシとして機能し、バックエンドサーバー(例:Apache、Node.js)の前に配置されることが一般的です。Nginxキャッシュを有効にすると、以下のメリットがあります。
- レスポンス速度の向上: Nginxはキャッシュされたコンテンツを高速に提供するため、Webサイトの表示速度が大幅に向上します。
- バックエンドサーバーの負荷軽減: キャッシュされたコンテンツはNginxから提供されるため、バックエンドサーバーへのリクエストが減り、サーバーの負荷を軽減できます。
- トラフィックコストの削減: キャッシュされたコンテンツはバックエンドサーバーから提供されないため、データ転送量が減少し、トラフィックコストを削減できます。
- サーバーダウン時の可用性向上: バックエンドサーバーがダウンした場合でも、キャッシュされたコンテンツを提供することで、Webサイトの一時的な停止を防ぐことができます(graceful degradation)。
2. Nginxキャッシュの設定方法:基本編
Nginxでキャッシュを設定するには、主に以下のディレクティブを使用します。
proxy_cache_path
: キャッシュストレージの場所と設定を定義します。proxy_cache_key
: キャッシュキーを定義します。proxy_cache
: キャッシュを有効にするコンテキストを指定します。
2.1 proxy_cache_path
ディレクティブ:キャッシュストレージの定義
proxy_cache_path
ディレクティブは、キャッシュストレージの場所、サイズ、有効期間などを定義します。このディレクティブは、http
コンテキスト内で一度だけ定義する必要があります。
nginx
http {
proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m inactive=60m max_size=1g;
...
}
各パラメータの意味は以下の通りです。
/path/to/cache
: キャッシュファイルを保存するディレクトリを指定します。このディレクトリはNginxユーザーが書き込み可能な必要があります。levels
: ディレクトリ階層のレベルを指定します。この例では、1:2と指定されているため、キャッシュファイルは2階層のディレクトリ構造で保存されます。これにより、1つのディレクトリに大量のファイルが保存されるのを防ぎ、ファイルシステムのパフォーマンスを向上させることができます。keys_zone
: キャッシュキーを保存する共有メモリ領域の名前とサイズを指定します。この例では、my_cache
という名前で10MBのメモリ領域を割り当てています。キャッシュキーは、キャッシュされたコンテンツを識別するために使用されます。inactive
: キャッシュされたコンテンツが指定された時間(この例では60分)アクセスされない場合、自動的に削除されます。max_size
: キャッシュストレージの最大サイズを指定します。この例では、1GBに設定されています。最大サイズを超えると、Nginxは最もアクセス頻度の低いコンテンツから順に削除します。
2.2 proxy_cache_key
ディレクティブ:キャッシュキーの定義
proxy_cache_key
ディレクティブは、キャッシュキーを定義します。キャッシュキーは、キャッシュされたコンテンツを識別するために使用されます。デフォルトでは、$scheme$proxy_host$request_uri
が使用されますが、必要に応じてカスタマイズすることができます。
nginx
proxy_cache_key "$host$request_uri$is_args$args";
この例では、ホスト名、URI、クエリパラメータを含めた文字列をキャッシュキーとして使用しています。$is_args
と$args
は、クエリパラメータの有無を考慮するために使用されます。
2.3 proxy_cache
ディレクティブ:キャッシュの有効化
proxy_cache
ディレクティブは、キャッシュを有効にするコンテキストを指定します。このディレクティブは、http
, server
, location
コンテキストで使用できます。
nginx
location / {
proxy_pass http://backend;
proxy_cache my_cache;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
}
この例では、/
以下のすべてのリクエストに対して、my_cache
という名前のキャッシュを有効にしています。proxy_pass
ディレクティブは、リクエストをバックエンドサーバーに転送する際に使用されます。proxy_cache_valid
ディレクティブは、HTTPステータスコードに基づいてキャッシュの有効期間を設定します(後述)。
2.4 基本的なキャッシュ設定例:静的コンテンツと動的コンテンツ
静的コンテンツのキャッシュ:
nginx
location ~* \.(jpg|jpeg|png|gif|css|js|ico)$ {
expires 30d;
add_header Cache-Control "public, max-age=2592000";
access_log off;
log_not_found off;
}
この例では、JPG、JPEG、PNG、GIF、CSS、JS、ICOファイルなどの静的コンテンツに対して、ブラウザキャッシュを有効にしています。expires
ディレクティブは、ブラウザに対してキャッシュの有効期間を30日に設定します。add_header
ディレクティブは、Cache-Control
ヘッダーを設定し、同様にキャッシュの有効期間を30日に設定します。access_log off
とlog_not_found off
は、アクセスログと404エラーログを無効にすることで、ディスクI/Oを減らし、パフォーマンスを向上させます。
動的コンテンツのキャッシュ:
nginx
location / {
proxy_pass http://backend;
proxy_cache my_cache;
proxy_cache_valid 200 10m; # 200 OKレスポンスを10分間キャッシュ
proxy_cache_valid 404 1m; # 404 Not Foundレスポンスを1分間キャッシュ
proxy_cache_valid 500 5m; # 500 Internal Server Errorレスポンスを5分間キャッシュ
proxy_cache_use_stale error timeout updating invalid_header http_500 http_502 http_503 http_504;
proxy_cache_lock on;
proxy_cache_lock_timeout 5s;
proxy_cache_lock_age 30s;
}
この例では、すべてのリクエストに対して、my_cache
という名前のキャッシュを有効にしています。proxy_cache_valid
ディレクティブは、HTTPステータスコードに基づいてキャッシュの有効期間を設定します。例えば、200 OKレスポンスは10分間、404 Not Foundレスポンスは1分間キャッシュされます。proxy_cache_use_stale
ディレクティブは、バックエンドサーバーがダウンした場合でも、キャッシュされた古いコンテンツを提供し続けるように設定します。proxy_cache_lock
ディレクティブは、キャッシュスタンプedeの発生を防ぎます(後述)。
3. Nginxキャッシュの設定方法:応用編
3.1 proxy_cache_valid
ディレクティブ:キャッシュ有効期間の設定
proxy_cache_valid
ディレクティブは、HTTPステータスコードに基づいてキャッシュの有効期間を設定します。複数のステータスコードと有効期間を個別に指定することができます。
nginx
proxy_cache_valid 200 10m;
proxy_cache_valid 301 1h;
proxy_cache_valid 404 1m;
この例では、200 OKレスポンスは10分間、301 Moved Permanentlyレスポンスは1時間、404 Not Foundレスポンスは1分間キャッシュされます。
3.2 proxy_cache_bypass
ディレクティブ:キャッシュのバイパス条件
proxy_cache_bypass
ディレクティブは、指定された条件に一致する場合、キャッシュをバイパスし、バックエンドサーバーにリクエストを転送します。例えば、特定のクッキーが存在する場合や、特定のURLにアクセスした場合にキャッシュをバイパスすることができます。
nginx
proxy_cache_bypass $http_cookie;
proxy_cache_bypass $arg_nocache;
この例では、Cookie
ヘッダーが存在する場合、またはnocache
というクエリパラメータが存在する場合に、キャッシュをバイパスします。
3.3 proxy_no_cache
ディレクティブ:キャッシュしない条件
proxy_no_cache
ディレクティブは、指定された条件に一致する場合、キャッシュを行いません。proxy_cache_bypass
ディレクティブと似ていますが、proxy_no_cache
はキャッシュ自体を無効にする点が異なります。
nginx
proxy_no_cache $http_cookie;
この例では、Cookie
ヘッダーが存在する場合、キャッシュを行いません。
3.4 proxy_cache_lock
ディレクティブ:キャッシュスタンプedeの防止
proxy_cache_lock
ディレクティブは、キャッシュスタンプedeと呼ばれる現象を防ぎます。キャッシュスタンプedeとは、キャッシュがまだ作成されていない場合に、同じリソースに対する複数のリクエストが同時にバックエンドサーバーに転送され、サーバーに負荷がかかる現象です。proxy_cache_lock
を有効にすると、最初のリクエストのみがバックエンドサーバーに転送され、その結果がキャッシュに保存されるまで、他のリクエストは待機します。
nginx
proxy_cache_lock on;
proxy_cache_lock_timeout 5s; # ロックのタイムアウト時間
proxy_cache_lock_age 30s; # ロックが適用される時間
この例では、proxy_cache_lock
を有効にし、ロックのタイムアウト時間を5秒、ロックが適用される時間を30秒に設定しています。
3.5 キャッシュpurge(キャッシュ削除)の設定:ngx_cache_purge
モジュール
ngx_cache_purge
モジュールを使用すると、特定のキャッシュされたコンテンツを削除することができます。このモジュールは、デフォルトではNginxに含まれていないため、別途インストールする必要があります。
“`nginx
インストール (例: Ubuntu/Debian)
sudo apt-get install nginx-module-ngx-cache-purge
設定 (例: nginx.conf)
http {
…
map $request_method $purge_method {
PURGE 1;
default 0;
}
server {
…
location ~ /purge(/.*) {
allow 127.0.0.1; # アクセスを制限
deny all;
proxy_cache_purge my_cache “$scheme$request_method$host$1”;
}
…
}
}
“`
この例では、PURGE
メソッドを使用してキャッシュを削除できるように設定しています。特定のIPアドレスからのアクセスのみを許可するように制限することをお勧めします。キャッシュを削除するには、次のようなリクエストを送信します。
bash
curl -X PURGE http://example.com/purge/path/to/resource
4. キャッシュ制御ヘッダーとの連携
キャッシュ制御ヘッダーは、クライアント(ブラウザなど)とサーバー間のキャッシュの動作を制御するために使用されます。Nginxは、これらのヘッダーを解釈し、適切にキャッシュを処理します。
4.1 Cache-Control
ヘッダー:クライアントとサーバー間のキャッシュ制御
Cache-Control
ヘッダーは、最も汎用的なキャッシュ制御ヘッダーであり、様々なディレクティブを使用してキャッシュの動作を制御します。
public
: キャッシュは、ブラウザとCDNなどの中間キャッシュサーバーによってキャッシュできます。private
: キャッシュは、ブラウザのみによってキャッシュできます。max-age
: キャッシュの有効期間を秒単位で指定します。s-maxage
: CDNなどの共有キャッシュの有効期間を秒単位で指定します。no-cache
: キャッシュを使用する前に、サーバーに再検証を要求します。no-store
: キャッシュを一切行いません。
4.2 Expires
ヘッダー:キャッシュの有効期限
Expires
ヘッダーは、キャッシュの有効期限を日付と時刻で指定します。Cache-Control
ヘッダーよりも古くからあるヘッダーですが、互換性のために使用されることがあります。
4.3 ETag
ヘッダーとLast-Modified
ヘッダー:条件付きGETリクエスト
ETag
ヘッダーは、リソースのバージョンを識別するために使用されます。Last-Modified
ヘッダーは、リソースが最後に更新された日付と時刻を指定します。これらのヘッダーは、条件付きGETリクエスト(If-None-Match
ヘッダーまたはIf-Modified-Since
ヘッダーを使用)を可能にし、キャッシュされたリソースが変更されていない場合に、サーバーは304 Not Modified
レスポンスを返すことで、データ転送量を削減できます。
4.4 キャッシュ制御ヘッダーの最適な設定方法
キャッシュ制御ヘッダーの最適な設定方法は、Webサイトのコンテンツの種類と更新頻度によって異なります。
- 静的コンテンツ:
Cache-Control: public, max-age=31536000
(1年間)のような長期間のキャッシュを設定します。 - 動的コンテンツ:
Cache-Control: no-cache
またはCache-Control: max-age=0
を設定し、サーバーに再検証を要求します。ETag
ヘッダーまたはLast-Modified
ヘッダーを使用して、条件付きGETリクエストをサポートします。 - 頻繁に更新されるコンテンツ:
Cache-Control: max-age=60
(1分間)のような短期間のキャッシュを設定します。
5. 動的コンテンツのキャッシュ
動的コンテンツは、ユーザーのリクエストに基づいて生成されるため、キャッシュが難しい場合があります。しかし、Nginxは、いくつかのテクニックを使用して動的コンテンツのキャッシュを可能にします。
5.1 SSI(Server Side Includes)による部分的なキャッシュ
SSI(Server Side Includes)は、HTMLページに動的なコンテンツを埋め込むことができる技術です。Nginxは、SSIを使用して、HTMLページの一部をキャッシュすることができます。
nginx
location / {
proxy_pass http://backend;
proxy_cache my_cache;
proxy_cache_valid 200 10m;
ssi on;
}
この例では、SSIを有効にし、HTMLページに<!--#include virtual="/dynamic_content" -->
のようなSSIディレクティブを埋め込むことで、/dynamic_content
というURLで提供される動的コンテンツを部分的にキャッシュすることができます。
5.2 Redisなどの外部キャッシュストレージとの連携
Nginxは、Redisなどの外部キャッシュストレージと連携することができます。これにより、より複雑なキャッシュ戦略を実装することができます。ngx_http_redis
モジュールを使用すると、Nginxから直接Redisにアクセスし、キャッシュされたコンテンツを取得することができます。
5.3 レイヤー化されたキャッシュ戦略
複数のキャッシュレイヤーを使用することで、パフォーマンスをさらに向上させることができます。例えば、ブラウザキャッシュ、CDNキャッシュ、Nginxキャッシュ、Redisキャッシュなどの組み合わせを使用することができます。
6. キャッシュパフォーマンスの監視とチューニング
キャッシュパフォーマンスを監視し、適切にチューニングすることで、Webサイトの表示速度を最大限に向上させることができます。
6.1 Nginxのステータスモジュール(ngx_http_stub_status_module
)の利用
ngx_http_stub_status_module
モジュールを使用すると、Nginxの基本的なステータス情報を取得することができます。このモジュールは、デフォルトではNginxに含まれているため、有効にするだけで使用できます。
nginx
location /nginx_status {
stub_status;
allow 127.0.0.1; # アクセスを制限
deny all;
}
この例では、/nginx_status
というURLでステータス情報を提供するように設定しています。アクセスを制限することをお勧めします。ステータス情報には、アクティブな接続数、リクエスト数、接続数などが含まれます。
6.2 キャッシュヒット率の監視と分析
キャッシュヒット率は、キャッシュからコンテンツが提供された割合を示す指標です。キャッシュヒット率が高いほど、キャッシュが効果的に機能していることを意味します。キャッシュヒット率は、Nginxのログを分析したり、専用の監視ツールを使用したりすることで監視することができます。
6.3 キャッシュストレージのサイズの最適化
キャッシュストレージのサイズは、Webサイトのコンテンツ量とアクセスパターンに基づいて最適化する必要があります。サイズが小さすぎると、頻繁にキャッシュミスが発生し、パフォーマンスが低下します。サイズが大きすぎると、ディスクスペースを浪費し、キャッシュの検索速度が低下する可能性があります。
6.4 キャッシュキーの最適化
キャッシュキーは、キャッシュされたコンテンツを識別するために使用されます。キャッシュキーが適切でない場合、不要なキャッシュミスが発生したり、異なるコンテンツが誤って同じキーでキャッシュされたりする可能性があります。キャッシュキーは、Webサイトのコンテンツの種類とアクセスパターンに基づいて最適化する必要があります。
6.5 キャッシュのウォームアップ
キャッシュのウォームアップとは、Webサイトの公開後やキャッシュのクリア後に、キャッシュを事前に埋めておく作業です。これにより、Webサイトへの最初のアクセス時にキャッシュミスが発生するのを防ぎ、スムーズなユーザーエクスペリエンスを提供することができます。キャッシュのウォームアップは、クローラーを使用したり、特定のURLに対してリクエストを送信したりすることで行うことができます。
7. キャッシュ設定のトラブルシューティング
キャッシュ設定が期待どおりに動作しない場合は、以下の点を確認してください。
7.1 キャッシュが有効にならない原因と対策
proxy_cache
ディレクティブが有効になっているか確認する。proxy_cache_path
ディレクティブが正しく設定されているか確認する。- キャッシュディレクトリがNginxユーザーによって書き込み可能になっているか確認する。
- バックエンドサーバーが
Cache-Control: no-cache
などのキャッシュ制御ヘッダーを送信していないか確認する。 proxy_cache_bypass
ディレクティブまたはproxy_no_cache
ディレクティブが意図せずにキャッシュをバイパスしていないか確認する。
7.2 キャッシュキーが適切でない場合の対処法
proxy_cache_key
ディレクティブを修正して、より適切なキャッシュキーを定義する。- クエリパラメータやクッキーなど、キャッシュキーに含めるべき要素が不足していないか確認する。
- キャッシュキーが長すぎる場合、ハッシュ関数を使用して短縮することを検討する。
7.3 キャッシュストレージの容量不足の解消
proxy_cache_path
ディレクティブのmax_size
パラメータを増やして、キャッシュストレージの最大サイズを増やす。- 不要なコンテンツをキャッシュから削除する。
- キャッシュストレージをより大きなディスクに移動する。
7.4 セキュリティ上の考慮事項
- キャッシュpurge機能を有効にする場合は、アクセスを制限して、不正なキャッシュ削除を防ぐ。
- 機密情報を含むコンテンツをキャッシュしないように注意する。
- キャッシュされたコンテンツが最新の状態であることを確認するために、定期的にキャッシュをクリアする。
8. まとめ:Nginxキャッシュ設定のベストプラクティス
Nginxのキャッシュ設定は、Webサイトのパフォーマンスを大幅に向上させるための強力な手段です。以下に、Nginxキャッシュ設定のベストプラクティスをまとめます。
- 静的コンテンツには、長期間のキャッシュを設定する。
- 動的コンテンツには、適切なキャッシュ戦略を実装する。
- キャッシュ制御ヘッダーを適切に設定する。
- キャッシュパフォーマンスを監視し、チューニングする。
- セキュリティ上の考慮事項を忘れずに。
本記事で解説したテクニックを参考に、Webサイトの要件に合わせた最適なキャッシュ設定を行い、高速で快適なユーザーエクスペリエンスを実現してください。