やや大袈裟な名前ですが「memcachedにおけるキャッシュシステムの Thundering Herd 問題への対策案」とか「キャッシュシステムの Thundering Herd 問題への対策案。その2 排他制御」で書いていたコードをモジュールにした

github: https://github.com/kazeburo/Cache-Isolator

機能としては、平行動作数を制御できるget_or_setと、一定の確率で少し早く有効期限が切れるキャッシュの保存、取得、削除あたりがあげられます

使い方ですが、まず、get_or_setの例。

my $isolator = Cache::Isolator->new(
    cache => Cache::Memcached::Fast->new(...),
    concurrency => 4, # get_or_setのcallbackの最大平行動作数。デフォルト1
    interval => 0.01, #lockを確認するinterval
    timeout => 10, #lockする最長時間
    trial => 0, #lockを試行する最大回数
);

my $key   = 'query:XXXXXX';
# get_or_set( key, callback, expires)
$isolator->get_or_set(
    $key, 
    sub {
        get_from_db($key);
    },
    3600
);

次に早期有効期限の例。get/set/deleteは普通とかわらずに使えます。

my $isolator = Cache::Isolator->new(
    cache => Cache::Memcached::Fast->new(...),
    early_expires_ratio => 10, #1/10の確率で早くexpires
    expires_before => 10, # expiresする秒数
);

$isolator->get($key);
$isolator->set($key, $value, $expires);
$isolator->delete($key);

early_expiresでは、set時に2つキャッシュを作成し、片方のexpiresをexpires_beforeで指定した秒数早くして保存します。getするときは、early_expires_raitoの確率で早くexpiresするキャッシュを引き、通常のキャッシュよりも早い期限切れを表現しています。

この2つの機能は同時に使うことができるので、early_expiresをしつつ、get_or_setの平行動作数をしぼったりもできます。うまく組み合わせるとThundering Herd問題を回避できると思われます。

このモジュールではないけど、既に某blogサービスの一部の重いクエリに対してこの仕組みが導入されていたりします。かなりDBの負荷削減に効果ありました

このブログ記事について

このページは、Masahiro Naganoが2011年2月25日 00:00に書いたブログ記事です。

ひとつ前のブログ記事は「HTTPコンテンツ圧縮とPlack」です。

次のブログ記事は「Cache::Memcached::鉄板(てっぱん)」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

ウェブページ

OpenID対応しています OpenIDについて
Powered by Movable Type 4.27-ja