Python操作Memcached
Memcached是一個(gè)高性能的分布式內(nèi)存對(duì)象緩存系統(tǒng),用于動(dòng)態(tài)WEB應(yīng)用以減輕數(shù)據(jù)庫(kù)負(fù)載。它通過在內(nèi)存中緩存數(shù)據(jù)和對(duì)象來減少讀取數(shù)據(jù)庫(kù)的次數(shù),從而提高動(dòng)態(tài),數(shù)據(jù)庫(kù)網(wǎng)站的速度。Memcached基于一個(gè)存儲(chǔ)鍵/值對(duì)的hashmap。其守護(hù)進(jìn)程(daemon)是用C寫的,但是客戶端可以用任何語言來編程,并通過memcached協(xié)議與守護(hù)進(jìn)程通信。
?
Memcached安裝
- 服務(wù)端安裝memcached:
| 1 2 3 4 5 6 7 | 用wget 去http://memcached.org下載最新源碼 tar?-zxvf memcached-x.x.x.tar.gz cd memcached-x.x.x ./configure && make && make test && sudo make install PS:依賴libevent,需要提前安裝 yum install libevent-devel apt-get install libevent-dev |
- 啟動(dòng)memcached
| 1 2 3 4 5 6 7 8 9 10 | memcached?-d?-m?10?-u root?-l?0.0.0.0?-p?12000?-c?256?-P?/tmp/memcached.pid ? 參數(shù)說明: ????-d 是啟動(dòng)一個(gè)守護(hù)進(jìn)程 ????-m 是分配給Memcache使用的內(nèi)存數(shù)量,單位是MB ????-u 是運(yùn)行Memcache的用戶 ????-l 是監(jiān)聽的服務(wù)器IP地址 ????-p 是設(shè)置Memcache監(jiān)聽的端口,最好是1024以上的端口 ????-c 選項(xiàng)是最大運(yùn)行的并發(fā)連接數(shù),默認(rèn)是1024,按照你服務(wù)器的負(fù)載量來設(shè)定 ????-P 是設(shè)置保存Memcache的pid文件 |
- memcached命令
| 1 2 3 | 存儲(chǔ)命令:?set/add/replace/append/prepend/cas 獲取命令: get/gets 其他命令: delete/stats.. |
菜鳥教程:https://www.runoob.com/memcached/memcached-install.html
Python操作Memcached
安裝API
簡(jiǎn)單的操作示例:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #!/usr/bin/env python3 #coding:utf8 import?memcache #鏈接 mc?=?memcache.Client(['139.129.5.191:12000'], debug=True) #插入 mc.set("name",?"python") #讀取 ret?=?mc.get('name') print?(ret) ? # 輸出結(jié)果 python ? # debug=True表示運(yùn)行出現(xiàn)錯(cuò)誤時(shí),可以顯示錯(cuò)誤信息,正式環(huán)境可以不加 |
天生支持集群:
python-memcached模塊原生支持集群操作,其原理是在內(nèi)存中維護(hù)一個(gè)主機(jī)列表,且集群中主機(jī)的權(quán)重值和主機(jī)在列表中重復(fù)出現(xiàn)的次數(shù)成正比。
| 1 2 3 4 | 主機(jī)IP??????? 權(quán)重 1.1.1.1????????1 1.1.1.2????????2 1.1.1.3????????3 |
那么內(nèi)存中主機(jī)列表為:host_list = ["1.1.1.1", "1.1.1.2","1.1.1.2","1.1.1.3","1.1.1.3","1.1.1.3",]
用戶如果要在內(nèi)存中創(chuàng)建一個(gè)鍵值對(duì)(如:k1 = "value1"),那么要執(zhí)行以下步驟:
代碼如下:
| 1 2 3 4 5 6 7 | #!/usr/bin/env python3 #coding:utf8 import?memcache mc?=?memcache.Client([('1.1.1.1:12000',?1), ('1.1.1.2:12000',?2),('1.1.1.3:12000',3)]) mc.set('k1','value1') ret?=?mc.get('k1') print?(ret) |
?
基本memcached操作
- add?? ? ? ?添加一條鍵值對(duì),如果已經(jīng)存在的key,重復(fù)執(zhí)行add操作會(huì)出現(xiàn)異常
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #!/usr/bin/env python # -*- coding:utf-8 -*- import?memcache mc?=?memcache.Client(['0.0.0.0:12000']) mc.add('k1',?'v1') mc.add('k1',?'v2')?# 報(bào)錯(cuò),對(duì)已經(jīng)存在的key重復(fù)添加,失敗!!! 例如: ret1?=?mc.add('name','tom') print(refalse) ret2?=?mc.add('name','jack') print(retrue) 結(jié)果: False?#當(dāng)已經(jīng)存在key 那么返回false True??#如果不存在key???? 那么返回treue?? |
- replace?? ?replace修改某個(gè)key的值,如果key不存在,則異常
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #!/usr/bin/env python # -*- coding:utf-8 -*- import?memcache mc?=?memcache.Client(['0.0.0.0:12000']) mc.set('name','tom') re?=?mc.get('name') print(re) rereplace?=?mc.replace('name','jack') re?=?mc.get('name') print(rereplace,re) 結(jié)果: tom??#第一次賦值 True?jack?#如果存在key那么修改成功為yaoyao 返回True rereplace?=?mc.replace('name1','hahaha') re?=?mc.get('name1') print(rereplace,re) 結(jié)果: False?None?#如果不存在key,修改失敗,返回空值 |
- set 和 set_multi
set : 設(shè)置一個(gè)鍵值對(duì),如果Key不存在,則創(chuàng)建,如果key存在,則修改。
set_multi : 設(shè)置多個(gè)鍵值對(duì),如果key不存在,則創(chuàng)建,如果key存在,則修改。
| 1 2 3 4 5 6 7 8 9 10 11 12 | import?memcache mc?=?memcache.Client(['0.0.0.0:12000']) mc.set('name','tom') re?=?mc.get('name') print('set用法',re)?#設(shè)置一個(gè)鍵值對(duì) dic?=?{'name':'to,','age':'19','job':'IT'} mc.set_multi(dic)??#設(shè)置多個(gè)鍵值對(duì) #或者mc.set_multi({'name':'tom','age':'19','job':'IT'}) mcname?=?mc.get('name') mcage?=?mc.get('age') mcjob?=?mc.get('job') print('set_multi用法:',mcname,mcage,mcjob) |
- delete 和 delete_multi
delete : 在Memcached中刪除指定的一個(gè)鍵值對(duì)
delete_multi : 在Memcached中刪除指定多個(gè)鍵值對(duì)
| 1 2 3 4 5 6 7 8 | import?memcache mc?=?memcache.Client(['0.0.0.0:12000']) mc.set('name','tom') re?=?mc.get('name') print('存在',re) mc.delete('name') re?=?mc.get('name') print('刪除',re)??#刪除一個(gè)鍵值對(duì) |
- get 和 get_multi
get : 獲取一個(gè)鍵值對(duì)
get_multi : 獲取多個(gè)鍵值對(duì)
| 1 2 3 4 5 6 7 8 9 10 11 | #!/usr/bin/env python # -*- coding:utf-8 -*- import?memcache mc?=?memcache.Client(['0.0.0.0:12000']) mc.set('name','tom') re?=?mc.get('name') print('get',re)?????#獲取一個(gè)鍵值對(duì) dic?=?{'name':'to,','age':'19','job':'IT'} mc.set_multi(dic) regetmu=mc.get_multi(['name','age','job']) print('get_multi',re)?#獲取多個(gè)鍵值對(duì)的值 |
- append 和 prepend
append : 修改指定key的值,在該值后面追加內(nèi)容。
prepend : 修改指定key的值,在該值前面插入內(nèi)容。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import?memcache mc?=?memcache.Client(['0.0.0.0:12000']) mc.set('num','第一|') re?=?mc.get('num') print(re) mc.append('num','追加第二個(gè)')?#在第一后面追加 re?=?mc.get('num') print(re) mc.prepend('num','我是零個(gè)')??#在第一前面追加 re?=?mc.get('num') print(re) 結(jié)果: 第一| 第一|追加第二個(gè) 我是零個(gè)第一|追加第二個(gè) |
- decr 和 incr
?decr : 自減,將Memcached中的一個(gè)值增加N(N默認(rèn)為1)
?incr ?: 自增,將Memcached中的一個(gè)值減少N(N默認(rèn)為1)
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #!/usr/bin/env python # -*- coding:utf-8 -*- import?memcache mc?=?memcache.Client(['0.0.0.0:12000']) mc.set('num','1') re?=?mc.get('num') print('我是沒加過的值',re) mc.incr('num','9') re?=?mc.get('num') print('我是加上新增后的值',re) mc.decr('num','5') re?=?mc.get('num') print('我是減去的值',re) # 結(jié)果: 我是沒加過的值?1 我是加上新增后的值?10 是減去的值?5 |
- gets 和 cas
使用緩存系統(tǒng)共享數(shù)據(jù)資源就必然繞不開數(shù)據(jù)爭(zhēng)奪和臟數(shù)據(jù)(數(shù)據(jù)混亂)的問題。
假設(shè)商城某件商品的剩余個(gè)數(shù)保存在memcache中,product_count = 900
A用戶刷新頁面從memecache中讀取到product_count = 900
B用戶刷新頁面從memecache中讀取到product_count = 900
A,B用戶均購(gòu)買商品,并修改product_count的值
A修改后,product_count = 899
B修改后,product_count = 899
然而正確數(shù)字應(yīng)該是898,數(shù)據(jù)就混亂了。
如果想要避免這種情況的發(fā)生,則可以使用 ?gets 和 cas
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #!/usr/bin/env python # -*- coding:utf-8 -*- import?memcache mc?=?memcache.Client(['0.0.0.0:12000'],cache_cas=True) mc.set('count','10') reget?=?mc.get('count') print('件數(shù)',reget) regets?=?mc.gets('count') print(regets) # 如果有人在gets之后和cas之前修改了product_count,那么, 下面的設(shè)置將會(huì)執(zhí)行失敗,剖出異常,從而避免非正常數(shù)據(jù)的產(chǎn)生 recas?=?mc.cas('count','11') print(recas) regets?=?mc.gets('count') print('修改',regets) |
本質(zhì)上每次執(zhí)行g(shù)ets時(shí),會(huì)從memcache中獲取一個(gè)自增的數(shù)字,通過cas去修改gets的值時(shí),會(huì)攜帶之前獲取的自增和memcache中的自增值進(jìn)行比較,如果相等,則可以提交,如果不相等,那么表示在gets和cas執(zhí)行之間,又有其他人執(zhí)行了gets,則不允許修改。
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的Python操作Memcached的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 常见数据归一化的几种方法
- 下一篇: [RabbitMQ+Python入门经典