21Python標(biāo)準(zhǔn)庫(kù)系列之Memcache模塊

Python標(biāo)準(zhǔn)庫(kù)系列之Memcache模塊


創(chuàng)新互聯(lián)建站主要業(yè)務(wù)有網(wǎng)站營(yíng)銷策劃、成都做網(wǎng)站、成都網(wǎng)站制作、成都外貿(mào)網(wǎng)站建設(shè)、微信公眾號(hào)開(kāi)發(fā)、微信小程序開(kāi)發(fā)、H5建站、程序開(kāi)發(fā)等業(yè)務(wù)。一次合作終身朋友,是我們奉行的宗旨;我們不僅僅把客戶當(dāng)客戶,還把客戶視為我們的合作伙伴,在開(kāi)展業(yè)務(wù)的過(guò)程中,公司還積累了豐富的行業(yè)經(jīng)驗(yàn)、網(wǎng)絡(luò)營(yíng)銷推廣資源和合作伙伴關(guān)系資源,并逐漸建立起規(guī)范的客戶服務(wù)和保障體系。 

這個(gè)模塊是一個(gè)Python操作memcached的一個(gè)API接口。

Memcached官網(wǎng):http://memcached.org/
模塊官網(wǎng):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.

以上內(nèi)容摘自官網(wǎng)的介紹,具體信息訪問(wèn)官網(wǎng)


安裝Memcached

包安裝

Ubuntu

apt-get install memcached

CentOS

yum install memcached

源碼安裝

Memcached源碼包安裝的時(shí)候需要依賴于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

具體參數(shù)見(jiàn)./configure --help全選項(xiàng),SASL支持需要一些可選附加庫(kù)。

啟動(dòng)

我這里安裝的時(shí)候是采用包的方式進(jìn)行安裝的。

[root@anshengme ~]# memcached -d -m 10 -u root -l 0.0.0.0 -p 11211 -c 256 -P /tmp/memcached.pid

參數(shù)說(shuō)明

參數(shù)描述
-d是啟動(dòng)一個(gè)守護(hù)進(jìn)程
-m是分配給Memcache使用的內(nèi)存數(shù)量,單位是MB
-u是運(yùn)行Memcache的用戶
-l是監(jiān)聽(tīng)的服務(wù)器IP地址
-p是設(shè)置Memcache監(jiān)聽(tīng)的端口,最好是1024以上的端口
-c選項(xiàng)是最大運(yùn)行的并發(fā)連接數(shù),默認(rèn)是1024,按照你服務(wù)器的負(fù)載量來(lái)設(shè)定
-P是設(shè)置保存Memcache的pid文件

設(shè)置開(kāi)機(jī)自啟動(dòng)

