apacheでmod_proxyとmod_cacheを使ってリバースプロキシでキャッシュを行う
こんにちは,mbuchiです.
先日私的な用件で,リバースプロキシに動的コンテンツも含めてキャッシュさせる方法を探しました.
特にキャッシュ周りの情報が少なくて苦戦したので,ここにまとめておきます.
構築するもの
動的コンテンツもキャッシュするリバースプロキシ
環境
- Ubuntu 14.04
- Apache 2.4.7 (apt-getで入れたもの)
使うもの
- mod_proxy
- mod_cache
必要な手順
1. mod_proxyの設定
こちらのサイトが分かりやすかったです.
ここでは省略します.
2. mod_cacheの設定
/etc/apache2/mods-available/cache_disk.conf
に追記
# アンコメント CacheEnable disk / # 15行目 # 追記 CacheIgnoreCacheControl On # キャッシュされているコンテンツを返さないようにクライアントから リクエストされても無視する CacheStorePrivate On # private と指定されているレスポンスのキャッシュを試みる。 CacheIgnoreNoLastMod On # 応答にLast Modified が無くてもキャッシュする CacheStoreNoStore On # no-store と指定されているレスポンスのキャッシュを試みる。 CacheDefaultExpire 3600 # キャッシュの有効期限(秒) CacheLock on # Thundering Herd 問題対策
Thundering Herd問題については以下のサイトで知りました.
Kazuho@Cybozu Labs: キャッシュシステムの Thundering Herd 問題
例えば同一URLへのアクセスがほぼ同時に2件来た場合,キャッシュは無い状態なので,2件ともオリジナルのサーバへアクセスするという問題への対応をしてくれるオプションという理解です.
注意点
CacheStoreNoStore について
RFC 2616 に記載されているように no-store ディレクティブは、 "不注意による機密情報の漏洩や残留 (バックアップテープ等) を防ぐ" 目的で使われますが、このオプションを有効にすると、 機密情報を保持することになってしまいます。 ですので、ここで警告しておきます。mod_cache - Apache HTTP サーバより
3. テストしてみる
1. クライアントから2回アクセスする
$ curl http://proxy_server/index.cgi; sleep 1; curl http://proxy_server/index.cgi
2. リバースプロキシから飛ばされるオリジナルのサーバのログを確認
/var/log/apache2/access.log
を確認します.
192.168.0.3,-,-,[01/Jun/2016:16:24:01 +0900],"GET /index.cgi HTTP/1.1",200,13779,0,17406
プロキシへのアクセスは2回行われていますが,オリジナルのサーバへは1回しかアクセスが来ていません. キャッシュできていることが確認できました.
4. さらにテストしてみる
並列でリクエスト送ってみる
先程は1つずつでしたが,今度はリクエストを並列して送ってみます.
GNU parallel
を使います.
GNU parallel
自体の説明は,以下のサイトがわかりやすかったです.
クライアント側
$ parallel curl ::: http://proxy_server/index.cgi http://proxy_server/index.cgi
実行される内容としては,curl http://proxy_server/index.cgi
が2つ並列に走ります.
オリジナルのサーバのログ
192.168.0.3,-,-,[01/Jun/2016:17:07:30 +0900],"GET /index.cgi HTTP/1.1",200,13779,0,17646
1回だけアクセスされています.
CacheLockをoffにして並列でアクセスする
2.で設定したキャッシュサーバのcache_disk.conf
のCacheLock On
をOff
にして実験してみます.
ちなみにデフォルト値はOff
なので,この行を削除でも可です.
クライアント側
$ parallel curl ::: http://proxy_server/index.cgi http://proxy_server/index.cgi
オリジナルのサーバのログ
192.168.0.3,-,-,[01/Jun/2016:16:57:17 +0900],"GET /index.cgi HTTP/1.1",200,13779,0,16586 192.168.0.3,-,-,[01/Jun/2016:16:57:17 +0900],"GET /index.cgi HTTP/1.1",200,13779,0,12987
先ほどとは違い,アクセスが2回とも来ています.
まとめ
動的コンテンツもキャッシュするリバースプロキシの構築方法でした.
天気予報,商品の在庫数を表示するようなECサイト,掲示板(数秒ごとにキャッシュ更新すれば可?)など,極端にリアルタイム性を求められないサイトでお使いいただけるのではないでしょうか.
Thundering Herd問題は聞いたことがなかったので,今回いろいろと調べたなかで,特に良い勉強になりました.
上で貼ったもの以外に参考にさせていただいたページ
Apache2.2の mod_proxyと mod_cacheであらゆるものをキャッシュする - ブログ - ワルブリックス株式会社