memcache 缓存的批量删除方案(转)
memcache 默認(rèn)只支持使用delete(key)和 flush_all,這兩種方法都太極端了,不能滿足用戶的特定需求,如:批量刪除‘a(chǎn)aaaaaaa_’開(kāi)頭的所有緩存,這個(gè)時(shí)候該怎么辦?
1 getExtendStats 遍歷所有item,刪除指定的key(不推薦)
?網(wǎng)上有對(duì)應(yīng)的php代碼和perl程序,感興趣的可以看看,在本地測(cè)試時(shí)可以使用,但是在真是服務(wù)器上請(qǐng)不要使用。
?
2?memcache結(jié)合DB
方法:每次set緩存時(shí),將key值存入數(shù)據(jù)庫(kù),在要?jiǎng)h除緩存時(shí)查詢數(shù)據(jù)庫(kù),查詢出對(duì)應(yīng)的信息,在memcache中將其刪除
?缺點(diǎn):浪費(fèi)數(shù)據(jù)褲磁盤(pán)
?
3 memcache偽命名空間(推薦)
memcache默認(rèn)不提供命名空間,但可以設(shè)置一個(gè)全局變量,來(lái)模擬命名空間,代碼如下:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | ?php? ????//生成一個(gè)用來(lái)保存 namespace 的 key? ????$ns_key = $memcache->get("foo_namespace_key");? ??????? ????//如果 key 不存在,則創(chuàng)建,默認(rèn)使用當(dāng)前的時(shí)間戳作為標(biāo)識(shí) ????if($ns_key===false) $memcache->set("foo_namespace_key",time());? ??????? ????//根據(jù) namespace_key 生成真正的 key,確保是唯一的key值? ????$my_key = "foo_".$ns_key.$otherParms; ?????? ????//然后利用拼接的my_key值設(shè)置你需要緩存的各種數(shù)據(jù) ????$memcache->set($my_key,$value,false,expire); ????//或者key值獲得以前存儲(chǔ)的緩存 ????$memcaceh->get($my_key); ??????? ??????? ????//需要?jiǎng)h除整個(gè) namespace 里的對(duì)象的時(shí)候,如:更改數(shù)據(jù)庫(kù)或者刪除某些信息后 ????//將ns_key的值改變,則以后在訪問(wèn)緩存時(shí),以前時(shí)間的將永遠(yuǎn)不會(huì)別訪問(wèn)到,以此來(lái)實(shí)現(xiàn)批量刪除緩存 ?????$memcache->set("foo_namespace_key",time()); ?> |
?
memcache 命令操作
在定位緩存問(wèn)題測(cè)試時(shí),經(jīng)常需要對(duì)memcache的數(shù)據(jù)進(jìn)行一些操作,但是其本身沒(méi)有自帶的客戶端,所以只能通過(guò)telnet來(lái)進(jìn)行操作。
通過(guò)telnet連接memcache
telnet 127.0.0.1 11211?
memcache寫(xiě)入操作
telnet寫(xiě)入memcache命令格式
command name> key> flags> exptime> bytes>\r\n data block>\r\n參數(shù)詳解:
1. command name> 可以是”set”, “add”, “replace”
? ? ?set:key>不存在時(shí)添加,key>存在時(shí)覆蓋
? ? ?add:key>不存在時(shí)添加,key>存在時(shí)則會(huì)操作失敗
? ? ?replace:key>不存在時(shí)添加失敗,key>存在時(shí)替換數(shù)據(jù)
2. key> 保存數(shù)據(jù)的key
3. flags> 是一個(gè)16位的無(wú)符號(hào)的整數(shù)(以十進(jìn)制的方式表示)。
? ? ?該標(biāo)志將和需要存儲(chǔ)的數(shù)據(jù)一起存儲(chǔ),并在客戶端get數(shù)據(jù)時(shí)返回
? ? ?客戶可以將此標(biāo)志用做特殊用途,此標(biāo)志對(duì)服務(wù)器來(lái)說(shuō)是透明的
4. exptime> 過(guò)期的時(shí)間
? ? ?0 表示存儲(chǔ)的數(shù)據(jù)永遠(yuǎn)不過(guò)期(但可被服務(wù)器算法:LRU 等替換)
? ? ?n?非0數(shù)字(unix時(shí)間),當(dāng)過(guò)期后服務(wù)器可以保證用戶得不到該數(shù)據(jù)(以服務(wù)器時(shí)間為標(biāo)準(zhǔn))
5. bytes> 需要存儲(chǔ)的字節(jié)數(shù)(不包含最后的”\r\n”),當(dāng)用戶希望存儲(chǔ)空數(shù)據(jù)時(shí),可以為0
6. 最后客戶端需要加上”\r\n”作為”命令頭”的結(jié)束標(biāo)志
7. data block>
? ? ?緊接著”命令頭”結(jié)束之后就要發(fā)送數(shù)據(jù)塊(即希望存儲(chǔ)的數(shù)據(jù)內(nèi)容),最后加上”\r\n”作為此次通訊的結(jié)束。
?
telnet 響應(yīng)命令
當(dāng)以上數(shù)據(jù)發(fā)送結(jié)束之后,服務(wù)器將返回一個(gè)應(yīng)答,可能有如下情況:
1. STORED:表示存儲(chǔ)成功
2. NOT_STORED: 表示存儲(chǔ)失敗,但是該失敗不是由于錯(cuò)誤。
? ? 通常這是由于”add”或者”replace”命令本身的要求所引起的,或者該項(xiàng)在刪除隊(duì)列之中。
示例
set key 32 0 10 helloworld STORED?
獲取 Key&Value
get key>*參數(shù)詳解:
1. key>*: 表示一個(gè)或者多個(gè)key(以空格分開(kāi))
2. \r\n:命令結(jié)束
?
響應(yīng)結(jié)果
服務(wù)器端將返回0個(gè)或者多個(gè)的數(shù)據(jù)項(xiàng)。每個(gè)數(shù)據(jù)項(xiàng)都是由一個(gè)文本行和一個(gè)數(shù)據(jù)塊組成。當(dāng)所有的數(shù)據(jù)項(xiàng)都接收完畢將收到END\r\n每一項(xiàng)的數(shù)據(jù)結(jié)構(gòu):
VALUE key> flags> bytes> data block>參數(shù)詳解:
1. key> 希望得到存儲(chǔ)數(shù)據(jù)的key
2.falg> 發(fā)送set命令時(shí)設(shè)置的標(biāo)志項(xiàng)
3.bytes>發(fā)送數(shù)據(jù)塊的長(zhǎng)度(不包含”\r\n”)
4.\r\n 文本行的結(jié)束標(biāo)志
5.data block> 希望接收的數(shù)據(jù)項(xiàng)。
6.\r\n 接收一個(gè)數(shù)據(jù)項(xiàng)的結(jié)束標(biāo)志。
PS:如果有些key出現(xiàn)在get命令行中但沒(méi)有返回相應(yīng)的數(shù)據(jù),這意味著服務(wù)器中不存在該項(xiàng),可能是超時(shí)了,或者被刪除了。
示例
get key VALUE key 32 10 helloworld END?
刪除KeyValue
delete key> time>參數(shù)詳解:
1. key> 需要被刪除數(shù)據(jù)的key
2. time> 客戶端希望服務(wù)器將該數(shù)據(jù)刪除的時(shí)間(unix時(shí)間或者從現(xiàn)在開(kāi)始的秒數(shù))
3. \r\n命令頭的結(jié)束
?
檢查Memcache服務(wù)器狀態(tài)
stats在這里可以看到memcache的獲取次數(shù),當(dāng)前連接數(shù),寫(xiě)入次數(shù),已經(jīng)命中率等;
pid : 進(jìn)程iduptime :總的運(yùn)行時(shí)間,秒數(shù)
time : 當(dāng)前時(shí)間
version : 版本號(hào)
….
curr_items : 當(dāng)前緩存中的KeyValue數(shù)量
total_items : 曾經(jīng)總共經(jīng)過(guò)緩存的KeyValue數(shù)量
bytes : 所有的緩存使用的內(nèi)存量
….
curr_connections 當(dāng)前連接數(shù)
cmd_get : 總獲取次數(shù)
cmd_set : 總的寫(xiě)入次數(shù)
get_hits : 總的命中次數(shù)
miss_hits :? 獲取失敗次數(shù)
….
bytes_read : 總共讀取的流量字節(jié)數(shù)
bytes_written : 總的寫(xiě)入流量字節(jié)
limit_maxbytes : 最大允許使用的內(nèi)存量,字節(jié)
?
清空統(tǒng)計(jì)數(shù)據(jù)
stats reset?
清除單個(gè)key值
delete key?
清空所有鍵值
flush_all注:flush并不會(huì)將items刪除,只是將所有的items標(biāo)記為expired,因此這時(shí)memcache依舊占用所有內(nèi)存。
?
退出
quit ? ? 或者 ??Ctrl + ]??
其他命令
1. 顯示各個(gè)slab的信息,包括chunk的大小、數(shù)目、使用情況等
stats slabs?
2. 顯示各個(gè)slab中item的數(shù)目和最老item的年齡(最后一次訪問(wèn)距離現(xiàn)在的秒數(shù))
stats items?
3. 設(shè)置或者顯示詳細(xì)操作記錄
stats detail [on|off|dump]?
參數(shù)為on,打開(kāi)詳細(xì)操作記錄
參數(shù)為off,關(guān)閉詳細(xì)操作記錄
參數(shù)為dump,顯示詳細(xì)操作記錄(每一個(gè)鍵值get、set、hit、del的次數(shù))
?
4. 顯示某個(gè)slab中的前l(fā)imit_num個(gè)key列表
stats cachedump slab_id limit_num顯示格式如下:
ITEM key_name> [?<value_length>b;?<expire_time access_time="">s]?
key_name>:鍵名
value_length>:值長(zhǎng)度(單位字節(jié))
expire_time|access_time>:memcached 1.2.2及以前版本顯示的是 訪問(wèn)時(shí)間(timestamp)
總結(jié)
以上是生活随笔為你收集整理的memcache 缓存的批量删除方案(转)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Spring-web源码解析之Filte
- 下一篇: esxi虚机启动慢的问题