取得系のキャッシュの制御ってめんどいな

  • 投稿日:
  • by
  • カテゴリ:

「無駄なリクエストを発行しない」だけなら簡単だけど。

取得系のキャッシュの目的は2つある気がします。

  • 外部サーバに迷惑をかけない
  • 閲覧者のストレス軽減

 

外部サーバに迷惑をかけない

file_get_contents()で他人様の外部サーバから情報をとってくるとします。RSSとかATOMですな。

ページの生成のたびに、RSSを取りにいくと、ブラウザの更新ボタン連打で、外部サーバにご迷惑をおかけすることになります。

しかも取得元は私のサーバー。

閲覧者が勝手にRSSをブラウザで開いて更新連打したら、そのユーザが取得元ですね。

CGIからRSSを取りにいくとうちのサーバが閲覧者の代行をするわけです。

なので、取りに行く頻度には気をつけないと、イカンというわけです。悪意のある閲覧者が更新連打しても、ガードするわけですな。

# あるいは毎秒10PVあるようなすごいサイトに成長したときに迷惑をかけちゃう^^

 

そのガードのために取得系にキャッシュを導入するとします。たとえばCache_Liteを使ってfile_get_contents()をラップしたりするわけですな。

 

閲覧者のストレス軽減

生成するページに10個のサイトから取ってきた情報を混ぜて表示するRSSリーダを作るとします。閲覧者からの要求1回につき、file_get_contents()を10回発行するわけですな。するとページの表示にかかる時間が長くなります。重いページのできあがりというわけです。重いといっても、外部サイトの応答を待ってるだけですから、大してCPU負荷が高いわけでもなく、RSSがばかでかくなければ帯域負荷も小さいでしょう。ただ時間がかかるわけです。しかも外部サーバの応答時間なんて、どうしようもないわけですから。

たぶん今風に対策するならAJAXで取得できたRSSを順に混ぜて表示していけばよいのだろうと思います。

#そして毎秒1ユーザ以上が訪問するような忙しいサイトなら、何も対処しなくても大丈夫だったりするのでしょうけど。

 

1個ずつのRSS取得にかかる時間は知れていて、そんな遠回りのことはしたくないので、以下のようにごまかしました。

Cache_Lite::get()がfalseを返した(つまりキャッシュが有効期限切れのときの)回数をカウントする

ある回数を越えていたら、Cache_Lite::get()の第3引数にTRUEを指定する

回数のカウントは要求ごとにおこないますからグローバルでもstaticでもなんでもいいんじゃないですかね。get()の第3引数は、マニュアルによると、

boolean$doNotTestCacheValidity

もし TRUE を指定した場合、キャッシュの正当性はテストされません。

とのことです。これはキャッシュが古いかどうかをチェックせずに返すということです。つまり古いままのキャッシュを強制的に用います。

 

これで以下のようにキャッシュの日付がぴったり揃うことはなくなるはずです。

-rw-r--r-- 1 www-data www-data 11321 2011-05-24 20:15 cache_c21f969b5f03d33d43e04f8f136e7682_2e07f3efdc42bd01d02a33f89f12a84e
-rw-r--r-- 1 www-data www-data 90624 2011-05-24 20:15 cache_c21f969b5f03d33d43e04f8f136e7682_372567a182e0a63d33565ddbe0aba22a
-rw-r--r-- 1 www-data www-data 45828 2011-05-24 20:15 cache_c21f969b5f03d33d43e04f8f136e7682_3b409bd76564add829d6eb93d5550f95
-rw-r--r-- 1 www-data www-data 70054 2011-05-24 20:15 cache_c21f969b5f03d33d43e04f8f136e7682_3e241c223ee119793be10cc2d6c6a687
-rw-r--r-- 1 www-data www-data 37177 2011-05-24 20:15 cache_c21f969b5f03d33d43e04f8f136e7682_43c9442162500123a6a9a22898108fae
-rw-r--r-- 1 www-data www-data 35729 2011-05-24 20:15 cache_c21f969b5f03d33d43e04f8f136e7682_4996fd4d4eb96e4b5d0a93e772f0583f
-rw-r--r-- 1 www-data www-data 42308 2011-05-24 20:15 cache_c21f969b5f03d33d43e04f8f136e7682_531cbbee9a498bfa47bb0e8d4f31b323
-rw-r--r-- 1 www-data www-data 53249 2011-05-24 20:15 cache_c21f969b5f03d33d43e04f8f136e7682_5e299fd70e127aa23f5e54f64a1ecec4
-rw-r--r-- 1 www-data www-data 18872 2011-05-24 20:15 cache_c21f969b5f03d33d43e04f8f136e7682_60c012b0170453a2ceed82f4ed8225c8
-rw-r--r-- 1 www-data www-data 81978 2011-05-24 20:15 cache_c21f969b5f03d33d43e04f8f136e7682_70cec775e8ec44984fe3705d2bcf3e29
-rw-r--r-- 1 www-data www-data 30327 2011-05-24 20:15 cache_c21f969b5f03d33d43e04f8f136e7682_776ba7285e8d2c0e0204552b09fd1b48
-rw-r--r-- 1 www-data www-data 29421 2011-05-24 20:15 cache_c21f969b5f03d33d43e04f8f136e7682_7ca1f44847f6083548ece076640b6aac
-rw-r--r-- 1 www-data www-data 35456 2011-05-24 20:15 cache_c21f969b5f03d33d43e04f8f136e7682_9c73620671be71e86a2cb3ce05643715
-rw-r--r-- 1 www-data www-data  5232 2011-05-24 20:15 cache_c21f969b5f03d33d43e04f8f136e7682_a0d84c0ac715ced1038284dcea5852f2
-rw-r--r-- 1 www-data www-data 34471 2011-05-24 20:15 cache_c21f969b5f03d33d43e04f8f136e7682_a9294f953ea98f7245450c56c4c5fe53

更新ボタンが連打されても、指定した数個のRSS取得のみが行われ、自前サーバの負荷はPHPの処理のみ。APCとか導入すりゃ改善できるんでしょ?

# もしかしてここに長々と書いたことはAPC導入で自動的にやってくれたりするの?

 

まぁきっとフレームワークとか使えば何も考えなくてもAJAXのかっちょええのがかけるんだろうな。