2009-07-31 52 views
2

我剛開始用的memcache玩(d)昨晚,所以我還有很多要學習一下吧這是使用memcache的最佳方式嗎?

我想知道如果這個代碼是在做它在做什麼,或者我應該使用的好辦法其他memcache功能

我想顯示緩存版本的東西,如果緩存不存在,那麼我從mysql生成內容並將其設置爲緩存,然後在頁面上顯示mysql結果,然後下一頁加載它會檢查緩存,看看它在那裏,所以它會顯示它。

這段代碼似乎有訣竅,但有幾種不同的memcache函數應該使用其他的來實現這個功能嗎?

<?PHP 
$memcache= new Memcache(); 
$memcache->connect('127.0.0.1', 11211); 

$rows2= $memcache->get('therows1'); 
if($rows2 == ''){ 
    $myfriends = findfriend2(); // this function gets our array from mysql 
    $memcache->set('therows1', $myfriends, 0, 30); 
    echo '<pre>'; 
    print_r($myfriends); // print the mysql version 
    echo '</pre>'; 
}else{ 
    echo '<pre>'; 
    print_r($rows2); //print the cached version 
    echo '</pre>'; 
} 
?> 

這裏是發佈的鏈接提供的鎖定功能通過@crescentfresh

<?PHP 
// {{{ locked_mecache_update($memcache,$key,$updateFunction,$expiryTime,$waitUTime,$maxTries) 
/** 
* A function to do ensure only one thing can update a memcache at a time. 
* 
* Note that there are issues with the $expiryTime on memcache not being 
* fine enough, but this is the best I can do. The idea behind this form 
* of locking is that it takes advantage of the fact that 
* {@link memcache_add()}'s are atomic in nature. 
* 
* It would be possible to be a more interesting limiter (say that limits 
* updates to no more than 1/second) simply by storing a timestamp or 
* something of that nature with the lock key (currently stores "1") and 
* not deleitng the memcache entry. 
* 
* @package TGIFramework 
* @subpackage functions 
* @copyright 2009 terry chay 
* @author terry chay &lt;[email protected]&gt; 
* @param $memcache memcache the memcache object 
* @param $key string the key to do the update on 
* @param $updateFunction mixed the function to call that accepts the data 
* from memcache and modifies it (use pass by reference). 
* @param $expiryTime integer time in seconds to allow the key to last before 
* it will expire. This should only happen if the process dies during update. 
* Choose a number big enough so that $updateFunction will take much less 
* time to execute. 
* @param $waitUTime integer the amount of time in microseconds to wait before 
* checking for the lock to release 
* @param $maxTries integer maximum number of attempts before it gives up 
* on the locks. Note that if $maxTries is 0, then it will RickRoll forever 
* (never give up). The default number ensures that it will wait for three 
* full lock cycles to crash before it gives up also. 
* @return boolean success or failure 
*/ 
function locked_memcache_update($memcache, $key, $updateFunction, $expiryTime=3, $waitUtime=101, $maxTries=100000) 
{ 
    $lock = 'lock:'.$key; 

    // get the lock {{{ 
    if ($maxTries>0) { 
     for ($tries=0; $tries< $maxTries; ++$tries) { 
      if ($memcache->add($lock,1,0,$expiryTime)) { break; } 
      usleep($waitUtime); 
     } 
     if ($tries == $maxTries) { 
      // handle failure case (use exceptions and try-catch if you need to be nice) 
      trigger_error(sprintf('Lock failed for key: %s',$key), E_USER_NOTICE); 
      return false; 
     } 
    } else { 
     while (!$memcache->add($lock,1,0,$expiryTime)) { 
      usleep($waitUtime); 
     } 
    } 
    // }}} 
    // modify data in cache {{{ 
    $data = $memcache->get($key, $flag); 
    call_user_func($updateFunction, $data); // update data 
    $memcache->set($key, $data, $flag); 
    // }}} 
    // clear the lock 
    $memcache->delete($lock,0); 
    return true; 
} 
// }}} 
?> 

回答

11

夫婦的事情。

  1. 你應該在return value from get()使用===進行檢查false,不''。 PHP的類型轉換可以幫助您避免這樣做,但是恕我直言,最好是從緩存查找中明確您正在查找的值
  2. 您的競爭條件存在於空白檢查和您在哪裏set() db結果。從http://code.google.com/p/memcached/wiki/FAQ#Race_conditions_and_stale_data

    記住檢查 的memcached,獲取SQL和存儲 到的memcached的過程中,是不是原子的了!

    這種情況的症狀是,當密鑰過期並且(在一個高容量的站點上)一堆請求同時嘗試擊中db並緩存該值時,數據庫CPU中會出現尖峯。

    您可以使用add()而不是get來解決。看一個更具體的例子here

+0

感謝您的信息和鏈接,基本上在http://terrychay.com/blog/article/keeping-memcache-consistent.shtml,我沒有正確理解這個功能,它似乎在每一頁加載該函數被調用,設置一個新的鎖定緩存,一旦設置它使用get獲取緩存,它就更新/添加緩存,然後刪除鎖定緩存。我想那就是它在做什麼?直到獲取和添加/設置部分,如果您獲得緩存,那麼這對我來說很有意義,那麼爲什麼要設置/添加它呢?或者我不正確理解該頁面上的功能? – JasonDavis 2009-07-31 02:38:10