天天看點

python操作memcache

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,如需轉載請自行聯系原作者