Python操作Memcached
Memcached 是一個高性能的分布式內存對象緩存系統,用於動態Web應用以減輕數據庫負載。它通過在內存中緩存數據和對象來減少讀取數據庫的次數,從而提高動態、數據庫驅動網站的速度。Memcached基於一個存儲鍵/值對的hashmap。其守護進程(daemon )是用C寫的,但是客戶端可以用任何語言來編寫,並通過memcached協議與守護進程通信。
linux下安裝memcached
memcached官網,戳我
安裝libevent tar zxf libevent-2.0.22-stable.tar.gz cd libevent-2.0.22-stable ./configure --prefix=/usr/local/libevent make make install 安裝memcached tar zxf memcached-1.4.36.tar.gz cd memcached-1.4.36 ./configure --prefix=/usr/local/memcache --with-libevent=/usr/local/libevent/ make make install ln -s /usr/local/memcache/bin/* /usr/local/bin/
啟動Memcached
memcached -m 32m -p 11211 -d -u root -P /var/run/memcache.pid -c 256 參數說明: -d 是啟動一個守護進程 -m 是分配給Memcache使用的內存數量,單位是MB -u 是運行Memcache的用戶 -l 是監聽的服務器IP地址 -p 是設置Memcache監聽的端口,最好是1024以上的端口 -c 選項是最大運行的並發連接數,默認是1024,按照你服務器的負載量來設定 -P 是設置保存Memcache的pid文件
使用telnet連接memcached
telnet 192.168.56.102 11211
memcahce的命令及更多,戳我
使用python操作memcached
安裝API
python操作Memcached使用Python-memcached模塊 下載安裝:https://pypi.python.org/pypi/python-memcached
1、第一次操作
import memcache mc = memcache.Client([‘192.168.56.102:11211‘], debug=True) mc.set("foo", "bar") ret = mc.get(‘foo‘) print ret
Ps:debug = True 表示運行出現錯誤時,現實錯誤信息,上線後移除該參數。
2、天生支持集群
python-memcached模塊原生支持集群操作,其原理是在內存維護一個主機列表,且集群中主機的權重值和主機在列表中重復出現的次數成正比
主機 權重 192.168.56.102 1 192.168.56.103 2 192.168.56.104 1 那麽在內存中主機列表為: host_list = ["192.168.56.102", "192.168.56.103", "192.168.56.104", "192.168.56.105", ]
如果用戶根據如果要在內存中創建一個鍵值對(如:k1 = "v1"),那麽要執行一下步驟:
- 根據算法將 k1 轉換成一個數字
- 將數字和主機列表長度求余數,得到一個值 N( 0 <= N < 列表長度 )
- 在主機列表中根據 第2步得到的值為索引獲取主機,例如:host_list[N]
- 連接 將第3步中獲取的主機,將 k1 = "v1" 放置在該服務器的內存中
代碼實現如下:
mc = memcache.Client([(‘192.168.56.102:11211‘, 1), (‘192.168.56.103:11211‘, 2), (‘192.168.56.104:11211‘, 1)], debug=True) mc.set(‘k1‘, ‘v1‘)
3、add
添加一條鍵值對,如果已經存在的 key,重復執行add操作異常
#!/usr/bin/env python # -*- coding:utf-8 -*- import memcache mc = memcache.Client([‘192.168.10.102:11211‘], debug=True) mc.add(‘k1‘, ‘v1‘) # mc.add(‘k1‘, ‘v2‘) # 報錯,對已經存在的key重復添加,失敗!!!
4、replace
replace 修改某個key的值,如果key不存在,則異常
#!/usr/bin/env python # -*- coding:utf-8 -*- import memcache mc = memcache.Client([‘192.168.10.102:11211‘], debug=True) # 如果memcache中存在kkkk,則替換成功,否則一場 mc.replace(‘kkkk‘,‘999‘)
5、set 和 set_multi
set 設置一個鍵值對,如果key不存在,則創建,如果key存在,則修改
set_multi 設置多個鍵值對,如果key不存在,則創建,如果key存在,則修改
#!/usr/bin/env python # -*- coding:utf-8 -*- import memcache mc = memcache.Client([‘192.168.10.102:11211‘], debug=True) mc.set(‘key‘, ‘musker‘) mc.set_multi({‘key1‘: ‘val1‘, ‘key2‘: ‘val2‘})
6、delete 和 delete_multi
delete 在Memcached中刪除指定的一個鍵值對
delete_multi 在Memcached中刪除指定的多個鍵值對
#!/usr/bin/env python # -*- coding:utf-8 -*- import memcache mc = memcache.Client([‘192.168.10.102:11211‘], debug=True) mc.delete(‘key‘) mc.delete_multi([‘key1‘, ‘key2‘])
7、get 和 get_multi
get 獲取一個鍵值對
get_multi 獲取多一個鍵值對
#!/usr/bin/env python # -*- coding:utf-8 -*- import memcache mc = memcache.Client([‘102.168.56.102:11211‘], debug=True) val = mc.get(‘key‘) item_dict = mc.get_multi(["key1", "key2", "key3"])
8、append 和 prepend
append 修改指定key的值,在該值 後面 追加內容
prepend 修改指定key的值,在該值 前面 插入內容
#!/usr/bin/env python # -*- coding:utf-8 -*- import memcache mc = memcache.Client([‘192.168.56.102:11211‘], debug=True) # k1 = "v1" mc.append(‘k1‘, ‘after‘) # k1 = "v1after" mc.prepend(‘k1‘, ‘before‘) # k1 = "beforev1after"
9、decr 和 incr
incr 自增,將Memcached中的某一個值增加 N ( N默認為1 )
decr 自減,將Memcached中的某一個值減少 N ( N默認為1 )
#!/usr/bin/env python # -*- coding:utf-8 -*- import memcache mc = memcache.Client([‘192.168.56.102:11211‘], debug=True) mc.set(‘k1‘, ‘777‘) mc.incr(‘k1‘) # k1 = 778 mc.incr(‘k1‘, 10) # k1 = 788 mc.decr(‘k1‘) # k1 = 787 mc.decr(‘k1‘, 10) # k1 = 777
10、gets 和 cas
如商城商品剩余個數,假設改值保存在memcache中,product_count = 900
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 即可,如:
#!/usr/bin/env python # -*- coding:utf-8 -*- import memcache mc = memcache.Client([‘192.168.56.102:11211‘], debug=True, cache_cas=True) v = mc.gets(‘product_count‘) # ... # 如果有人在gets之後和cas之前修改了product_count,那麽,下面的設置將會執行失敗,剖出異常,從而避免非正常數據的產生 mc.cas(‘product_count‘, "899")
Ps:本質上每次執行gets時,會從memcache中獲取一個自增的數字,通過cas去修改gets的值時,會攜帶之前獲取的自增值和memcache中的自增值進行比較,如果相等,則可以提交,如果不想等,那表示在gets和cas執行之間,又有其他人執行了gets(獲取了緩沖的指定值), 如此一來有可能出現非正常數據,則不允許修改。
Python操作Memcached