PHP使用Memcache時(shí)模擬命名空間及緩存失效問(wèn)題的解決
緩存命名空間
memcache本身不支持命名空間,但是我們可以利用 memcache本身的機(jī)制,來(lái)模擬命名空間。比如:你要清除一組數(shù)據(jù),就需要用到命名空間,來(lái)看這樣一個(gè)例子,說(shuō)明寫(xiě)在了注釋里:
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)緩存不在被訪問(wèn),會(huì)通過(guò)LRU失效機(jī)制 $mc_wr->set('foo_namespace_key', time()); } }
memcache緩存失效問(wèn)題
在大并發(fā)的場(chǎng)合,當(dāng)cache失效時(shí),大量并發(fā)同時(shí)取不到cache,會(huì)同一瞬間去訪問(wèn)db并回設(shè)cache,可能會(huì)給系統(tǒng)帶來(lái)潛在的超負(fù)荷風(fēng)險(xiǎn)。
解決方法:
方法一
在load db之前先add一個(gè)mutex key, mutex key add成功之后再去做加載db, 如果add失敗則sleep之后重試讀取原cache數(shù)據(jù)。為了防止死鎖,mutex key也需要設(shè)置過(guò)期時(shí)間。偽代碼如下
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)過(guò)期時(shí)候,馬上延長(zhǎng)timeout1并重新設(shè)置到cache。然
后再?gòu)臄?shù)據(jù)庫(kù)加載數(shù)據(jù)并設(shè)置到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環(huán)境下安裝配置MemCache的全過(guò)程解析
- PHP保存session到memcache服務(wù)器的方法
- 在php中設(shè)置session用memcache來(lái)存儲(chǔ)的方法總結(jié)
- PHP擴(kuò)展Memcache分布式部署方案
- PHP環(huán)境中Memcache的安裝和使用
- windows下安裝php5.2.*,php5.3.*,php5.4.*版本的memcache擴(kuò)展
- PHP實(shí)現(xiàn)的memcache環(huán)形隊(duì)列類實(shí)例
- php中memcache 基本操作實(shí)例
- 在win系統(tǒng)安裝配置 Memcached for PHP 5.3 圖文教程
- php模塊memcache和memcached區(qū)別分析
相關(guān)文章
TP5框架使用QueryList采集框架爬小說(shuō)操作示例
這篇文章主要介紹了TP5框架使用QueryList采集框架爬小說(shuō)操作,結(jié)合實(shí)例形式分析了TP5結(jié)合QueryList采集框架爬17k小說(shuō)的相關(guān)原理、步驟與實(shí)現(xiàn)技巧,需要的朋友可以參考下2020-03-03php上傳文件,創(chuàng)建遞歸目錄的實(shí)例代碼
這篇文章介紹了php上傳文件,創(chuàng)建遞歸目錄的實(shí)例代碼,有需要的朋友可以參考一下2013-10-10PHP結(jié)合Jquery和ajax實(shí)現(xiàn)瀑布流特效
php+ajax+jquery實(shí)現(xiàn)無(wú)限瀑布流布局 寬度是一定的高度不定的瀑布流布局 也可以說(shuō)是無(wú)縫拼圖 當(dāng)瀏覽器滾動(dòng)到底部時(shí)候自動(dòng)加載圖片,非常的實(shí)用,需要的小伙伴可以參考下。2016-01-01php微信公眾號(hào)開(kāi)發(fā)之答題連闖三關(guān)
這篇文章主要為大家詳細(xì)介紹了php微信公眾號(hào)開(kāi)發(fā)之答題連闖三關(guān),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-10-10學(xué)習(xí)PHP Cookie處理函數(shù)
這篇文章主要為大家詳細(xì)介紹了PHP Cookie處理函數(shù)的使用方法,感興趣的小伙伴們可以參考一下2016-08-08PHP 雙鏈表(SplDoublyLinkedList)簡(jiǎn)介和使用實(shí)例
這篇文章主要介紹了PHP 雙鏈表(SplDoublyLinkedList)簡(jiǎn)介和使用實(shí)例的相關(guān)資料,需要的朋友可以參考下2015-05-05Laravel實(shí)現(xiàn)登錄跳轉(zhuǎn)功能
網(wǎng)站管理員登錄成功后跳轉(zhuǎn)到網(wǎng)站后臺(tái),vip用戶登錄成功后跳轉(zhuǎn)到vip頁(yè)面,跳轉(zhuǎn)功能怎么實(shí)現(xiàn)的呢,下面小編給大家?guī)?lái)了Laravel實(shí)現(xiàn)登錄跳轉(zhuǎn)功能,需要的朋友可以參考下2021-08-08PHP封裝請(qǐng)求類實(shí)例分析【基于Yii框架】
這篇文章主要介紹了PHP封裝請(qǐng)求類,結(jié)合實(shí)例形式分析了基于Yii框架的curl封裝請(qǐng)求處理的相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2019-10-10