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