F.Ko-Jiの「一秒後は未来」

MagpieRSSのキャッシュ・ディレクトリをフィードのURLごとに分けてみる

フィード(RSS/Atom)を取得してキャッシュするときにどのような方法を取ろうかという話です。

とあるサイトはPHPで構築していて、フィードの取得には Magpie RSS を利用しています。MagpieRSSでは、

  • MAGPIE_CACHE_DIR にキャッシュ用のディレクトリパスを指定
  • MAGPIE_CACHE_AGE にキャッシュ秒数を指定

とすることで、自動的にフィードをキャッシュしてくれます。通常はこれで事足ります。

しかし、大量のフィード(現時点で約12,000フィード)をキャッシュしておく必要がある場合は、1個のディレクトリではキャッシュしきれません。

ということで、キャッシュするディレクトリをフィードごとに振り分けることにしました。(もちろんここで「データベースに保存する」という手段も取れますが。)

やったことは、

  • キャッシュ用のベースディレクトリの下に 00, 01, 02, …, f9, fa, fb, fc,fd, fe, ff という名前のディレクトリを準備。
  • MD5でフィードのURLのハッシュ値をとり、ハッシュ値の先頭2文字と一致するディレクトリにキャッシュを保存。

というもの。キャッシュ用のディレクトリのパスを取得する関数はたとえば次のように書けます。

protected function getMagpieCacheDir($feedUrl) {
    return SERVER_ROOT_DIR . 'magpie_cache/' . substr(md5($feedUrl), 0, 2);
}

また、 fetch_rss の引数にディレクトリを渡せるように、rss_fetch.inc を修正します。

88行目
+ function fetch_rss ($url, $magpieCacheDir = '') {
- function fetch_rss ( $url ) {
117行目
+ $cacheDir = ($magpieCacheDir == '') ? MAGPIE_CACHE_DIR : $magpieCacheDir;
+ $cache = new RSSCache( $cacheDir, MAGPIE_CACHE_AGE );
- $cache = new RSSCache( MAGPIE_CACHE_DIR, MAGPIE_CACHE_AGE );

こうしておくと、1個のディレクトリに5,000ファイルくらいキャッシュさせるとしても、128万ファイルをキャッシュできるようになります。

ちなみにページへのアクセスが少ない場合には、ユーザの訪問時にどうしてもキャッシュの有効期限が切れている可能性が高くなり、キャッシュがあまり意味のないものになってしまいます。

それを回避するために、データベースにフィードのURLをすべて登録しておいて、バックグラウンドでランダムにフィードを取得するcronをまわして、なるべくキャッシュが効くようにしています。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

著者について

fkoji

F.Ko-Ji

Webエンジニアやってます。最近は ドットインストール の開発がお仕事です。その傍ら、個人で Meity電車遅延なう梅酒.in#グラドル自画撮り部 の部室といったネットサービスを開発・運営してます。梅酒と草野球とリアル脱出ゲームが好きです。

» 詳しいプロフィールや運営サービスの一覧など