Memcached

Memcached 是一個高性能的分佈式內存對象緩存系統,用於動態Web應用以減輕數據庫負載。它經過在內存中緩存數據和對象來減小讀取數據庫的次數,從而提升動態、數據庫驅動網站的速度。Memcached基於一個存儲鍵/值對的hashmap。其守護進程(daemon )是用C寫的,可是客戶端能夠用任何語言來編寫,並經過memcached協議與守護進程通訊。python

Memcached安裝和基本使用

Memcached安裝:算法

1
2
3
4
5
6
7
8
wget http: / / memcached.org / latest
tar  - zxvf memcached - 1.x .x.tar.gz
cd memcached - 1.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  - - 10     - u root  - 10.211 . 55.4  - 12000  - 256  - / 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..

Python操做Memcached

安裝API服務器

1
2
python操做Memcached使用Python - memcached模塊
下載安裝:https: / / pypi.python.org / pypi / python - memcached

一、第一次操做併發

1
2
3
4
5
6
import  memcache
 
mc  =  memcache.Client([ '10.211.55.4:12000' ], debug = True )
mc. set ( "foo" "bar" )
ret  =  mc.get( 'foo' )
print  ret

Ps:debug = True 表示運行出現錯誤時,現實錯誤信息,上線後移除該參數。app

二、天生支持集羣分佈式

python-memcached模塊原生支持集羣操做,其原理是在內存維護一個主機列表,且集羣中主機的權重值和主機在列表中重複出現的次數成正比memcached

1
2
3
4
5
6
7
      主機    權重
     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 = "v1"),那麼要執行一下步驟:post

  • 根據算法將 k1 轉換成一個數字
  • 將數字和主機列表長度求餘數,獲得一個值 N( 0 <= N < 列表長度 )
  • 在主機列表中根據 第2步獲得的值爲索引獲取主機,例如:host_list[N]
  • 鏈接 將第3步中獲取的主機,將 k1 = "v1" 放置在該服務器的內存中

代碼實現以下:

1
2
3
mc  =  memcache.Client([( '1.1.1.1:12000' 1 ), ( '1.1.1.2:12000' 2 ), ( '1.1.1.3:12000' 1 )], debug = True )
 
mc. set ( 'k1' 'v1' )

三、add
添加一條鍵值對,若是已經存在的 key,重複執行add操做異常

1
2
3
4
5
6
7
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import  memcache
 
mc  =  memcache.Client([ '10.211.55.4:12000' ], debug = True )
mc.add( 'k1' 'v1' )
# mc.add('k1', 'v2') # 報錯,對已經存在的key重複添加,失敗!!!

四、replace
replace 修改某個key的值,若是key不存在,則異常

1
2
3
4
5
6
7
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import  memcache
 
mc  =  memcache.Client([ '10.211.55.4:12000' ], debug = True )
# 若是memcache中存在kkkk,則替換成功,不然一場
mc.replace( 'kkkk' , '999' )

五、set 和 set_multi

set            設置一個鍵值對,若是key不存在,則建立,若是key存在,則修改
set_multi   設置多個鍵值對,若是key不存在,則建立,若是key存在,則修改

1
2
3
4
5
6
7
8
9
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import  memcache
 
mc  =  memcache.Client([ '10.211.55.4:12000' ], debug = True )
 
mc. set ( 'key0' 'wupeiqi' )
 
mc.set_multi({ 'key1' 'val1' 'key2' 'val2' })

六、delete 和 delete_multi

delete             在Memcached中刪除指定的一個鍵值對
delete_multi    在Memcached中刪除指定的多個鍵值對

1
2
3
4
5
6
7
8
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import  memcache
 
mc  =  memcache.Client([ '10.211.55.4:12000' ], debug = True )
 
mc.delete( 'key0' )
mc.delete_multi([ 'key1' 'key2' ])

七、get 和 get_multi

get            獲取一個鍵值對
get_multi   獲取多一個鍵值對

1
2
3
4
5
6
7
8
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import  memcache
 
mc  =  memcache.Client([ '10.211.55.4:12000' ], debug = True )
 
val  =  mc.get( 'key0' )
item_dict  =  mc.get_multi([ "key1" "key2" "key3" ])

八、append 和 prepend

append    修改指定key的值,在該值 後面 追加內容
prepend   修改指定key的值,在該值 前面 插入內容

1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import  memcache
 
mc  =  memcache.Client([ '10.211.55.4:12000' ], debug = True )
# k1 = "v1"
 
mc.append( 'k1' 'after' )
# k1 = "v1after"
 
mc.prepend( 'k1' 'before' )
# k1 = "beforev1after"

九、decr 和 incr  

incr  自增,將Memcached中的某一個值增長 N ( N默認爲1 )
decr 自減,將Memcached中的某一個值減小 N ( N默認爲1 )

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([ '10.211.55.4:12000' ], debug = True )
mc. set ( 'k1' '777' )
 
mc.incr( 'k1' )
# k1 = 778
 
mc.incr( 'k1' 10 )
# k1 = 788
 
mc.decr( 'k1' )
# k1 = 787
 
mc.decr( 'k1' 10 )
# k1 = 777

十、gets 和 cas

如商城商品剩餘個數,假設改值保存在memcache中,product_count = 900
A用戶刷新頁面從memcache中讀取到product_count = 900
B用戶刷新頁面從memcache中讀取到product_count = 900

若是A、B用戶均購買商品

A用戶修改商品剩餘個數 product_count=899
B用戶修改商品剩餘個數 product_count=899

如此一來緩存內的數據便不在正確,兩個用戶購買商品後,商品剩餘仍是 899
若是使用python的set和get來操做以上過程,那麼程序就會如上述所示狀況!

若是想要避免此狀況的發生,只要使用 gets 和 cas 便可,如:

1
2
3
4
5
6
7
8
9
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import  memcache
mc  =  memcache.Client([ '10.211.55.4:12000' ], debug = True , cache_cas = True )
 
=  mc.gets( 'product_count' )
# ...
# 若是有人在gets以後和cas以前修改了product_count,那麼,下面的設置將會執行失敗,剖出異常,從而避免非正常數據的產生
mc.cas( 'product_count' "899" )

Ps:本質上每次執行gets時,會從memcache中獲取一個自增的數字,經過cas去修改gets的值時,會攜帶以前獲取的自增值和memcache中的自增值進行比較,若是相等,則能夠提交,若是不想等,那表示在gets和cas執行之間,又有其餘人執行了gets(獲取了緩衝的指定值), 如此一來有可能出現非正常數據,則不容許修改。

Memcached 真的過期了嗎?

相關文章
相關標籤/搜索