[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

關(guān)閉memcached

[root@anshengme ~]# pkill `cat /tmp/memcached.pid`

測(cè)試

先查看11211端口是否啟動(dòng)

[root@anshengme ~]# netstat -tlnp | grep "11211"
tcp        0      0 0.0.0.0:11211           0.0.0.0:*               LISTEN      4245/memcached

使用telnet查看啟動(dòng)的11211端口是否可以,可以則測(cè)試OK,否則就需要你拍錯(cuò)了,但愿沒(méi)有問(wèn)題。

[root@anshengme ~]# telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.

如果出現(xiàn)以下內(nèi)容就代表啟動(dòng)成功!

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

進(jìn)入Python解釋器導(dǎo)入模塊,如果導(dǎo)入成功就表示模塊安裝成功。

[root@anshengme python-memcached-1.58]# python
>>> import memcache
>>>

首次體驗(yàn)

# 導(dǎo)入memcache模塊
>>> import memcache
# 連接到一臺(tái)Memcached服務(wù)器
>>> conn = memcache.Client(['192.168.56.100:11211'])
# 設(shè)置一個(gè)值,如果存在則覆蓋
>>> conn.set('k1', 'v1')
True
# 獲取值的內(nèi)容
>>> conn.get('k1')
'v1'

更多的使用方法

設(shè)置超時(shí)時(shí)間

>>> conn.set('k', 'v', 1)
True
>>> conn.get('k')

設(shè)置值,如果存在就報(bào)錯(cuò)

>>> conn.add('k','hello')
# False設(shè)置失敗
False
>>> conn.get('k')
# 原值沒(méi)變
'v'

修改值,不存在則返回False

>>> conn.replace('k','helloworld')
# 設(shè)置成功
True
>>> conn.get('k')
# 返回修改后的值
'helloworld'
>>> conn.replace('kkkk','hello')
# 修改一個(gè)不存在的值
False

設(shè)置多個(gè)值,值不存在則創(chuàng)建,存在則修改

>>> conn.get('key1')
>>> conn.set_multi({'key1':'value1','key2':'value2'})
[]
>>> conn.get('key1')
'value1'

刪除一個(gè)值

>>> conn.get('key1')
'value1'
>>> conn.delete('key1')
1
>>> conn.get('key1')

刪除多個(gè)值

>>> conn.set_multi({'key3':'value3','key4':'value4'})
[]
>>> conn.delete_multi(['key3', 'key4'])
1

獲取一個(gè)值和獲取多個(gè)值

>>> conn.set_multi({'key5':'value5','key6':'value6'})
[]
>>> conn.get('key5')
'value5'
>>> conn.get_multi(['key5','key6'])
{'key5': 'value5', 'key6': 'value6'}

修改指定key的值,在該值后面追加內(nèi)容

>>> conn.append('key5','after')
True
>>> conn.get('key5')
'value5after'

修改指定key的值,在該值 前面 插入內(nèi)容

>>> conn.prepend('key5','before')
True
>>> conn.get('key5')
'beforevalue5after'

自增與自減,將Memcached中的某一個(gè)值加或減少N(N默認(rè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

比如設(shè)置了這么一個(gè)值:

conn.set('n','10)

現(xiàn)在A用戶和B用戶同時(shí)獲取到了這兩個(gè)值,如果有其中的任何一個(gè)用戶對(duì)這個(gè)值進(jìn)行了修改,那么另外一個(gè)用戶在對(duì)這個(gè)值進(jìn)行操作的時(shí)候就會(huì)報(bào)錯(cuò)。

如果要解決以上的問(wèn)題可以使用getscas,測(cè)試代碼如下:

# -- 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會(huì)獲取到值并且獲取計(jì)數(shù)器
result = conn1.gets('n')
print(result)
# 阻塞
input('>>>')
# 設(shè)置值
conn1.cas('n', 99)


# -- s2
# _*_ coding:utf-8 _*_
import memcache
conn2 = memcache.Client(['192.168.56.100:11211'], debug=True, cache_cas=True)
# gets會(huì)獲取到值并且獲取計(jì)數(shù)器
result = conn2.gets('n')
print(result)
# 阻塞
input('>>>')
# 設(shè)置值
conn2.cas('n', 100)

執(zhí)行效果如下圖:
21Python標(biāo)準(zhǔn)庫(kù)系列之Memcache模塊

多節(jié)點(diǎn)的操作

首先在服務(wù)器上面起四個(gè)memcached實(shí)例,每個(gè)實(shí)例都是一個(gè)單獨(dú)的memcached服務(wù)

[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

# 連接到多臺(tái)memcached服務(wù)器
conn = memcache.Client(
    # IP:端口,權(quán)重
    [('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é)點(diǎn)數(shù)據(jù)存儲(chǔ)流程

  1. 先將一個(gè)字符串轉(zhuǎn)換為一個(gè)數(shù)字

  2. 得出的結(jié)果和節(jié)點(diǎn)的數(shù)量進(jìn)行除法運(yùn)算

  3. 得出的結(jié)果肯定在節(jié)點(diǎn)數(shù)量之間,余數(shù)是幾,就在那臺(tái)節(jié)點(diǎn)上面存放數(shù)據(jù)

如圖所示

21Python標(biāo)準(zhǔn)庫(kù)系列之Memcache模塊

# 將字符串轉(zhuǎn)換為數(shù)字模塊
import binascii

# 摘自memcache源碼中的一部分
def cmemcache_hash(key):
    return ((((binascii.crc32(key) & 0xffffffff) >> 16) & 0x7fff) or 1)
    
    # result就是返回的數(shù)字
result = cmemcache_hash(bytes('k', encoding='utf-8'))
print(result)

基于Memcached的Session實(shí)例

主程序腳本

# _*_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):
        # 獲取傳過(guò)來(lái)的值
        Key = self.get_argument('key')
        Val = self.get_argument('val')
        action = self.get_argument('action')
        if action == 'set':
            # 設(shè)置值
            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()

模板文件

<!-- template\index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
</head>
<body>

<form action="/" method="post">
    set/del:<input type="text" name="action" value="set"/>
    Key: <input type="text" name="key"/>
    Val: <input type="text" name="val"/>
    <input type="submit" value="設(shè)置"/>
</form>

{{ Data }}

</body>
</html>

設(shè)置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: 請(qǐng)求頭
        """
        self.handler = handler
        # 從客戶端獲取隨機(jī)字符串
        SessionID = self.handler.get_secure_cookie(Session.CookieID, None)
        # 客戶端存在并且在服務(wù)端也存在
        if SessionID and conn.get(SessionID):
            self.SessionID = SessionID
        else:
            # 獲取隨機(jī)字符串
            self.SessionID = self.SessionKey()
            # 把隨機(jī)字符串寫(xiě)入memcached,時(shí)間是20分鐘
            conn.set(self.SessionID, json.dumps({}), Session.ExpiresTime)
        # 每次訪問(wèn)超時(shí)時(shí)間就加20分鐘
        conn.set(self.SessionID, conn.get(self.SessionID), Session.ExpiresTime)
        # 設(shè)置Cookie
        self.handler.set_secure_cookie('uc', self.SessionID)
        
    def SessionKey(self):
        """
        :return: 生成隨機(jī)字符串
        """
        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):
        """
        設(shè)置session
        :param key: session信息中的key
        :param value: 對(duì)應(yīng)的Value
        """
        # 獲取session_id
        SessionDict = json.loads(conn.get(self.SessionID))
        # 設(shè)置字典的key
        SessionDict[key] = value
        # 重新賦值
        conn.set(self.SessionID, json.dumps(SessionDict), Session.ExpiresTime)
        
    def __getitem__(self, item):
        """
        :param item: Session信息中對(duì)應(yīng)的Key
        :return: 獲取的Session信息
        """
        # 獲取SessionID并轉(zhuǎn)換為字典
        SessionDict = json.loads(conn.get(self.SessionID))
        # 獲取對(duì)應(yīng)的數(shù)據(jù)
        ResultData = SessionDict.get(item, None)
        return ResultData
        
    def __delitem__(self, key):
        """
        :param key: 要?jiǎng)h除的Key
        """
        # 獲取SessionID并轉(zhuǎn)換為字典
        SessionDict = json.loads(conn.get(self.SessionID))
        # 刪除字典的key
        del SessionDict[key]
        # 重新賦值
        conn.set(self.SessionID, json.dumps(SessionDict), Session.ExpiresTime)
        
    def GetAll(self):
        # 獲取Session中所有的信息,僅用于測(cè)試
        SessionData = conn.get(self.SessionID)
        return SessionData

演示如下:
21Python標(biāo)準(zhǔn)庫(kù)系列之Memcache模塊

#Python標(biāo)準(zhǔn)庫(kù) #Memcache

網(wǎng)頁(yè)名稱:21Python標(biāo)準(zhǔn)庫(kù)系列之Memcache模塊
文章來(lái)源:http://muchs.cn/article42/jiogec.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供標(biāo)簽優(yōu)化電子商務(wù)、搜索引擎優(yōu)化微信小程序、App開(kāi)發(fā)、網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

小程序開(kāi)發(fā)