《PHP實(shí)戰(zhàn):PHP使用Memcache時(shí)模擬命名空間及緩存失效問題的解決》要點(diǎn):
本文介紹了PHP實(shí)戰(zhàn):PHP使用Memcache時(shí)模擬命名空間及緩存失效問題的解決,希望對您有用。如果有疑問,可以聯(lián)系我們。
相關(guān)主題:memcache擴(kuò)展 / 鍵值KeyValue存儲數(shù)據(jù)庫
緩存命名空間PHP教程
memcache本身不支持命名空間,但是我們可以利用 memcache本身的機(jī)制,來模擬命名空間.比如:你要清除一組數(shù)據(jù),就需要用到命名空間,來看這樣一個(gè)例子,說明寫在了注釋里:PHP教程
class Action { public function index() { global $mc_wr; // 獲取命名空間 $ns_key = $mc_wr->get("foo_namespace_key"); // 如果命名空間不存在,則設(shè)置一個(gè) if($ns_key===false) $mc_wr->set("foo_namespace_key",time()); $otherParms = 'select * from user LIMIT 1'; // 根據(jù)命名空間生成唯一的key $my_key = "foo_".$ns_key.'_'.md5($otherParms); // 獲取當(dāng)前key下的緩存 $val = $mc_wr->get($my_key); if (!$val) { $value = 'wangdekang_'.time(); // 緩存不存在則設(shè)置緩存 600秒, 0為隨機(jī)失效時(shí)間, 為失效時(shí)間添加隨機(jī)秒數(shù),防止瞬間所有緩存同時(shí)失效 $mc_wr->set($my_key,$value,600, 0); } echo $val; } public function clear_ns() { global $mc_wr; // 更新命名空間值,讓當(dāng)前命名空間的所有值失效, memcache自身的緩存失效機(jī)制,當(dāng)緩存不在被訪問,會通過LRU失效機(jī)制 $mc_wr->set('foo_namespace_key', time()); } }
memcache緩存失效問題
在大并發(fā)的場合,當(dāng)cache失效時(shí),大量并發(fā)同時(shí)取不到cache,會同一瞬間去訪問db并回設(shè)cache,可能會給系統(tǒng)帶來潛在的超負(fù)荷風(fēng)險(xiǎn).
解決方法:PHP教程
方法一
在load db之前先add一個(gè)mutex key, mutex key add成功之后再去做加載db, 如果add失敗則sleep之后重試讀取原cache數(shù)據(jù).為了防止死鎖,mutex key也需要設(shè)置過期時(shí)間.偽代碼如下
PHP教程
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內(nèi)部設(shè)置1個(gè)超時(shí)值(timeout1), timeout1比實(shí)際的memcache
timeout(timeout2)小.當(dāng)從cache讀取到timeout1發(fā)現(xiàn)它已經(jīng)過期時(shí)候,馬上延長timeout1并重新設(shè)置到cache.然
后再從數(shù)據(jù)庫加載數(shù)據(jù)并設(shè)置到cache中.偽代碼如下PHP教程
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(); } } }
《PHP實(shí)戰(zhàn):PHP使用Memcache時(shí)模擬命名空間及緩存失效問題的解決》是否對您有啟發(fā),歡迎查看更多與《PHP實(shí)戰(zhàn):PHP使用Memcache時(shí)模擬命名空間及緩存失效問題的解決》相關(guān)教程,學(xué)精學(xué)透。維易PHP學(xué)院為您提供精彩教程。
轉(zhuǎn)載請注明本頁網(wǎng)址:
http://www.fzlkiss.com/jiaocheng/7500.html