1. 程式人生 > >Python操作Memcached

Python操作Memcached

uno 每次 守護 插入內容 imp 不想 但是 href 數據庫驅動

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