我們有一個非常昂貴的計算,我們想要緩存。所以我們做類似的東西:緩存和避免緩存踩踏 - 多個同時計算
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東西一切),我開始懷疑:
有沒有更好的方法嗎?是否有特殊原因,例如Perl的Cache
和Cache::Cache
類不提供這樣的機制?有沒有一個我可以使用的嘗試和真正的模式?
理想的情況是一個CPAN模塊與Debian軟件包已經在擠壓或靈光一現,在這裏我看到了我的方式錯誤... :-)
編輯:我後來瞭解到,這就是所謂的一個Cache stampede並更新了問題的標題。
[IPC :: ShareLite](http://search.cpan.org/~andya/IPC-ShareLite-0.17/lib/IPC/ShareLite.pm)提供的SysV OO接口共享內存。它與** Cache **類似,提供排他鎖。 – tuxuday
有[緩存踩踏 - 維基百科文章](https://en.wikipedia.org/wiki/Cache_stampede)和[Perl緩存討論>避免踩踏主題](https://groups.google.com/d/topic/perl-cache-discuss/jDdBQliwlP4/discussion)。 –
還有一個[djangosnippets:MintCache](https://www.djangosnippets.org/snippets/155/)策略。 –