Memcached 是一個高性能的分佈式內存對象緩存系統,用於動態Web應用以減輕數據庫負載。它經過在內存中緩存數據和對象來減小讀取數據庫的次數,從而提升動態、數據庫驅動網站的速度。Memcached基於一個存儲鍵/值對的hashmap。其守護進程(daemon )是用C寫的,可是客戶端能夠用任何語言來編寫,並經過memcached協議與守護進程通訊。
memcached在實現分佈式羣集部署時,memcached服務之間是不能進行通信的,分佈式也是經過客戶端的算法把數據保存在不一樣的memcached中。magent是一款開源的代理服務軟件,咱們能夠經過它來實現緩存數據的同步。magent還可使用keepalived來實現高可用。python
在linux下安裝mysql
安裝libevent
Libevent 是一個異步事件處理軟件函式庫,以 BSD 許可證釋出。Memcached 依賴 Libevent,所以必須先安裝 Libevent。linux
1 |
yum install libevent-devel |
安裝memcachedredis
1 2 3 4 5 6 |
cd /usr/local/src wget http://memcached.org/latest tar zxf memcached-1.5.7.tar.gz mv memcached-1.5.7 memcached cd memcached/ ./configure && make && make install |
1 |
memcached -d -u root |
啓動參數說明
memcached -d -m 10 -u root -l 127.0.0.1 -p 12000 -c 256 -P /tmp/memcache/logs/memcache.pid
-p 指定端口號(默認11211)
-m 指定最大使用內存大小(默認64MB)
-t 線程數(默認4)
-l 鏈接的IP地址, 默認是本機
-d 之後臺守護進程的方式啓動
-c 最大同時鏈接數,默認是1024
-P 制定memecache的pid文件
-h 打印幫助信息
啓動確認算法
1 2 3 4 5 6 |
[root@VM_0_4_centos memcached]# ps aux|grep memcache root 24421 0.0 0.0 413792 1080 ? Ssl 07:45 0:00 memcached -d -u root root 24436 0.0 0.0 112644 964 pts/0 R+ 07:45 0:00 grep --color=auto memcache [root@VM_0_4_centos memcached]# netstat -lntp|grep memcached tcp 0 0 0.0.0.0:11211 0.0.0.0:* LISTEN 24421/memcached tcp6 0 0 :::11211 :::* LISTEN 24421/memcached |
python訪問memcached須要安裝python-memcached模塊。sql
1 |
pip install python-memcached |
操做實例數據庫
1 2 3 4 5 |
import memcache mem = memcache.Client(["118.24.18.158:11211"]) mem.set("db", "oracle") print(mem.get("db")) #輸出結果:oracle |
另外,python-memcached模塊原生支持集羣操做,其原理是在內存中維護一個主機列表,且集羣中主機的權重值和主機在列表中重複出現的次數成正比。centos
1 2 3 4 |
主機IP 權重 1.1.1.1 1 1.1.1.2 2 1.1.1.3 1 |
那麼內存中主機列表爲:host_list = [「1.1.1.1」, 「1.1.1.2」,」1.1.1.2」,」1.1.1.3」,]
用戶若是要在內存中建立一個鍵值對(如:k1 = 「value1」),那麼要執行如下步驟:
根據算法將k1轉換成一個數字
將數字和主機列表長度求餘數,獲得一個值N(0 <= N < 長度)
在主機列表中根據第二步獲得的值爲索引獲取主機,例如: host_list[N]
鏈接將第三步中獲取的主機,將k1 = 「value1」 放置在該服務器的內存中
代碼以下:緩存
1 2 3 4 5 6 7 |
#!/usr/bin/env python3 #coding:utf8 import memcache mc = memcache.Client([('1.1.1.1:11211', 1), ('1.1.1.2:11211', 2),('1.1.1.3:11211',1)]) mc.set('k1','value1') ret = mc.get('k1') print (ret) |
None
。get_multi(keys)
一次獲取多個keys服務器
1 2 3 4 |
mem.set_multi({"db1": "oracle", "db2": "mysql"}) mem.set("db3", "memcache") print(mem.get("db1")) #輸出結果:oracle print(mem.get_multi(["db2", "db3"])) #輸出結果:{'db2': 'mysql', 'db3': 'memcache'} |
add(key, val)
在memcache中添加新的鍵值對。若已存在則返回False。
1 2 3 |
print(mem.add("db", "memcache")) #輸出結果:True print(mem.get("db")) #輸出結果:memcache print(mem.add("db", "memcache")) #輸出結果:False |
replace(key, val)
修改key的值爲val,若不存在則返回False。
1 2 3 4 |
mem.add("db", "memcache") print(mem.replace("db", "redis")) #輸出結果:True print(mem.get("db")) #輸出結果:redis print(mem.replace("db1", "redis")) #輸出結果:False |
delete(key)
刪除一個指定的key/value對。
delete_multi(keys)
刪除多個指定的key/value對。
1 2 3 4 |
mem.set_multi({"db1": "oracle", "db2": "mysql", "db3": "memcache"}) mem.delete("db1") mem.delete_multi(["db2", "db3"]) print(mem.get_multi(["db1", "db2", "db3"])) #輸出結果:{} |
append(key, val)
在指定key對應的value後面
追加內容。
前面
追加內容。stats
查看歷史操做
1 2 3 4 5 6 7 |
mem.set("db", "oracle") print(mem.get("db")) #輸出結果:oracle mem.append("db", " or mysql") print(mem.get("db")) #輸出結果:oracle or mysql mem.prepend("db", "redis or ") print(mem.get("db")) #輸出結果:redis or oracle or mysql print(mem.stats) #輸出結果:{'set': 1, 'get': 3, 'append': 1, 'prepend': 1} |
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 |
mem = memcache.Client(["118.24.18.158:11211"]) mem.set("count", "100") print(mem.get("count")) #輸出結果:100 print(mem.cas("count", "99")) #輸出結果:True print(mem.gets("count")) #輸出結果:99 |
gets和cas一塊兒使用,cas是check and set
操做。它僅噹噹前客戶端最後一次取值後,該key對應的值沒有被其餘客戶端修改的狀況下,纔可以將值寫入。