新聞中心
Python標準庫系列之Memcache模塊
創(chuàng)新互聯(lián)建站主要業(yè)務有網站營銷策劃、成都做網站、成都網站制作、成都外貿網站建設、微信公眾號開發(fā)、微信小程序開發(fā)、H5建站、程序開發(fā)等業(yè)務。一次合作終身朋友,是我們奉行的宗旨;我們不僅僅把客戶當客戶,還把客戶視為我們的合作伙伴,在開展業(yè)務的過程中,公司還積累了豐富的行業(yè)經驗、網絡營銷推廣資源和合作伙伴關系資源,并逐漸建立起規(guī)范的客戶服務和保障體系。
這個模塊是一個Python
操作memcached
的一個API接口。
Memcached官網:http://memcached.org/
模塊官網:https://pypi.python.org/pypi/python-memcached/
What is Memcached?
Free & open source, high-performance, distributed memory object caching system, generic in nature, but intended for use in speeding up dynamic web applications by alleviating database load.
Memcached is an in-memory key-value store for small chunks of arbitrary data (strings, objects) from results of database calls, API calls, or page rendering.
Memcached is simple yet powerful. Its simple design promotes quick deployment, ease of development, and solves many problems facing large data caches. Its API is available for most popular languages.
以上內容摘自官網的介紹,具體信息訪問官網
安裝Memcached
包安裝
Ubuntu
apt-get install memcached
CentOS
yum install memcached
源碼安裝
Memcached
源碼包安裝的時候需要依賴于libevent
# Ubuntu apt-get install libevent-dev # CentOS yum install libevent-devel
編譯安裝memcached
wget https://memcached.org/latest tar -zxf memcached-1.x.x.tar.gz cd memcached-1.x.x ./configure --prefix=/usr/local/memcached make && make test && sudo make install
具體參數見./configure --help
全選項,SASL支持需要一些可選附加庫。
啟動
我這里安裝的時候是采用包的方式進行安裝的。
[root@anshengme ~]# memcached -d -m 10 -u root -l 0.0.0.0 -p 11211 -c 256 -P /tmp/memcached.pid
參數說明
參數 | 描述 |
---|---|
-d | 是啟動一個守護進程 |
-m | 是分配給Memcache使用的內存數量,單位是MB |
-u | 是運行Memcache的用戶 |
-l | 是監(jiān)聽的服務器IP地址 |
-p | 是設置Memcache監(jiān)聽的端口,最好是1024以上的端口 |
-c | 選項是最大運行的并發(fā)連接數,默認是1024,按照你服務器的負載量來設定 |
-P | 是設置保存Memcache的pid文件 |
設置開機自啟動
[root@anshengme ~]# chmod +x /etc/rc.d/rc.local [root@anshengme ~]# echo 'memcached -d -m 10 -u root -l 0.0.0.0 -p 11211 -c 256 -P /tmp/memcached.pid' >> /etc/rc.local
關閉memcached
[root@anshengme ~]# pkill `cat /tmp/memcached.pid`
測試
先查看11211端口是否啟動
[root@anshengme ~]# netstat -tlnp | grep "11211" tcp 0 0 0.0.0.0:11211 0.0.0.0:* LISTEN 4245/memcached
使用telnet查看啟動的11211端口是否可以,可以則測試OK,否則就需要你拍錯了,但愿沒有問題。
[root@anshengme ~]# telnet 127.0.0.1 11211 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'.
如果出現(xiàn)以下內容就代表啟動成功!
Memcache使用
安裝Memcache
下載模塊包,目前最新版
[root@anshengme ~]# wget https://pypi.python.org/packages/f7/62/14b2448cfb04427366f24104c9da97cf8ea380d7258a3233f066a951a8d8/python-memcached-1.58.tar.gz#md5=23b258105013d14d899828d334e6b044
解壓并安裝
[root@anshengme ~]# tar xf python-memcached-1.58.tar.gz [root@anshengme ~]# cd python-memcached-1.58 [root@anshengme python-memcached-1.58]# python setup.py install
進入Python解釋器導入模塊,如果導入成功就表示模塊安裝成功。
[root@anshengme python-memcached-1.58]# python >>> import memcache >>>
首次體驗
# 導入memcache模塊 >>> import memcache # 連接到一臺Memcached服務器 >>> conn = memcache.Client(['192.168.56.100:11211']) # 設置一個值,如果存在則覆蓋 >>> conn.set('k1', 'v1') True # 獲取值的內容 >>> conn.get('k1') 'v1'
更多的使用方法
設置超時時間
>>> conn.set('k', 'v', 1) True >>> conn.get('k')
設置值,如果存在就報錯
>>> conn.add('k','hello') # False設置失敗 False >>> conn.get('k') # 原值沒變 'v'
修改值,不存在則返回False
>>> conn.replace('k','helloworld') # 設置成功 True >>> conn.get('k') # 返回修改后的值 'helloworld' >>> conn.replace('kkkk','hello') # 修改一個不存在的值 False
設置多個值,值不存在則創(chuàng)建,存在則修改
>>> conn.get('key1') >>> conn.set_multi({'key1':'value1','key2':'value2'}) [] >>> conn.get('key1') 'value1'
刪除一個值
>>> conn.get('key1') 'value1' >>> conn.delete('key1') 1 >>> conn.get('key1')
刪除多個值
>>> conn.set_multi({'key3':'value3','key4':'value4'}) [] >>> conn.delete_multi(['key3', 'key4']) 1
獲取一個值和獲取多個值
>>> conn.set_multi({'key5':'value5','key6':'value6'}) [] >>> conn.get('key5') 'value5' >>> conn.get_multi(['key5','key6']) {'key5': 'value5', 'key6': 'value6'}
修改指定key的值,在該值后面
追加內容
>>> conn.append('key5','after') True >>> conn.get('key5') 'value5after'
修改指定key的值,在該值 前面 插入內容
>>> conn.prepend('key5','before') True >>> conn.get('key5') 'beforevalue5after'
自增與自減,將Memcached中的某一個值加或減少N(N默認為1)
>>> conn.set('number','9') True # 增加 >>> conn.incr('number') 10 # 增加 >>> conn.incr('number', 10) 20 # 減少 >>> conn.decr('number') 19 # 減少 >>> conn.decr('number', 10) 9
比如設置了這么一個值:
conn.set('n','10)
現(xiàn)在A用戶和B用戶同時獲取到了這兩個值,如果有其中的任何一個用戶對這個值進行了修改,那么另外一個用戶在對這個值進行操作的時候就會報錯。
如果要解決以上的問題可以使用gets
與cas
,測試代碼如下:
# -- s1.py # _*_ coding:utf-8 _*_ import memcache conn1 = memcache.Client(['192.168.56.100:11211'], debug=True, cache_cas=True) conn1.set('n', 9) # gets會獲取到值并且獲取計數器 result = conn1.gets('n') print(result) # 阻塞 input('>>>') # 設置值 conn1.cas('n', 99) # -- s2 # _*_ coding:utf-8 _*_ import memcache conn2 = memcache.Client(['192.168.56.100:11211'], debug=True, cache_cas=True) # gets會獲取到值并且獲取計數器 result = conn2.gets('n') print(result) # 阻塞 input('>>>') # 設置值 conn2.cas('n', 100)
執(zhí)行效果如下圖:
多節(jié)點的操作
首先在服務器上面起四個memcached
實例,每個實例都是一個單獨的memcached
服務
[root@anshengme ~]# netstat -tlnp | grep "memcached" tcp 0 0 0.0.0.0:11211 0.0.0.0:* LISTEN 1125/memcached tcp 0 0 0.0.0.0:11212 0.0.0.0:* LISTEN 1330/memcached tcp 0 0 0.0.0.0:11213 0.0.0.0:* LISTEN 1337/memcached tcp 0 0 0.0.0.0:11214 0.0.0.0:* LISTEN 1344/memcached
# _*_ coding:utf-8 _*_ import memcache # 連接到多臺memcached服務器 conn = memcache.Client( # IP:端口,權重 [('192.168.56.100:11211', 4), ('192.168.56.100:11212', 3), ('192.168.56.100:11213', 1), ('192.168.56.100:11214', 2)] ) conn.set('k', 'v')
多節(jié)點數據存儲流程
先將一個字符串轉換為一個數字
得出的結果和節(jié)點的數量進行除法運算
得出的結果肯定在節(jié)點數量之間,余數是幾,就在那臺節(jié)點上面存放數據
如圖所示
# 將字符串轉換為數字模塊 import binascii # 摘自memcache源碼中的一部分 def cmemcache_hash(key): return ((((binascii.crc32(key) & 0xffffffff) >> 16) & 0x7fff) or 1) # result就是返回的數字 result = cmemcache_hash(bytes('k', encoding='utf-8')) print(result)
基于Memcached的Session實例
主程序腳本
# _*_coding:utf-8 _*_ import tornado.ioloop import tornado.web import MemcacheToSession class BaseHandler(tornado.web.RequestHandler): def initialize(self): self.session = MemcacheToSession.Session(self) # pass class MainHandler(BaseHandler): def get(self): Info = self.session.GetAll() self.render("template/index.html", Data=Info) def post(self, *args, **kwargs): # 獲取傳過來的值 Key = self.get_argument('key') Val = self.get_argument('val') action = self.get_argument('action') if action == 'set': # 設置值 self.session[Key] = Val elif action == 'del': del self.session[Key] # 獲取所有信息 Info = self.session.GetAll() # 返回給前端渲染 self.render("template/index.html", Data=Info) settings = { "tempalte_path": "template", "cookie_secret": "508CE6152CB93994628D3E99934B83CC", } application = tornado.web.Application([ (r'/', MainHandler), ], **settings) if __name__ == "__main__": application.listen(9999) tornado.ioloop.IOLoop.instance().start()
模板文件
{{ Data }}
設置Session的小模塊
# _*_ coding: utf-8 _*_ import memcache import hashlib import uuid import json # 連接memcached conn = memcache.Client( ['192.168.56.100:11211'] ) class Session: CookieID = 'uc' ExpiresTime = 60 * 20 def __init__(self, handler): """ 用于創(chuàng)建用戶session在memcached中的字典 :param handler: 請求頭 """ self.handler = handler # 從客戶端獲取隨機字符串 SessionID = self.handler.get_secure_cookie(Session.CookieID, None) # 客戶端存在并且在服務端也存在 if SessionID and conn.get(SessionID): self.SessionID = SessionID else: # 獲取隨機字符串 self.SessionID = self.SessionKey() # 把隨機字符串寫入memcached,時間是20分鐘 conn.set(self.SessionID, json.dumps({}), Session.ExpiresTime) # 每次訪問超時時間就加20分鐘 conn.set(self.SessionID, conn.get(self.SessionID), Session.ExpiresTime) # 設置Cookie self.handler.set_secure_cookie('uc', self.SessionID) def SessionKey(self): """ :return: 生成隨機字符串 """ UUID = str(uuid.uuid1()).replace('-', '') MD5 = hashlib.md5() MD5.update(bytes(UUID, encoding='utf-8')) SessionKey = MD5.hexdigest() return SessionKey def __setitem__(self, key, value): """ 設置session :param key: session信息中的key :param value: 對應的Value """ # 獲取session_id SessionDict = json.loads(conn.get(self.SessionID)) # 設置字典的key SessionDict[key] = value # 重新賦值 conn.set(self.SessionID, json.dumps(SessionDict), Session.ExpiresTime) def __getitem__(self, item): """ :param item: Session信息中對應的Key :return: 獲取的Session信息 """ # 獲取SessionID并轉換為字典 SessionDict = json.loads(conn.get(self.SessionID)) # 獲取對應的數據 ResultData = SessionDict.get(item, None) return ResultData def __delitem__(self, key): """ :param key: 要刪除的Key """ # 獲取SessionID并轉換為字典 SessionDict = json.loads(conn.get(self.SessionID)) # 刪除字典的key del SessionDict[key] # 重新賦值 conn.set(self.SessionID, json.dumps(SessionDict), Session.ExpiresTime) def GetAll(self): # 獲取Session中所有的信息,僅用于測試 SessionData = conn.get(self.SessionID) return SessionData
演示如下:
#Python標準庫 #Memcache
網頁標題:21Python標準庫系列之Memcache模塊
分享路徑:http://fisionsoft.com.cn/article/jiogec.html