Python自動化開發(fā)學(xué)習(xí)-Memcached

講師的博客:https://www.cnblogs.com/wupeiqi/p/5132791.html
如果是要在django里使用Memcache緩存,那么下面都不用看了,直接看django里是怎么用的就好了。
這篇里緩存的章節(jié):https://blog.51cto.com/steed/2104127

創(chuàng)新互聯(lián)是一家以網(wǎng)絡(luò)技術(shù)公司,為中小企業(yè)提供網(wǎng)站維護(hù)、成都做網(wǎng)站、成都網(wǎng)站建設(shè)、網(wǎng)站備案、服務(wù)器租用、國際域名空間、軟件開發(fā)、微信平臺小程序開發(fā)等企業(yè)互聯(lián)網(wǎng)相關(guān)業(yè)務(wù),是一家有著豐富的互聯(lián)網(wǎng)運營推廣經(jīng)驗的科技公司,有著多年的網(wǎng)站建站經(jīng)驗,致力于幫助中小企業(yè)在互聯(lián)網(wǎng)讓打出自已的品牌和口碑,讓企業(yè)在互聯(lián)網(wǎng)上打開一個面向全國乃至全球的業(yè)務(wù)窗口:建站咨詢熱線:18980820575

Memcached

Memcached是一個高性能的分布式內(nèi)存對象緩存系統(tǒng),用于動態(tài)Web應(yīng)用以減輕數(shù)據(jù)庫負(fù)載。它通過在內(nèi)存中緩存數(shù)據(jù)和對象來減少讀取數(shù)據(jù)庫的次數(shù),從而提高動態(tài)、數(shù)據(jù)庫驅(qū)動網(wǎng)站的速度。Memcached基于一個存儲鍵/值對的hashmap。其守護(hù)進(jìn)程(daemon )是用C寫的,但是客戶端可以用任何語言來編寫,并通過memcached協(xié)議與守護(hù)進(jìn)程通信。

和redis比較

貌似Redis要比Memcached好。不過這兩個都不錯,也都有人在用。仔細(xì)比較的話也確實是各有優(yōu)劣的,比如Redis只使用單核,而Memcached可以使用多核。
具體看這篇吧:https://www.oschina.net/news/26691/memcached-timeout

安裝Memcached

Memcached官網(wǎng):http://memcached.org/
關(guān)于安裝,可以看這里:https://github.com/memcached/memcached/wiki/Install
可以直接用yum安裝:

$ yum install libevent-devel

可能還要安裝這個,但是上面的yum安裝時并不在依賴關(guān)系里:

$ yum install libevent-devel

上面這個我還沒有安裝。

啟動運行

$ memcached -d -m 10 -u root -l 10.211.55.4 -p 12000 -c 256 -P /tmp/memcached.pid

啟動選項:

  • -p <num> : TCP監(jiān)聽端口(default: 11211)
  • -U <num> : UDP監(jiān)聽端口(default: 11211, 0 is off)
  • -s <file> : UNIX套接字路徑偵聽
  • -a <mask> : UNIX套接字的訪問掩碼,八進(jìn)制(默認(rèn)值:0700)
  • -l <addr> : 偵聽接口地址默認(rèn)為所有地址,可以指定主機加端口可以使用逗號分隔多個地址
  • -d : 作為守護(hù)進(jìn)程運行
  • -r : 最大文件描述符
  • -u <username> : 指定運行用戶
  • -m <num> : 最大內(nèi)存(默認(rèn)為64 MB)
  • -M : 內(nèi)存耗盡時返回錯誤而不刪除項目
  • -c <num> : 最大同時連接數(shù)默認(rèn)為1024
  • -k : 鎖定所有分頁內(nèi)存
  • -v : 顯示錯誤或警告事件
  • -vv : 詳細(xì)錯誤
  • -vvv : 詳細(xì)錯誤信息及內(nèi)部狀態(tài)轉(zhuǎn)換
  • -h : 打印此幫助
  • -i : 打印內(nèi)存緩存和許可證
  • -P <file> : 指定PID文件,只與-d選擇一起使用
  • -f <factor> : 塊大小生長因子,默認(rèn)值為1.25
  • -n <bytes> : 為鍵值標(biāo)志的最小空間,默認(rèn)為48
  • -L : 使用大內(nèi)存頁,增加的內(nèi)存頁大小可以減少TLB命中數(shù)提高性能
  • -D <char> : 使用<char>作為密鑰前綴和IDS之間的分隔符
  • -t <num> : 使用的線程數(shù),默認(rèn)為4
  • -R : 每個事件的最大請求數(shù)默認(rèn)為20
  • -C : 禁用CAS的使用
  • -b <num> : 設(shè)置積壓隊列限制默認(rèn)值1024
  • -B : 綁定協(xié)議——ASCII、二進(jìn)制或AUTO(默認(rèn))之一
  • -I : 重寫每個板頁的大小。調(diào)整最大項目大?。J(rèn)值:1MB,MI:1K,MAX:128M)
  • -S : 打開SASL認(rèn)證
  • -o : 逗號分隔的擴(kuò)展或?qū)嶒炦x項列表

