2013-08-26 109 views
0

我有一個mysql數據庫和一個緩存(memcached)在它前面。阻止mysql數據庫查詢

基本上我不想讓任何請求去我的數據庫。相反,所有的請求都應該由緩存來回答。

但是,緩存每隔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); 
} 
+0

好像Ÿ歐是想禁用緩存刷新,但你不要似乎明白了一個cahce是如何工作的?它必須能夠訪問數據庫刷新 – gbtimmon

+0

你爲什麼一次刷新整個緩存?爲什麼不給這些項目10分鐘TTL,使得TTL之後的請求命中數據庫,以每個項目爲基礎重新填充緩存,而不是立即整個緩存? –

+0

即使在每件商品的基礎上,如果商品被沖洗,然後立即被幾百人請求,他們現在都會去DB –

回答

0

以下是完全的理論,因爲我不知道PHP。但它使用C接口,因此我認爲它也應該在Web服務中工作。

有兩個時間常數,你需要仔細選擇它們。一個是你願意等待緩存被填充的時間。我建議大約有一半的時間需要重新填充,但如果重新填充時間(數據庫查找)較高,則可能會更少。輪詢memcached不會花費太多,但你不希望每三微秒做一次,我不這麼認爲。另一個是第一行中特殊標記的到期。我將它設置爲1(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)