キャッシュしたい非常に高価な計算があります。したがって、次のようなことを行います。
my $result = $cache->get( $key );
unless ($result) {
$result = calculate( $key );
$cache->set( $key, $result, '10 minutes' );
}
return $result;
ここでcalculate($key)
、結果をキャッシュに保存する前に、他のいくつかの要求が入ってきて実行を開始しcalculate($key)
、多くのプロセスがすべて同じことを計算するため、システム パフォーマンスが低下します。
アイデア: 値が計算されていることを示すフラグをキャッシュに入れましょう。他のリクエストはその 1 つの計算が完了するのを待つだけなので、すべてのリクエストがそれを使用します。何かのようなもの:
my $result = $cache->get( $key );
if ($result) {
while ($result =~ /Wait, \d+ is running calculate../) {
sleep 0.5;
$result = $cache->get( $key );
}
} else {
$cache->set( $key, "Wait, $$ is running calculate()", '10 minutes' );
$result = calculate( $key );
$cache->set( $key, $result, '10 minutes' );
}
return $result;
これにより、まったく新しいワームの缶が開かれます。$$ がキャッシュを設定する前に死亡した場合はどうなりますか。もしも、もし...それらはすべて解決可能ですが、CPANにはこれを行うものは何もないため(CPANにはすべてのものがあります)、私は疑問に思い始めます:
より良いアプローチはありますか?Cache
PerlやCache::Cache
クラスがこのようなメカニズムを提供していないなど、特定の理由はありますか? 代わりに使用できる実証済みのパターンはありますか?
理想的なのは、すでにスクイーズまたは eureka の瞬間にある debian パッケージを含む CPAN モジュールです。ここで、自分のやり方のエラーが表示されます... :-)
編集:これがキャッシュスタンピードと呼ばれることを知り、質問のタイトルを更新しました。