0

私は mysql データベースとキャッシュ (memcached) をその前に持っています。

基本的に、データベースへのリクエストを許可したくありません。代わりに、すべてのリクエストにキャッシュが応答する必要があります。

ただし、キャッシュは 10 分ごとにフラッシュされ、キャッシュが最新のデータで更新されるまで、リクエストがデータベースに送られます。ただし、これにより、しばらくの間トラフィックが急増する可能性があります!!

キャッシュが再び更新されるまで、リクエストを保留するか、そのうちの 1 つだけをデータベースに通すにはどうすればよいですか?

$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 サービスでも動作するはずです。

2 つの時定数があり、慎重に選択する必要があります。1 つは、キャッシュがいっぱいになるまで待機できる時間です。補充にかかる時間の約半分をお勧めしますが、補充時間 (データベース ルックアップ) が長い場合はさらに短くなる可能性があります。memcached のポーリングにはそれほどコストはかかりませんが、3 マイクロ秒ごとにポーリングする必要はないと思います。もう 1 つは、最初の行の特別なトークンの有効期限です。可能な最小値であるため、1 (1 秒) に設定しましたが、予想される補充時間よりも短くすべきではありません。もちろん、予想される補充時間は通常 1 秒未満です。

注: memcached インターフェースを使用しました。これは、追加/設定時に 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 に答える