ブログのキャッシュバックエンドの変更
今までは Cache::FileCache によるファイルシステムキャッシュにしていたけど、いくつか問題があって SQLite にかえた
ファイルシステムキャッシュで困っていたこと
- なんか遅い
- キャッシュ無効化の処理のためにキャッシュを生成元とキャッシュのキーをキャッシュ内に格納したいが、アトミックにやるうまい方法がなかった
SQLite 選択
Redis とかを立てるのが機能的には便利そうだけど、リソース的にあんまりサーバプロセスを増やしたくはないので、SQLite とした。
CREATE TABLE cache (
`cache_key` TEXT NOT NULL PRIMARY KEY,
`content` BLOB NOT NULL
);
CREATE TABLE cache_relation (
`id` INTEGER PRIMARY KEY,
`cache_key` TEXT NOT NULL,
`source_id` TEXT NOT NULL
);
CREATE INDEX cache_relation_index_cache_key ON cache_relation (`cache_key`);
CREATE INDEX cache_relation_index_source_id ON cache_relation (`source_id`);
CREATE TRIGGER on_cache_deleted AFTER DELETE ON cache BEGIN
DELETE FROM cache_relation WHERE cache_key = old.cache_key;
END;
CREATE TRIGGER on_cache_related_deleted AFTER DELETE ON cache_relation BEGIN
DELETE FROM cache WHERE cache_key = old.cache_key;
END; こんな感じでキャッシュ本体 (cacheテーブル)と、そのキャッシュを生成するのに使ったもののid(文字列)のリスト(cache_relationテーブル)を持って、お互いにトリガーで消しあうようにしておく。
こうしておくと、通常のキャッシュキーによる追加・削除だけではなくて、生成元が更新された時に関連するキャッシュをまとめて消せる。
なお、キャッシュ用のDBファイルは元データと分けた。というのも、元データのDBは毎日バックアップとしてGmailに送りつけているので、キャッシュを含めたくなかったから。
関連エントリー
- 関連画像を表示 libpuzzle の Perl binding である Image::Libpuzzle を使って関連画像を実装してみた。pHash や ...
- SQLite の WITHOUT ROWID の効果測定 SQLite で「PRIMARY KEY」を《真のプライマリキー》とするには | tech - 氾濫原 の続きです。 以下のような簡単なベン...
- TF-IDFとコサイン類似度による類似エントリー機能の実装 TF-IDFによる類似エントリー機能の実装をしてみました。ほぼSQLiteですませるような構成です。 やっていることの概要 エントリーのHT...
- リクエスト時の Cache-Control、max-age=0 と no-cache の違い ほとんどのブラウザで、通常リロードは Cache-Control: max-age=0、スーパーリロードで Cache-Control: n...
- RaspberryPi を家庭内 LAN の DNS キャッシュサーバーに LAN向けのDNSキャッシュサーバ 経緯としてRTX1200 の DNS 機能が TCP フォールバックに対応してないのでオフにした、という...