Bulknews::Subtech RSSフィード

2006/12/16 (土)

Why storing session on memcached? 19:14  Why storing session on memcached? - Bulknews::Subtech を含むブックマーク はてなブックマーク -  Why storing session on memcached? - Bulknews::Subtech

http://d.hatena.ne.jp/tokuhirom/20061216/1166231736

memcached の開発元でもある Six Apart ですが、Vox/LJ ではセッションを memcached にいれてはいません。理由は簡単で memcached は比較的小さなデータを格納し、アプリケーションサーバ群で共有するのに適した設計になっているからで、memcached のデータがとべばセッションが消えるというのもアプリケーションによっては致命的になりえるから。

memcached に限らずキャッシュと名のつくものは、あってもなくても動くような役割でないといけないと思う。

http://www.jsw4.net/info/listserv_archives/mod_perl/04-wk37/msg00055.html で Perrin Harkins が言っているんだけど、

I wouldn't recommend using memcached for storing sessions. Memcached is explicitly unreliable storage. It is built with the premise that you won't put anything into it that you care about losing. If it gets full, it will simply drop data from storage. The mechanism for failover across multiple machines also counts on being able to lose all the data from one machine without it being a big deal.


Memcached would be better suited to acting as a write-through cache for session data that you store in a database.

データベースに書き込む際に memcached に同時に書き込み、読み込み時には memcached -> データベースと fallback する (= Write-through Cache)、というのであれば、いい使い方だとはおもいますが、memcached をメインのストレージにするというアイデアには懐疑的です。

以下は個別項目に対して。

> MySQL でセッションの管理をすると、複数サーバにふりわける仕組みがない(つくればいーけど)

Data::ObjectDriver のパーティション機能でユーザごとにセッションを割り振っています。

> MySQL 使ってるとテーブルロックがかかりまくってサイト全体が刺さる危険性がある

InnoDB を使いましょう。

> MySQL 使ってると、セッションデータを定期的に消してやらなきゃいけないけど DELETE FROM sessions WHERE timestamp >= '2006-12-01 00:00:00'; とかはすごく重かったりして、ここでまた刺さる

定期的に消すのではなくてセッションの復元時に expires をチェックするようにしている。。(未ログインユーザとかの不要セッションでごみがたまる問題はあるかな)

> memcached なら、サーバいくつか置いとけば、フェイルオーバになる

書き込みのときにフェイルオーバすることはできるけど、すでに書いてしまったデータを持ってるノードが落ちても、とりだせはしない。

http://www.danga.com/memcached/ にあるように、memcached はキーのハッシュ値をとって Memcached サーバの台数で modulo をとって割り振るだけ。増やしたから書き込みも Spread するというわけではない。つまり memcached のサーバを増やしてアプリを再起動したら、まず cache warming をしないとキャッシュヒット率が大幅に下がる可能性がある。

> mysql でアプリケーション用の DB にセッションテーブルいれちゃうと、無駄にデカいテーブルがレプられてウザい

テーブル名でレプリケーションを抑制する設定があったような。まあせっかくデータベースにいれるならレプリケーションさせないと意味ないかとは思うけど。


というわけで、「データベース自体をパーティショニングしてスケールさせる必要・需要がなく、いつユーザのセッションがとんでも問題なく、履歴をとっておく必要もないアプリケーションで、メモリを比較的大量につんだマシンをたくさん用意させられる環境」で memcached を使うのはいいと思います。また、「Webのセッションには永続を期待するデータをいれるべきでない=いつ消えても問題ないデータをいれるべき」という設計方針もあるだろうし、それ自体は個人的によいポリシーだともおもうので、それがうまく合致するなら問題がないともいえますね。ただ memcached サーバを追加したらセッションが消えてログインしなおし、というのはやはりなんとなく気持ちがよくない。

データベース(MySQL)を使用していてパフォーマンスに問題が、というのであれば Write-thru cache を実装してみると面白いかも。ちなみに Data::ObjectDriver の Cache はデフォルトで Write-through するようになってます。