激遅なレスポンスなんだけど、dormandのmemcached記事。

dormando - Should you cache?

この中でキャッシュの使い方でよく見る間違った使い方を指摘している部分があって、ここがとても重要だと思うので書いておく

Where would you think to add caching to this system? I hope I've made it too obvious.
(システムのどこにキャッシュ機能を追加するべきだろう?)

At the query layer!
Use a database abstraction class and have it memcache resultset objects and...
No no no, that's a lie. I'm lying. Don't do that.
(DBクエリーのレイヤーだ!
DB抽象化クラスを使って、memcachedに結果のオブジェクトをキャッシュして・・・
いやいやいや、ごめん、今のは嘘。それはしないでくれ)


これ、自分を含めキャッシュを使い始めようとしている人たちがまず犯す間違いだと思うんだ。俺もやったよ。やっぱりやりたくなるよね。

Do it inside that $user object.
At the highest level possible. 
Take the whole object state and shovel it somewhere.
That object is its own biggest authority.
It knows when it's been updated, when it needs to load data, and when to write to the database.
It might've had to read from several tables or load dependent objects based on what you ask it to do.
(ユーザーオブジェクトのレベルでやるんだ。
最も外側のレベルでやるんだ。
オブジェクトの全体の状態をどかにキャッシュしてしまうんだ。
オブジェクト自身が自分の事を一番よくわかっている。
自分がいつ更新されたのか知っているし、いつデータが読み出されたのか知っているし、いつデータベースに書かれるべきなのか知っている。
ひとつのオブジェクトを作成するのに複数テーブルから読み込む必要があるかもしれないし、他のオ依存しているブジェクトを呼び出したりするかもしれないしね)


そういうことです。シンプルなシステムならいざ知らず、memcached を使うようなシステムではキャッシュ対象となるオブジェクトはDBのテーブル(もしくはそのオブジェクトの保存元)と1対1とは限らず、色々な依存関係が存在する。これをあまりmicro-managementすると、今度は逆にキャッシュ管理が複雑になりすぎてしまう。

例えば、$userオブジェクトが三つの部品でできていて、それぞれの部品をDBから読み込み、それぞれの部品のレイヤーでキャッシュしているとする。この場合$userオブジェクト本体はキャッシュする?したいよね。でもすると全体のオブジェクト$userがキャッシュされている間に部品Aがキャッシュから消されていたら?ん、どっちを取るの?いつ取るの?どうやってその状況をわかるの?とかとか。

それくらいだったら、細かい部品のキャッシュはとりあえず忘れて、$userというオブジェクト全体のレベルでキャッシュすればよいのだ。これなら、$user全体がキャッシュされているかどうかだけ。簡単だね!