Memcached是一個高性能的分布式記憶體對象緩存系統,用于動态Web應用以減輕資料庫負載。它通過在記憶體中緩存資料和對象減少讀取資料庫的次數,進而提高動态、資料庫驅動網站的速度。Memcached基于一個存儲鍵/值的hash map。其守護程序(daemon)是用C語言寫的,但是用戶端可以用任何語言來編寫,并通過memcached協定與守護程序通信。
安裝
cd /usr/local/src
wget http://memcached.org/latest
tar -zxvf memcached-1.x.x.tar.gz
cd memcached-1.x.x
./configure && make && make test && make install
啟動
memcached -d -m 10 -u root -l 127.0.0.1 -p 12000 -c 256 -P /export/servers/memcache/logs/memcache.pid
-p 指定端口号(預設11211)
-m 指定最大使用記憶體大小(預設64MB)
-t 線程數(預設4)
-l 連接配接的IP位址, 預設是本機
-d 以背景守護程序的方式啟動
-c 最大同時連接配接數,預設是1024
-P 制定memecache的pid檔案
-h 列印幫助資訊
ps -ef檢查memcache是否啟動,檢查端口号
Python操作memcache叢集
python-memcachd子產品原生支援叢集操作,其原理是在記憶體維護一個主機清單,且叢集中主機的權重值和主機在清單中重複出現的次數成正比。
主機 權重
1.1.1.1 1
1.1.1.2 2
1.1.1.3 1
那麼在記憶體中主機清單為:host_list=['1.1.1.1','1.1.1.2','1.1.1.2','1.1.1.3',]
例子:
mc = memcache.Client([('1.1.1.1:12000', 1), ('1.1.1.2:12000', 2), ('1.1.1.3:12000', 1)], debug=True)
mc.set('k1', 'v1')
如果使用者要在記憶體中建立一個鍵值對(如:k1 = “v1”),那麼要執行以下步驟:
根據算法将k1轉換成一個數字;
将數字和主機清單長度求餘數,得到一個值N(0 <= N < 清單長度);
在主機清單中根據第2步得到的值為索引擷取主機,例如:host_list[N];
連接配接将第3步中擷取的主機,将k1 = 'v1'放置在該伺服器的記憶體中。
上面例子我們通過調用memcache子產品來實作對memcached進行存取資料,debug=True表示運作中出現錯誤時,顯示錯誤資訊,上線後移除該參數。
常用操作
add方法
添加一條鍵值對,如果已經存在的key,重複執行add操作會報異常。
import memcache
mc = memcache.Client(['192.168.1.1:11211'], debug=True)
#mc.set("foo", "bar")
#ret = mc.get("foo")
mc.add('k1','v1')
#print(ret)
replace方法
replace修改某個key的值,如果key不存在,則異常。
#mc.add('k1','v1')
mc.replace("k1", "666")
print(mc.get("k1"))
輸出:
666
set和set_multi方法
set:設定一個鍵值對,如果key不存在,則建立,如果key存在,則修改;
set_multi:設定多個鍵值對,如果key不存在,則建立,如果key存在,則修改。
mc.set("k10", "v10")
mc.set_multi({"k11": "v11", "k12": "v12"})
set方法和add方法的差別
set = add + replace
add 方法:add方法用于向memcache伺服器添加一個要緩存的資料。如果memcache伺服器中已經存在要存儲的key,此時add方法調用失敗。
set 方法:set方法用于設定一個指定key的緩存内容,set方法是add方法和replace方法的集合體。如果要設定的key不存在時,則set方法與add方法的效果一緻;如果要設定的key已經存在時,則set方法與replace方法效果一樣。
replace方法: replace方法用于替換一個指定key的緩存内容,如果key不存在則傳回false
delete和delete_multi方法
delete:在Memcached中删除指定的一個鍵值對;
delete_multi:在Memcached中删除指定的多個鍵值對。
#mc.set("k10", "v10")
#mc.set_multi({"k11": "v11", "k12": "v12"})
mc.delete("k10")
mc.delete_multi(["k11", "k12"])
get和get_multi方法
get : 擷取一個鍵值對;
get_multi:擷取多個鍵值對。
mc = memcache.Client(['192.168.48.128:11211'], debug=True)
#mc.delete("k10")
#mc.delete_multi(["k11", "k12"])
val = mc.get('k1')
print(val)
item_dict = mc.get_multi(['k11', 'k12'])
print(item_dict)
append和prepend方法
append:修改指定key的值,在該值後面追加内容;
prepend:修改指定key的值,在該值前面插入内容。
mc = memcache.Client(['192.168.10.128:12000'], debug=True)
mc.append('k1','after')
val1 = mc.get('k1')
print(val1)
mc.prepend('k1','brefore')
val2 = mc.get('k1')
print(val2)
v1afterafter
breforev1afterafter
incr:自增,将Memcached中的某一個值增加N(N預設為1);
decr:自減,将Memcached中的某一個值減少N(N預設為1)。
#預設自增1,第二個參數為增加的n
mc.set('k1','777')
#mc.incr('k1')
mc.incr('k1',10)
mc.decr('k1',20)
787 #自增後的結果
767 #自減後的結果
gets和cas:
如商城商品剩餘個數,假設改值儲存在memcache中,product_count =9000
A使用者重新整理頁面從memcache中讀取到product_count = 900
B使用者重新整理頁面從memcache中讀取到product_count = 900
如果A、B使用者均購買商品:
A使用者修改商品剩餘個數 product_count = 899
B使用者修改商品剩餘個數product_count = 899
如此一來緩存内的資料便不再正确,兩個使用者購買商品後,商品剩餘還是899,如果使用python的set和get來操作以上過程,那麼程式就會如上述所示情況,資料不準确。
如果想要避免此情況的發生,隻要使用gets和cas即可
v = mc.gets('product_count')
print(v)
#如果有人在gets之後和cas之前修改了product_count,那麼下面的設定将會執行失敗,抛出異常,進而避免非正常資料的産出
v1 = mc.cas('product_count',"899")
print(v1)
899
True
本質上每次執行gets時,會從memcache中擷取一個自增的數字,通過cas去修改gets的值時,會攜帶之前擷取的自增值和memcache中的自增值進行比較,如果相等,則可以送出,如果不相等,那表示在gets和cas執行之間,又有其他人執行了gets(擷取了緩沖的指定值),如此一來有可能出現非正常資料,則不允許修改。
本文轉自 粗糧面包 51CTO部落格,原文連結:http://blog.51cto.com/culiangmianbao/2048169,如需轉載請自行聯系原作者