上面如果用后臺啟動了之后無法關(guān)閉,可以先找到守護(hù)進(jìn)程的PID,然后kill掉:

$ ps -aux
$ kill -9 PID

開放防火墻:

$ firewall-cmd --permanent --add-port=11211/tcp
$ firewall-cmd --reload

安裝python-memcached模塊

直接使用pip安裝:

pip install python-memcached

第一次使用:

import memcache

mc = memcache.Client(['192.168.3.108:11211'], debug=True)
mc.set('k1', 'v1')
ret = mc.get('k1')
print(ret)

這里有個參數(shù),debug=True表示運行出現(xiàn)錯誤時,顯示錯誤信息,上線后移除該參數(shù)。
運行上面的代碼前先確認(rèn)啟動了服務(wù)端的Memcached,用如下的命令開啟吧:

$ memcache -u root -vv

此時,在運行上面的代碼,就可以進(jìn)行設(shè)置值和取值的操作了。

天生支持集群

python-memcached模塊原生支持集群操作。這里單講上面的生成memcache.Client實例的這條命令。
實例化的時候傳入的第一個參數(shù),是一個列表。既然是列表,就可以傳入多個,這樣是實現(xiàn)了集群的操作:

mc = memcache.Client(['192.168.3.108:11211', '192.168.3.109:11211', '192.168.3.110:11211'])

另外,列表中的元素可以是一個元組,元組的第一個元素就是上面的IP地址和端口,第二個元素是數(shù)字表示權(quán)重:

mc = memcache.Client([('192.168.3.108:11211', 1), ('192.168.3.109:11211', 3), ('192.168.3.110:11211', 4)])

根據(jù)算法將用戶要存的key轉(zhuǎn)換成一個數(shù)字,將數(shù)字和主機列表的長度求值,如此就知道該連接哪一臺主機了。加了權(quán)重值,就是增加這個主機在主機列表里出現(xiàn)的次數(shù)。

基本操作

這里操作的命令比較簡單,所以簡單了解一下有哪些命令可以操作就好了。

add
添加一條鍵值對,如果是已經(jīng)存在的key,會返回False:

res = mc.add('k2', 'v2')
print(res)  # 設(shè)置成功,返回True
res = mc.add('k2', 'value2')
print(res)  # 設(shè)置失敗,返回False

這里重復(fù)add同一個key,應(yīng)該是會產(chǎn)生異常的,不過應(yīng)該是被底層捕獲的,不會導(dǎo)致程序崩潰。如果開啟了debug,那么會把異常打印出來。

replace
修改某個key的值,如果key不存在,則異常:

mc.replace('k1', 'value1')

這里的異常和上面add的情況是一樣的。set操作就相當(dāng)于是 add + replace 。

set 和 set_multi
set : 設(shè)置一個鍵值對,如果key不存在,則創(chuàng)建,如果key存在,則修改
set_multi : 設(shè)置多個鍵值對,此時要傳入一個字典

res = mc.set('k1', 'v1')
print(res)  # 設(shè)置成功,會返回True
mc.set_multi({'k11': 'v11', 'k12': 'v12', 'k13': 'v13'})

set的時候可以直接傳數(shù)字,應(yīng)該是會自動幫我們傳成字符串保存的:

mc.set('n1', 100)
print(mc.get('n1'))

get 和 get_multi
get : 獲取一個鍵值對
get_multi : 獲取多個鍵值對,傳入一個列表,返回字典

items = mc.get_multi(['k11', 'k12', 'k13'])
print(items)

delete 和 delete_multi
delete : 刪除指定的一個鍵值對,可以刪除不存在的鍵值對
delete_multi : 刪除指定的多個鍵值對,如果key不存在,會異常

mc.delete('k1')
mc.delete_multi(['k11', 'k12', 'k13'])

