0

我前面有一个 mysql 数据库和一个缓存(memcached)。

基本上我不想让任何请求进入我的数据库。相反,所有请求都应由缓存响应。

但是,缓存每 10 分钟刷新一次,然后请求转到我的数据库,直到缓存更新为最近的数据。但这可能会导致一段时间的流量高峰!

如何阻止请求或只让其中一个请求进入我的数据库,直到缓存再次更新?

$get_result = $memcache->get('key'); //retrieve memcached data if possible
if($get_result){
    // Show the memcached result
}else {
   // Make request to the database 
   ...
   // and re-set the cache
   $memcache->set('key', $get_result, false, 600); 
}
4

1 回答 1

0

以下内容完全是理论上的,因为我不懂 PHP。但它使用 C 接口工作,所以我想它也应该在 Web 服务中工作。

有两个时间常数,您需要仔细选择它们。一是您愿意等待缓存被填充的时间。我建议您预计重新填充所花费的时间大约为一半,尽管如果重新填充时间(数据库查找)很长,它可能会更少。轮询 memcached 的成本并不高,但我不认为你不想每三微秒进行一次。另一个是第一行中特殊令牌的到期。我将其设置为 1(一秒),因为这是可能的最小值,但不应小于预期的重新填充时间。当然,预期的再填充时间通常会少于一秒。

注意:我使用了 memcached 接口,它不需要在 add/set 上使用 flags 参数。我相信它使用更新的 C 库。

// This string must never be produced from the database.
// Also, the empty string must never be possible.
$WAIT_FOR_IT = '**WAIT**'

do {
   // The WAIT special value must expire quickly; otherwise, a failed
   // task could hang all other requesters for the same key.
   if ($memcache->add('key', $WAIT_FOR_IT, 1)){
      $get_result = db_lookup('key');
      $memcache->set('key', $get_result, 600);
   } else {
      $get_result = $memcache->get('key')
      if ($get_result == $WAIT_FOR_IT){
         // We get here if someone else is supposedly working on the value.
         // Don't wait very long.
         usleep(5000)
         $get_result = FALSE
      }
   }
} while (!$get_result)
于 2013-08-27T01:26:09.553 回答