Memcached 涉及以下內容
1,Memcached 基本概念
2,Memcached 安裝
3,Memcached 基本命令
4,Memcached 原理
5,stats 命令
6,stats items 數據項統計
7,stats settings 查看設置
8,stats slabs區塊統計
9,Memcached的數據存儲過程
Memcached 是什么
Memcached 是一款開源的,高性能的,分布式的內存對象緩存系統。
Memcached能干什么
最主要的功能就是:在內存中緩存數據,以減輕數據庫負載。
它通過在內存中緩存數據和對象來減少讀取數據庫的次數,從而提高動態數據庫驅動網站的速度。
Memcached 特點
- 在內存中以key/value 對存儲,性能好。
- 協議簡單(基于文本行),功能強大。
- 基于libevent的事件處理,無阻塞通信,對內存讀寫數據非常快。
- 基于客戶端的分布式,服務器多個Memcached之間不互相通信。
- 服務器端以守護進程運行,客戶端可以用任何語言來編寫。
安裝Memcached服務器端
1. 需要安裝libevent.
- libevent是個程序庫,它將Linux的epoll、BSD類操作系統的kqueue等事件 處理功能封裝成統一的接口,具有很高的性能。
下載 wget https://github.com/libevent/libevent/releases/download/release-2.1.8-stable/libevent-2.1.8-stable.tar.gz
解壓 tar vxf libevent-2.1.8-stable.tar.gz
.configure --prefix=/usr/common/libevent
make & make install
2. 安裝Memcached.
下載 wget http://www.memcached.org/files/memcached-1.4.37.tar.gz
解壓 tar vxf memcached-1.4.37.tar.gz
./configure --prefix=/usr/common/memcached --with-libevent=/usr/common/libevent/
make & make install
Memcached 基本命令
啟動服務器端
cd /usr/common/memcached
./memcached -d -m 100 -u root -l 71.0.0.29 -p 2223 -c 256 -P /usr/pid/memcached.pid
-d 選項是啟動一個守護進程 。
-m 是分配給Memcache使用的內存數量,單位是MB,這里是100MB 。
-u 是運行Memcache的用戶,這里是root 。
-l 是監聽的服務器IP地址,這里指定了服務器的IP地址71.0.0.29。
-p 是監聽的端口,這里設置了2223,最好是1024以上的端口 。
-c 選項是最大運行的并發連接數,默認是1024,這里設置了256 。
-P 是設置保存Memcache的pid文件,這里是保存在 /usr/pid/memcached.pid。
常用的還有幾個需要了解:
-f 塊大小增長因子,默認是1.25。
-n 最小分配空間, key+value+flags 默認是 65byte。
-I 每個slab page的大小。
-v/-vv 詳細顯示工作時各種參數。
關閉Memcached
ps aux|grep memcached
kill pid
Memcached的基本原理
Memcached的基本的工作原理
Memcached 是以守候程序的方式運行與一個或者多個服務器,
隨時等待客戶端的鏈接。通過啟動Memcached服務器端,配置相應的監聽
IP,端口內存大小等參數,客戶端通過制定的服務器端IP,將數據以key/value的方式存儲。
Memcached 的兩階段哈希
客戶端存取數據時,首先參考節點列表計算出key的哈希值(階段一 哈希),
進而選中一個節點;客戶端將請求發送給選中的節點,然后Memcached節點通過
一個內部的哈希算法(階段二哈希),進行真正的數據(item)存取。
Memcached 的服務器客戶端通信并不適用復雜的xml等格式,而使用簡單的基于
文本行的協議。因此,通過telnet 也能在Memcached 上保存,取得數據。
Memcached的操作命令
- 命令行連接 Memcached
telnet 71.0.0.29 2223
- 標準協議:Memcached所有的標準協議包含在item執行命令過程中,一個item包含兩行:
第一行:Key flags expirationTime Bytes
Key:Key 用于查找緩存值 。
Flags:一個32位的標志值,客戶機使用它存儲關于鍵值對的額外信息 。
Expirationtime:在緩存中保存鍵值對的時長(以秒為單位,0表示永遠) 。
Bytes:在緩存中存儲的字節數。
第二行:Value:存儲的值(始終位于第二行)
noreply:可以在命令的第一行后面加入noreply,以避免在處理交互命令的時候,等待服
務端的返回
向Memcached寫入值
常用命令有:set、add、replace、append、prepend、cas,delete
1:set:用于向緩存添加新的鍵值對,如果鍵已經存在,則之前的值將被替換。
2:add:僅當緩存中不存在鍵時,add命令才會向緩存中添加一個鍵值對,如果緩存中已經存
在鍵,則之前的值將仍然保持,服務器響應 NOT_STORED。3:replace:僅當鍵已經存在時,replace命令才會替換緩存中的鍵。如果緩存中不存在鍵,
服務器響應NOT_STORED。4:append:是在現有緩存數據后面新增數據。如果key不存在,服務器響應 NOT_STORED。
5:prepend:是在現有緩存數據前面新增數據。如果key不存在,服務器響應 NOT_STORED。
6:cas(Check And Set ):檢查和更新,只有從你讀取數據后,別人沒有更新這 個數據,才能夠正確保存。就是版本控制,通常和gets配合使用。
獲取數據的命令有:get 、 gets get用來獲取數據,gets獲取的是數據+版本號。7: 刪除數據的命令:delete。
set k1 0 0 5
lihao
STORED
add s2 0 0 5
lihao
STORED
命令stats
stats命令:查詢服務器的運行狀態和其他內部數據。
- pid :服務器進程 ID。
- uptime :服務器運行時間,單位秒。
- time:服務器當前的 UNIX 時間 。
- version :服務器的版本號 5:libevent:libevent的版本。
- pointer_size :服務器操作系統位數。
- rusage_user:該進程累計的用戶時間
- rusage_system:該進程累計的系統時間
- curr_connections : 當前連接數
- total_connections :服務器啟動后總連接數
- connection_structures :服務器分配的連接結構的數量。
- reserved_fds:內部使用的miscfds 數量。
- cmd_get :獲取請求數量
- get_hits :獲取成功的總次數,命中次數
- get_misses :獲取失敗的總次數
- cmd_set :存儲請求數量
- delete_misses :刪除失敗次數
- delete_hits :刪除命中
- bytes :已用緩存空間
- bytes_read :總共獲取的數據量
- bytes_written :總寫入數量數
- limit_maxbytes :總允許寫入的數據量,和分配的內存有關
- accepting_conns:允許的總連接數
- curr_items: 當前緩存 item 數量
- total_items :從服務啟動后,總的存儲緩存 item 數量
- evictions :通過刪除 item 釋放內存的次數
這些數據隱含的幾個基本關系:
1,緩存命中率 = get_hits/cmd_get * 100%
2, get_misses的數字加上get_hits應該等于cmd_get。
3,flush_all命令:使內存中所有的item失效。加入參數則表示在N秒后失效。這個操作并不
會真的釋放內存空間,而是標志所有的item為失效。
4,version 命令 : 查看版本。
stats settings 查看設置
- maxbytes:最大字節數限制,0無限制
- maxconns:允許最大連接數
- growth_factor:增長因子
- chunk_size:key+value+flags大小
- reqs_per_event: 最大IO吞吐量(每event)
stats items 數據項統計
- number: 該slab中對象數,不包含過期對象。
- age:LRU隊列中最老對象的過期時間.
- evicted: LRU釋放對象數.
- evicted_nonzero: 設置了非0時間的LRU釋放對象數。
- evicted_time: 最后一次LRU秒數,監控頻率。
stats slabs區塊統計
- chunk_size: chunk大小,byte
- chunks_per_page: 每個page的chunk數量
- total_pages : page數量
- total_chunks: chunk數量*page數量
- get_hits: 命中數。
- used_chunks: 已被分配的chunk數
- free_chunks:剩余chunk數
- total_chunks: 總chunk數 used_chunks+free_chunks
- mem_requested: 請求存儲的字節數。
- active_slabs:slab數量。
- total_malloced:總內存數量。
被浪費內存數=((total_chunks或者used_chunks) * chunk_size) - mem_requested,如 果太大,需要調整factor。
Memcached的數據存儲
Memcached的數據存儲方式被稱為Slab Allocator,其基本方式是:
1:先把內存分成很多個Slab,這個大小是預先規定好的,以解決內存碎片的問題。
分配給Slab的內存空間被稱為Page,默認是1M。一個Slab下可以有多個Page。
2:然后把一個Page分成很多個chunk塊,chunk塊是用于緩存記錄的空間。Chunk的
大小是先有一個基本值,然后根據增長因子來增大。
3:slab class:內存區類別(48byte-1M),每個類別有一個slab classId
4:Memcached里面保存著slab內空閑的chunk列表,當收到要保存的item的時候,它
會根據item的大小,去選擇一個最合適的slab,然后找到空閑的chunk,把數據 存放進去。
新建Item分配內存過程
1:快速定位slab classid,先計算Item長度
key鍵長 + flag長度+value值長+65
如果>1MB,無法存儲丟棄。
取最小冗余的slab class
如:有48,96,120,存90會選擇96
2:按順序尋找可用chunk
(1)slot:檢查slab回收空間slot里是否有剩余chunk
delete:delete時標記到slot
exptime:get時檢查的過期對象標記到slot
(2)end_page_ptr:檢查page中是否有剩余chunk
(3)memory:內存還有剩余空間可以用于開辟新的slab
(4)LRU
Memcached的數據存儲方式的缺點:
由于chunk的大小是預先分配好的特定長度,因此如果數據不能完全填滿
chunk,那么剩余的空間就浪費了。
Lazy Expiration(延遲/惰性 過期)
Memcached不會監控記錄是否過期,而是在外部來獲取數據的時候,才檢查
記錄的時間戳,因此稱為Lazy Expiration。
LRU(Least Recently Used 最近最少使用)
當空間不足的時候,Memcached會優先使用已經過期的數據空間,如果還不
夠,那么就會把最近最少使用的對象的空間釋放出來使用。
懶惰刪除機制
刪除item對象時,不釋放內存,作刪除標記,指針放入slot回收插槽,下
次分配的時候直接使用。
要特別注意:Memcached的LRU不是全局的,而是針對slab的,可以說是區域性的。
相關文章
Memcached 安裝使用存儲
http://www.lxweimin.com/p/2b3c43c1778c
java 使用memcached以及spring 配置memcached
http://www.lxweimin.com/p/6f264bf5d9f9
memcached優化
http://www.lxweimin.com/p/789d208036f5