append 和 prepend
append : 修改指定key的值,在該字符串后面追加內(nèi)容
prepend : 修改指定key的值,在該字符串前面插入內(nèi)容
在Memcached里只有一個數(shù)據(jù)格式,就是字符串,所以這里是對字符串的操作:

mc.set('s1', 'TEST')
print(mc.get('s1'))
mc.append('s1', ' after')
print(mc.get('s1'))
mc.prepend('s1', 'before ')
print(mc.get('s1'))

decr 和 incr
incr : 自增,將某個值增加N,默認(rèn)加1
decr : 自減,將某個值減少N,默認(rèn)減1
這里能操作的只能是能是數(shù)字形式的字符串,否則程序會拋出異常。這個異常應(yīng)該是客戶端計算是產(chǎn)生的,直接會導(dǎo)致程序崩潰:

mc.set('n1', '123')
print(mc.get('n1'))
mc.incr('n1')
print(mc.get('n1'))
mc.incr('n1', 100)
print(mc.get('n1'))

設(shè)置超時時間
上面的設(shè)置值的操作:set、 set_multi、add、replace,都是可以設(shè)置超時時間的。通過time參數(shù),單位是秒:

mc.set('k1', 'v1', time=2)
time.sleep(1)
print(mc.get('k1'))  # 返回設(shè)置的值,v1
time.sleep(1)
print(mc.get('k1'))  # 超時,返回None

gets 和 cas
這里提供的方法,是為了解決同時修改某個數(shù)據(jù)的時候,導(dǎo)致數(shù)據(jù)一致性問題。
比如A取出了某個值假設(shè)是1000,B也取出了這個值1000。A和B都要把數(shù)據(jù)減1然后回寫回去。此時A和B都會嘗試把999寫回去。這樣最終這個數(shù)字就不對了。應(yīng)該是A和B都把數(shù)字減少了1,此時最終的數(shù)值應(yīng)該是998。
用這里的gets和cas操作,就可以發(fā)生上面的問題。要讓這兩個命令有效果,需要在創(chuàng)建客戶端實例的時候再加一個參數(shù)cache_cas=True:

mc = memcache.Client(['192.168.3.108:11211'], debug=True, cache_cas=True)

下面是演示這種沖突情況的代碼:

# s2a.py
import memcache

mc = memcache.Client(['192.168.3.108:11211'], debug=True, cache_cas=True)  # 注意參數(shù)
mc.set('count', 1000)  # 設(shè)置一個默認(rèn)值

n = mc.gets('count')
input("%s>>>" % n)  # 獲取到值之后,先暫停
res = mc.cas('count', n-1)  # 把計算后的新的值寫回
print(res, mc.get('count'))

# s2b.py
import memcache

mc = memcache.Client(['192.168.3.108:11211'], debug=True, cache_cas=True)

n = mc.gets('count')
input("%s>>>" % n)
res = mc.cas('count', n-1)
print(res, mc.get('count'))

先運行s2a.py,然后再運行s2b.py。此時2個程序都會在獲取到值之后暫停。隨便讓一個程序繼續(xù),寫回最新的數(shù)據(jù)。當(dāng)?shù)诙€程序?qū)懟氐臅r候就會發(fā)生錯誤,返回False。此時你就知道這里的操作失敗了。知道失敗了,就再重新執(zhí)行一個gets和cas的操作應(yīng)該就可以了。失敗返回如下:

1000>>>
MemCached: while expecting 'STORED', got unexpected response 'EXISTS'
False 999

這里應(yīng)該是一個樂觀鎖的實現(xiàn)??傊褪莄as之后檢查返回值判斷是否成功。如果不成功,表示之前執(zhí)行的時候有沖突,那么再執(zhí)行一次。
另外其實數(shù)字的加減,是不需要這樣做的。對于數(shù)字,使用decr 和 incr就不會發(fā)生上面的那種沖突的情況。不過如果是字符串操作,比如在前后添加內(nèi)容,就無法避免了。另外或許處理數(shù)字還有其他更復(fù)雜的情況,只是還沒遇到。

網(wǎng)頁題目:Python自動化開發(fā)學(xué)習(xí)-Memcached
新聞來源:http://www.muchs.cn/article42/gehsec.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站關(guān)鍵詞優(yōu)化、全網(wǎng)營銷推廣網(wǎng)站營銷、域名注冊網(wǎng)站設(shè)計公司

廣告

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

商城網(wǎng)站建設(shè)