Cache::Memcached(::Fast)を使う上でベストプラクティスをまとめたモジュールを書いてみた。名前は、Cache::Memcached::IronPlate。おのみち焼き。
githubにあります。ドキュメントが日本語だけです: https://github.com/kazeburo/Cache-Memcached-IronPlate
つかいかた
use Cache::Memcached::IronPlate;
use Cache::Memcached::Fast;
my $memd = Cache::Memcached::IronPlate->new(
cache => Cache::Memcached::Fast->new(...).
);
$memd->get
$memd->get_multi
$memd->set
$memd->add
$memd->replace
$memd->append
$memd->prepend
$memd->incr
$memd->counter
$memd->decr
$memd->delete
インスタンス作成時にCache::Memcache(::Fast)などのオブジェクトを渡します。ほかにもいくつかオプションがありますが、機能の説明をしながら紹介します。
自動キーフィルタ
memcached injectionを防ぐためマルチバイトや制御コードがkeyに含まれている場合、それらをURI Escapeして利用します
$memd->get("key hoge\n") => get("key%20hoge%0A")
キーが250文字以上の場合は、Digest::MD5でhash値を作り利用します。またオブジェクトの場合はシリアライズしてkeyとして用います。
キャッシュ分散
設定情報など、比較的変化が少なく多くのページで読まれるキャッシュは複製して多数のサーバに分散することで負荷の集中、memcachedサーバ障害時の影響を小さくすることができます。分散するkeyには「:dist」を付加します
$memd->set("mypref:dist")
内部的には、:dist:${num} などと1から複製する数の値をkeyに追加して、memcachedクライアントで分散されるようにします。分散される個数はデフォルト20です。変更するにはインスタンス作成時に distribution_num を設定します
my $memd = Cache::Memcached::IronPlate->new(
distribution_num => 30
);
このキャッシュ分散の機能は、setとget、get_multi、deleteにのみ有効です。他のメソッドに対して:distが付いたキーを渡すと例外となります
キャッシュ複製
Cache::Memcached::Fastのようにrehashしないクライアントでは、特定のmemcachedサーバに接続ができない状態になると特定のキーの保存ができす、セッション管理に用いていた場合では、特定のユーザのみがログインができないなどの影響がおこります。 keyの名前に「:dup」を付与すると、キャッシュ分散と同じように自動的にキャッシュを複製します。
内部的にもキャッシュ分散と同じように、:dup:${num} とキーに数値を追加して、複製、分散されるようにします。キャッシュ分散と異なるのは、キャッシュ取得時に複製したデータを全て取得し、取得できたデータが過半数に達した場合のみ、データを返す事です。
${num}はデフォルト3です。インスタンス作成時に duplication_num を設定します
my $memd = Cache::Memcached::IronPlate->new(
duplication_num => 30
);
キャッシュ複製では大きなキャッシュデータに利用した場合、通信量に影響がでるので注意してください。この機能も、setとget、get_multi、deleteにのみ有効です。他のメソッドに対して:dupが付いたキーを渡すと例外となります
カウンター
memcached の increment は指定した値がない場合では動作しません。counterは自動で初期値を保存します。
get_multiの分割処理
get_mulitiに1,000個以上のkeyを渡した場合は、タイムアウトを防ぐため内部的に1000個ごとに分割して処理をします
以上のような機能が使えます。お試しくださいませ。