程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> PHP使用Memcache時模擬命名空間及緩存失效問題的解決,memcache命名空間

PHP使用Memcache時模擬命名空間及緩存失效問題的解決,memcache命名空間

編輯:關於PHP編程

PHP使用Memcache時模擬命名空間及緩存失效問題的解決,memcache命名空間


緩存命名空間

memcache本身不支持命名空間,但是我們可以利用 memcache本身的機制,來模擬命名空間。比如:你要清除一組數據,就需要用到命名空間,來看這樣一個例子,說明寫在了注釋裡:

class Action
{
  
 public function index()
 {
  global $mc_wr;
   
  // 獲取命名空間
  $ns_key = $mc_wr->get("foo_namespace_key");
  // 如果命名空間不存在,則設置一個
  if($ns_key===false) $mc_wr->set("foo_namespace_key",time());
   
  $otherParms = 'select * from user LIMIT 1';
  // 根據命名空間生成唯一的key
  $my_key = "foo_".$ns_key.'_'.md5($otherParms);
   
  // 獲取當前key下的緩存
  $val = $mc_wr->get($my_key);
  if (!$val) {
   $value = 'wangdekang_'.time();
   // 緩存不存在則設置緩存 600秒, 0為隨機失效時間, 為失效時間添加隨機秒數,防止瞬間所有緩存同時失效
   $mc_wr->set($my_key,$value,600, 0);
  }
   
  echo $val;
 }
  
 public function clear_ns()
 {
  global $mc_wr;
  // 更新命名空間值,讓當前命名空間的所有值失效, memcache自身的緩存失效機制,當緩存不在被訪問,會通過LRU失效機制
  $mc_wr->set('foo_namespace_key', time());
 }
}

memcache緩存失效問題
在大並發的場合,當cache失效時,大量並發同時取不到cache,會同一瞬間去訪問db並回設cache,可能會給系統帶來潛在的超負荷風險。
解決方法:

方法一
在load db之前先add一個mutex key, mutex key add成功之後再去做加載db, 如果add失敗則sleep之後重試讀取原cache數據。為了防止死鎖,mutex key也需要設置過期時間。偽代碼如下

if (memcache.get(key) == null) {
 // 3 min timeout to avoid mutex holder crash
 if (memcache.add(key_mutex, 3 * 60 * 1000) == true) {
  value = db.get(key);
  memcache.set(key, value);
  memcache.delete(key_mutex);
 } else {
  sleep(50);
  retry();
 }
} 

方法二
在value內部設置1個超時值(timeout1), timeout1比實際的memcache
timeout(timeout2)小。當從cache讀取到timeout1發現它已經過期時候,馬上延長timeout1並重新設置到cache。然
後再從數據庫加載數據並設置到cache中。偽代碼如下

v = memcache.get(key);
if (v == null) {
 if (memcache.add(key_mutex, 3 * 60 * 1000) == true) {
  value = db.get(key);
  memcache.set(key, value);
  memcache.delete(key_mutex);
 } else {
  sleep(50);
  retry();
 }
} else {
 if (v.timeout <= now()) {
  if (memcache.add(key_mutex, 3 * 60 * 1000) == true) {
   // extend the timeout for other threads
   v.timeout += 3 * 60 * 1000;
   memcache.set(key, v, KEY_TIMEOUT * 2);

   // load the latest value from db
   v = db.get(key);
   v.timeout = KEY_TIMEOUT;
   memcache.set(key, value, KEY_TIMEOUT * 2);
   memcache.delete(key_mutex);
  } else {
   sleep(50);
   retry();
  }
 }
}

您可能感興趣的文章:

  • 在Mac OS的PHP環境下安裝配置MemCache的全過程解析
  • PHP保存session到memcache服務器的方法
  • 在php中設置session用memcache來存儲的方法總結
  • PHP擴展Memcache分布式部署方案
  • PHP環境中Memcache的安裝和使用
  • windows下安裝php5.2.*,php5.3.*,php5.4.*版本的memcache擴展
  • PHP實現的memcache環形隊列類實例
  • php中memcache 基本操作實例
  • 在win系統安裝配置 Memcached for PHP 5.3 圖文教程
  • php模塊memcache和memcached區別分析

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved