我们想要缓存一个非常昂贵的计算。所以我们做类似的事情:
my $result = $cache->get( $key );
unless ($result) {
$result = calculate( $key );
$cache->set( $key, $result, '10 minutes' );
}
return $result;
现在,在calculate($key)
我们将结果存储到缓存中之前,其他几个请求进来了,它们也开始运行calculate($key)
,并且系统性能受到影响,因为许多进程都在计算相同的东西。
想法:让我们在缓存中放置一个正在计算一个值的标志,所以其他请求只是等待那个计算完成,所以他们都使用它。就像是:
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 中的所有东西都有),我开始想知道:
有更好的方法吗?是否有特殊原因,例如 PerlCache
和Cache::Cache
类不提供这样的机制?有没有我可以使用的经过验证的真实模式?
理想的情况是一个 CPAN 模块,它的 debian 包已经处于挤压状态或 eureka 时刻,在那里我看到了我的方式的错误...... :-)
编辑:我已经知道这被称为缓存踩踏,并更新了问题的标题。