總結memcache的原理和使用
阿新 • • 發佈:2018-12-07
【轉】https://blog.csdn.net/cabing2005/article/details/52611475
大綱
memcache是什麼
memcache伺服器的配置
php中memcache的使用
php中memcached擴充套件的常用的引數
memcache的監控
memcached的原理
memcached的分散式演算法一致hash
memcache
分散式k-v資料庫
memcached伺服器的配置
memcached的常用的引數配置
-m 指定快取所使用的最大記憶體容量,單位是Megabytes,預設是64MB -u 只有以root身份執行時才指定該引數 -d 以daemon的形式執行 -l 指定監聽的地址 -p 指定監聽的TCP埠號,預設是11211 -t 指定執行緒數,預設是4個 -h 列印幫助資訊 -c 最大同時連線數,預設是1024. -U 指定監聽的UDP埠號,預設是11211 -M 記憶體耗盡時顯示錯誤,而不是刪除項 一開始說的“-d”引數需要進行進一步的解釋 -d install 安裝memcached -d uninstall 解除安裝memcached -d start 啟動memcached服務 -d restart 重啟memcached服務 -d stop 停止memcached服務 -d shutdown 停止memcached服務
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
更詳細的說明
-p <num> 監聽的TCP埠(預設: 11211) -U <num> 監聽的UDP埠(預設: 11211, 0表示不監聽) -s <file> 用於監聽的UNIX套接字路徑(禁用網路支援) -a <mask> UNIX套接字訪問掩碼,八進位制數字(預設:0700) -l <ip_addr> 監聽的IP地址。(預設:INADDR_ANY,所有地址) -d 作為守護程序來執行 -r 最大核心檔案限制 -u <username> 設定程序所屬使用者。(只有root使用者可以使用這個引數) -m <num> 所有slab class可用記憶體的上限,以MB為單位。(預設:64MB) (譯者注:也就是分配給該memcached例項的記憶體大小。) -M 記憶體用光時報錯。(不會刪除資料) -c <num> 最大併發連線數。(預設:1024) -k 鎖定所有記憶體頁。注意你可以鎖定的記憶體上限。 試圖分配更多記憶體會失敗的,所以留意啟動守護程序時所用的使用者可分配的記憶體上限。 (不是前面的 -u <username> 引數;在sh下使用命令"ulimit -S -l NUM_KB"來設定。) -v 提示資訊(在事件迴圈中列印錯誤/警告資訊。) -vv 詳細資訊(還列印客戶端命令/響應) -vvv 超詳細資訊(還列印內部狀態的變化) -h 列印這個幫助資訊並退出 -i 列印memcached和libevent的許可 -P <file> 儲存程序ID到指定檔案,只有在使用 -d 選項的時候才有意義 -f <factor> 不同slab class裡面的chunk大小的增長倍率。(預設:1.25) (譯者注:每個slab class裡面有相同數量個slab page,每個slab page裡面有chunk,且在當前slab class內的chunk大小固定。 而不同slab class裡的chunk大小不一致,具體差異就是根據這個引數的倍率在增長,直到分配的記憶體用盡。) -n <bytes> chunk的最小空間(預設:48) (譯者注:chunk資料結構本身需要消耗48個位元組,所以一個chunk實際消耗的記憶體是n+48。) -L 嘗試使用大記憶體頁(如果可用的話)。提高記憶體頁尺寸可以減少"頁表緩衝(TLB)"丟失次數,提高執行效率。 為了從作業系統獲得大記憶體頁,memcached會把全部資料項分配到一個大區塊。 -D <char> 使用 <char> 作為字首和ID的分隔符 這個用於按字首獲得狀態報告。預設是":"(冒號) 如果指定了這個引數,則狀態收集會自動開啟;如果沒指定,則需要用命令"stats detail on"來開啟。 -t <num> 使用的執行緒數(預設:4) -R 每個連線可處理的最大請求數 -C 禁用CAS -b 設定後臺日誌佇列的長度(預設:1024) -B 繫結協議 - 可能值:ascii,binary,auto(預設) -I 重寫每個資料頁尺寸。調整資料項最大尺寸
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
php使用memcache
php可以通過memcached擴充套件使用memcache快取資料
快取資料的基本操作add,set,get,replace,delete 具體的可以去看 手冊
$mc = new Memcached('mc');
$mc->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true);
//設定keyhash演算法
$mc->setOption(Memcached::OPT_HASH,Memcached::HASH_DEFAULT);
//壓縮資料
$mc->setOption(Memcached::OPT_COMPRESSION,true);
//設定伺服器hash演算法 預設採用餘數分散式hash 採用一致性hash
$mc->setOption(Memcached::OPT_DISTRIBUTION, Memcached::DISTRIBUTION_CONSISTENT);
//過期時間為1秒
$mc->setOption(Memcached::OPT_CONNECT_TIMEOUT,1000);
$mc->addServers(array(
array('127.0.0.1',11211),
));
$key = "abc";
$mc->set($key, 123,86400);
$mc->increment($key);
var_dump($mc->get($key));
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
memcached 擴充套件的常用引數
Memcached::OPT_COMPRESSION
開啟或關閉壓縮功能。當開啟的時候,item的值超過某個閾值(當前是100bytes)時,會首先對值進行壓縮然後儲存,並 在獲取該值時進行解壓縮然後返回,使得壓縮對應用層透明。
型別: boolean, 預設: TRUE.
Memcached::OPT_SERIALIZER
指定對於非標量值進行序列化的序列化工具。可用的值有Memcached::SERIALIZER_PHP和Memcached::SERIALIZER_IGBINARY。後者僅在memcached配置時開啟 --enable-memcached-igbinary選項並且 igbinary擴充套件被載入時才有效。
型別: integer, 預設: Memcached::SERIALIZER_PHP.
Memcached::SERIALIZER_PHP
預設的PHP序列化工具(即serialize方法)。
Memcached::SERIALIZER_IGBINARY
» igbinary序列化工具。它將php的資料結構 儲存為緊密的二進位制形式,在時間和空間上都有所改進。
Memcached::SERIALIZER_JSON
JSON序列化,需要 PHP 5.2.10以上。
Memcached::OPT_PREFIX_KEY
可以用於為key建立“域”。這個值將會被作為每個key的字首,它不能長於128個字元, 並且將會縮短最大可允許的key的長度。這個字首僅僅用於被儲存的元素的key,而不會用於伺服器key。
型別: string, 預設: "".
Memcached::OPT_HASH
指定儲存元素key使用的hash演算法。可用的值是Memcached::HASH_*系列的常量。 每種hash演算法都有它的優勢和劣勢,在你不瞭解或不確定哪種演算法對你更有利時,請使用預設值。
型別: integer, 預設: Memcached::HASH_DEFAULT
Memcached::HASH_DEFAULT
預設的(Jenkins one-at-a-time)元素key hash演算法
Memcached::HASH_MD5
md5元素key hash演算法。
Memcached::HASH_CRC
CRC元素key hash演算法。
Memcached::HASH_FNV1_64
FNV1_64元素key hash演算法。
Memcached::HASH_FNV1A_64
FNV1_64A元素key hash演算法。
Memcached::HASH_FNV1_32
FNV1_32元素key hash演算法。
Memcached::HASH_FNV1A_32
FNV1_32A元素key hash演算法。
Memcached::HASH_HSIEH
Hsieh元素key hash演算法。
Memcached::HASH_MURMUR
Murmur元素key hash演算法。
Memcached::OPT_DISTRIBUTION
指定元素key分佈到各個伺服器的方法。當前支援的方法有餘數分步法合一致性hash演算法兩種。一致性hash演算法提供 了更好的分配策略並且在新增伺服器到叢集時可以最小化快取丟失。
型別: integer, 預設: Memcached::DISTRIBUTION_MODULA.
Memcached::DISTRIBUTION_MODULA
餘數分佈演算法。
Memcached::DISTRIBUTION_CONSISTENT
一致性分佈演算法(基於libketama).
Memcached::OPT_LIBKETAMA_COMPATIBLE
開啟或關閉相容的libketama類行為。當開啟此選項後,元素key的hash演算法將會被設定為md5並且分佈演算法將會 採用帶有權重的一致性hash分佈。這一點非常有用因為其他基於libketama的客戶端(比如python,urby)在同樣 的服務端配置下可以透明的訪問key。
Note:
如果你要使用一致性hash演算法強烈建議開啟此選項,並且這個選項可能在未來的釋出版中被設定為預設開啟。
型別: boolean, 預設: FALSE.
Memcached::OPT_BUFFER_WRITES
開啟或關閉I/O快取。開啟I/O快取會導致儲存命令不實際傳送而是儲存到緩衝區中。任意的檢索資料操作都會導致 快取中的資料被髮送到遠端服務端。退出連線或關閉連線也會導致快取資料被髮送到遠端服務端。
型別: boolean, 預設: FALSE.
Memcached::OPT_BINARY_PROTOCOL
開啟使用二進位制協議。請注意這個選項不能在一個開啟的連線上進行切換。
型別: boolean, 預設: FALSE.
Memcached::OPT_NO_BLOCK
開啟或關閉非同步I/O。這將使得儲存函式傳輸速度最大化。
型別: boolean, 預設: FALSE.
Memcached::OPT_TCP_NODELAY
開啟或關閉已連線socket的無延遲特性(在某些幻境可能會帶來速度上的提升)。
型別: boolean, 預設: FALSE.
Memcached::OPT_SOCKET_SEND_SIZE
socket傳送緩衝的最大值。
型別: integer, 預設: 根據不同的平臺/核心配置不同
Memcached::OPT_SOCKET_RECV_SIZE
socket接收緩衝的最大值。
型別: integer, 預設: 根據不同的平臺/核心配置不同
Memcached::OPT_CONNECT_TIMEOUT
在非阻塞模式下這裡設定的值就是socket連線的超時時間,單位是毫秒。
型別: integer, 預設: 1000.
Memcached::OPT_RETRY_TIMEOUT
等待失敗的連線重試的時間,單位秒。
型別: integer, 預設: 0.
Memcached::OPT_SEND_TIMEOUT
socket傳送超時時間,單位毫秒。在這種情況下您不能使用非阻塞I/O,這將使得您仍然有資料會發送超時。
型別: integer, 預設: 0.
Memcached::OPT_RECV_TIMEOUT
socket讀取超時時間,單位毫秒。在這種情況下您不能使用非阻塞I/O,這將使得您仍然有資料會讀取超時。
型別: integer, 預設: 0.
Memcached::OPT_POLL_TIMEOUT
poll連線超時時間,單位毫秒。
型別: integer, 預設: 1000.
Memcached::OPT_CACHE_LOOKUPS
開啟或禁用DNS查詢快取。
型別: boolean, 預設: FALSE.
Memcached::OPT_SERVER_FAILURE_LIMIT
指定一個伺服器連線的失敗重試次數限制。在達到此數量的失敗重連後此伺服器將被從伺服器池中移除。
型別: integer, 預設: 0.
Memcached::HAVE_IGBINARY
指示是否支援igbinary的序列化。
型別: boolean.
Memcached::HAVE_JSON
指示是否支援json的序列化。
型別: boolean.
Memcached::GET_PRESERVE_ORDER
一個用於 Memcached::getMulti()和 Memcached::getMultiByKey()的標記用以確保返回的key和請求的key順序保持一致。 不存在的key將會得到一個NULL值。
Memcached::RES_SUCCESS
操作成功。
Memcached::RES_FAILURE
某種方式的操作失敗。
Memcached::RES_HOST_LOOKUP_FAILURE
DNS查詢失敗。
Memcached::RES_UNKNOWN_READ_FAILURE
讀取網路資料失敗。
Memcached::RES_PROTOCOL_ERROR
錯誤的memcached協議命令。
Memcached::RES_CLIENT_ERROR
客戶端錯誤。
Memcached::RES_SERVER_ERROR
服務端錯誤。
Memcached::RES_WRITE_FAILURE
向網路寫資料失敗。
Memcached::RES_DATA_EXISTS
比較並交換值操作失敗(cas方法):嘗試向服務端儲存資料時由於自此連線最後一次取此key對應資料之後被改變導致失敗。
Memcached::RES_NOTSTORED
元素沒有被儲存,但並不是因為一個錯誤。這通常表明add(元素已存在)或replace(元素不存在)方式儲存資料失敗或者元素已經在一個刪除序列中(延時刪除)。
Memcached::RES_NOTFOUND
元素未找到(通過get或cas操作時)。
Memcached::RES_PARTIAL_READ
區域性網路資料讀錯誤。
Memcached::RES_SOME_ERRORS
在多key獲取的時候發生錯誤。
Memcached::RES_NO_SERVERS
伺服器池空。
Memcached::RES_END
結果集到結尾了。
Memcached::RES_ERRNO
系統錯誤。
Memcached::RES_BUFFERED
操作被快取。
Memcached::RES_TIMEOUT
操作超時。
Memcached::RES_BAD_KEY_PROVIDED
提供了無效的key。
Memcached::RES_CONNECTION_SOCKET_CREATE_FAILURE
建立網路socket失敗。
Memcached::RES_PAYLOAD_FAILURE
不能壓縮/解壓縮或序列化/反序列化值。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
memcache的監控和命中率
檢視看mc狀態
echo stats | nc xx.xx.xx.xx 11211
- 1
主要觀察:
快取命中率 = get_hits/cmd_get * 100%
查詢次數 STAT cmd_get 34251580
查詢命中次數 STAT get_hits 1840400
get未命中次數 STAT get_misses 32411180
快取資料的大小 STAT bytes 161860110
- 1
- 2
- 3
- 4
- 5
- 6
提高命中率的方案
其一,提高服務獲取的記憶體總量
其二,提高空間利用率,這實際上也是另一種方式的增加記憶體總量
其三,應用一級別上再來一次LRU
其四,對於整體命中率,可以採取有效的冗餘策略,減少分散式服務時某個server發生服務抖動的情況
- 1
- 2
- 3
- 4
stat返回的引數
STAT pid 20487 ## memcache 程序PID
STAT uptime 1977637 ## 自memcache啟動以來,伺服器執行秒數
STAT time 1461202739 ## 伺服器當前unix時間戳
STAT version 1.4.21 ## memcache 伺服器版本
STAT libevent 1.4.13-stable ## libevent 版本
STAT pointer_size 64 ## 架構(32 或 64 位)
STAT rusage_user 150.835069 ## 程序累計使用者時間
STAT rusage_system 249.086133 ## 程序累計系統時間
STAT curr_connections 10 ## 當前開啟連線數
STAT total_connections 5509 ## 自memcache啟動以來,開啟的連線總數
STAT connection_structures 11 ## 伺服器分配的連線結構數
STAT reserved_fds 40 ##
STAT cmd_get 8913248 ## 自memcache啟動以來,執行get命令總數
STAT cmd_set 123382 ## 自memcache啟動以來,執行set命令總數
STAT cmd_flush 0 ## 自memcache啟動以來,執行flush命令總數
STAT cmd_touch 0 ## 自memcache啟動以來,執行touch_all命令總數
STAT get_hits 8913074 ## 自memcache啟動以來,get命中次數
STAT get_misses 174 ## 自memcache啟動以來,get未命中次數
STAT delete_misses 0 ## 自memcache啟動以來,delete未命中次數
STAT delete_hits 0 ## 自memcache啟動以來,delete命中次數
STAT incr_misses 0 ## 自memcache啟動以來,incr未命中次數
STAT incr_hits 0 ## 自memcache啟動以來,incr命中次數
STAT decr_misses 0 ## 自memcache啟動以來,decr未命中次數
STAT decr_hits 0 ## 自memcache啟動以來,decr命中次數
STAT cas_misses 0 ## 自memcache啟動以來,cas未命中次數
STAT cas_hits 0 ## 自memcache啟動以來,cas命中次數
STAT cas_badval 0 ## 使用擦拭次數
STAT touch_hits 0 ## 自memcache啟動以來,touch命中次數
STAT touch_misses 0 ## 自memcache啟動以來,touch未命中次數
STAT auth_cmds 0 ##
STAT auth_errors 0 ##
STAT bytes_read 111225505 ## memcached伺服器從網路讀取的總的位元組數
STAT bytes_written 3621054898 ## memcached伺服器傳送到網路的總的位元組數
STAT limit_maxbytes 33554432 ## memcached服務快取允許使用的最大位元組數(分配的記憶體數)
STAT accepting_conns 1 ## 目前接受的連結數
STAT listen_disabled_num 0 ##
STAT threads 8 ## 被請求的工作執行緒的總數量
STAT conn_yields 0 ## 連線操作主動放棄數目
STAT hash_power_level 16 ##
STAT hash_bytes 524288 ##
STAT hash_is_expanding 0 ##
STAT malloc_fails 0 ##
STAT bytes 384154 ## 儲存item位元組數(當前儲存佔用的位元組數)
STAT curr_items 856 ## item個數(當前儲存的資料總數)
STAT total_items 123382 ## item總數(啟動以來儲存的資料總數)
STAT expired_unfetched 0 ##
STAT evicted_unfetched 0 ##
STAT evictions 0 ## LRU釋放的物件數目。為了給新的資料專案釋放空間,從快取移除的快取物件的數目。比如超過快取大小時根據LRU演算法移除的物件,以及過期的物件
STAT reclaimed 0 ## 已過期的資料條目來儲存新資料的數目
STAT crawler_reclaimed 0 ##
STAT lrutail_reflocked 0 ##
END
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
memcached軟體的原理
memcached是兩階段的雜湊的
Memcached的高效能源於兩階段雜湊(two-stage hash)結構。Memcached就像一個巨大的、儲存了很多<key,value>對的雜湊表。通過key,可以儲存或查詢任意的資料。 客戶端
可以把資料儲存在多臺memcached上。當查詢資料時,客戶端首先參考節點列表計算出key的雜湊值(階段一雜湊),進而選中一個節點;客戶端將請求傳送給選中的節點,然後
memcached節點通過一個內部的雜湊演算法(階段二雜湊),查詢真正的資料(item)並返回給客戶端。從實現的角度看,memcached是一個非阻塞的、基於事件的伺服器程式。
為了提高效能,memcached 中儲存的資料都儲存在memcached 內建的記憶體儲存空間中。由於資料僅存在於記憶體中,因此重啟memcached、重啟作業系統會導致全部資料消失。另外,內容容量達到指定值之後,就基於LRU(Least Recently Used)演算法自動刪除不使用的快取。memcached 本身是為快取而設計的伺服器,因此並沒有過多考慮資料的永久性問題
memcached 不互相通訊的分散式
memcached 儘管是“分散式”快取伺服器,但伺服器端並沒有分散式功能。各個
memcached 不會互相通訊以共享資訊。那麼,怎樣進行分散式呢?這完全取決於客戶端的實現。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
memcached的記憶體分配
記憶體分配的機制
Memcache使用了Slab Allocator的記憶體分配機制:按照預先規定的大小,將分配的記憶體分割成特定長度的塊,以完全解決記憶體碎片問題
Memcache的儲存涉及到slab,page,chunk三個概念
1.Chunk為固定大小的記憶體空間,預設為96Byte。
2.page對應實際的物理空間,1個page為1M。
3.同樣大小的chunk又稱為slab。
4.1 Slab Allocation 機制:整理記憶體以便重複使用
Slab Allocator 就是為解決該問題而誕生的
Slab Allocation 的原理相當簡單。將分配的記憶體分割成各種尺寸的塊
(chunk),並把尺寸相同的塊分成組(chunk 的集合)
slab allocator 還有重複使用已分配的記憶體的目的。也就是說,分配到的記憶體不會釋放,而是重複利用。
Slab Allocation 的主要術語
Page
分配給Slab 的記憶體空間,預設是1MB。分配給Slab 之後根據slab 的大小切分成chunk。
Chunk
用於快取記錄的記憶體空間。
Slab Class
特定大小的chunk 的組
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
記憶體使用的過程
memcached 根據收到的資料的大小,選擇最適合資料大小的slab,memcached 中儲存著slab 內空閒chunk 的列表,根據該列表選擇chunk,然後將資料緩存於其中
由於分配的是特定長度的記憶體,因此無法有效利用分配的記憶體。例如,將100 位元組的資料快取到128 位元組的chunk 中,剩餘的28位元組就浪費了
對於該問題目前還沒有完美的解決方案,但在文件中記載了比較有效的解決方案。就是說,如果預先知道客戶端傳送的資料的公用大小,或者僅快取大小相同的資料的情況下,只要使用適合資料大小的組的列表,就可以減少浪費。但是很遺憾,現在還不能進行任何調優,只能期待以後的版本了。但是,我們可以調節slab class 的大小的差別。接下來說明growth factor 選項。
- 1
- 2
- 3
- 4
- 5
slab記憶體倍增機制
4.4 使用Growth Factor進行調優
memcached 在啟動時指定Growth Factor 因子(通過f 選項),就可以在某種程度上控制slab 之間的差異。預設值為1.25。但是,在該選項出現之前,這個因子曾經固定為2,稱為“powers of 2”策略。
下面是啟動後的verbose 輸出:
slab class 1: chunk size 128 perslab 8192
slab class 2: chunk size 256 perslab 4096
slab class 3: chunk size 512 perslab 2048
slab class 4: chunk size 1024 perslab 1024
slab class 5: chunk size 2048 perslab 512
slab class 6: chunk size 4096 perslab 256
slab class 7: chunk size 8192 perslab 128
slab class 8: chunk size 16384 perslab 64
slab class 9: chunk size 32768 perslab 32
slab class 10: chunk size 65536 perslab 16
slab class 11: chunk size 131072 perslab 8
slab class 12: chunk size 262144 perslab 4
slab class 13: chunk size 524288 perslab 2
可見,從128 位元組的組開始,組的大小依次增大為原來的2 倍。這樣設定的問題是,slab 之間的差別比較大,有些情況下就相當浪費記憶體。因此,為儘量減少記憶體浪費,兩年前追加了growth factor 這個選項來看看現在的預設設定(f=1.25)時的輸出(篇幅所限,這裡只寫到第10 組):
slab class 1: chunk size 88 perslab 11915
slab class 2: chunk size 112 perslab 9362
slab class 3: chunk size 144 perslab 7281
slab class 4: chunk size 184 perslab 5698
slab class 5: chunk size 232 perslab 4519
slab class 6: chunk size 296 perslab 3542
slab class 7: chunk size 376 perslab 2788
slab class 8: chunk size 472 perslab 2221
slab class 9: chunk size 592 perslab 1771
slab class 10: chunk size 744 perslab 1409
可見,組間差距比因子為2 時小得多,更適合快取幾百位元組的記錄。從上面的輸出結果來看,可能會覺得有些計算誤差,這些誤差是為了保持位元組數的對齊而故意設定的。將memcached 引入產品,或是直接使用預設值進行部署時,最好是重新計算一下資料的預期平均長度,調整growth factor,以獲得最恰當的設定。記憶體是珍貴的資源,浪費就太可惜了。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
一個item佔用空間的計算
item佔用空間計算
*nsuffix = (uint8_t) snprintf(suffix, 40, " %d %d\r\n", flags, nbytes – 2); return sizeof(item) + nkey + *nsuffix + nbytes;
*nsuffix=" %d %d\r\n”的長度
如果ITEM_CAS標誌設定時,這裡有8位元組的資料
完整的item長度是鍵長+值長+字尾長+item結構大小(48位元組) + 8
item.length=56+key.lenght+value.length+字尾長
32位機器 item結構是32位元組
64位機器 itme結構是48位元組
memcache儲存的時候對key的長度有限制,php和C的最大長度都是250
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
memcache刪除資料
memcache刪除資料的方式
memcached 是快取,不需要永久的儲存到伺服器上,本章介紹memcache 的刪除機制
Memcached 不會釋放已經分配的記憶體,記錄過期之後,客戶端無法再看到這一條記錄,其儲存空間就可以利用。
Lazy Expiration
memcached 內部不會監視記錄是否過期,而是在get 時檢視記錄的時間戳,檢查記錄是否過期。
這種技術被稱為lazy(惰性)expiration。因此,memcached不會在過期監視上耗費CPU 時間
- 1
- 2
- 3
- 4
- 5
memcache過期刪除演算法LRU
5.2 LRU:從快取中有效刪除資料的原理
1.search->refcount == 0 && 已經過期的 刪除
2.tries = 50; // 最多嘗試50次 LRU佇列tail 查詢 search->refcount == 0 第一個 刪除
3. tries = 50; // 最多嘗試50次 LRU佇列tail 查詢search->refcount != 0 查詢時間(超過3小時)的item 第一個 刪除
memcached 會優先使用已超時的記錄的空間,但即使如此,也會發生追加新記錄時空間不足的情況,此時就要使用名為Least Recently Used(LRU)機制來分配空間。顧名思義,這是刪除“最近最少使用”的記錄的機制。因此,當memcached 的記憶體空間不足時(無法從slab class 獲取到新的空間時),就從最近未被使用的記錄中搜索,並將其空間分配給新的記錄。從快取的實用角度來看,該模型十分理想。不過,有些情況下LRU 機制反倒會造成麻煩。
- 1
- 2
- 3
- 4
- 5
memcache -M 記憶體用盡後返回錯誤
memcached 啟動時通過“M”引數可以禁止LRU,如下所示:
$ memcached -M –m 1024
啟動時必須注意的是,小寫的“m”選項是用來指定最大記憶體大小的。不指定具體數值則使用預設值64MB。
指定“M”引數啟動後,記憶體用盡時memcached 會返回錯誤。話說回來,memcached 畢竟不是儲存器,而是快取,所以推薦使用LRU
- 1
- 2
- 3
- 4
memcache 的分散式演算法[ 第一次雜湊時的演算法]
memcached 雖然稱為“分散式”快取伺服器,但伺服器端並沒有“分散式”功能。memcached 的分散式,則是完全由客戶端程式庫實現的。這種分散式是memcached 的最大特點。
一致雜湊慢,因為有更多的計算,某臺服務宕機的時候,只會丟失這臺伺服器上的資料。
餘數分散式演算法,某臺服務宕機的時候,只會丟失絕大部分的資料。
6.2 餘數分散式演算法
就是“根據伺服器臺數的餘數進行分散”。求得鍵的整數雜湊值,再除以伺服器臺數,根據其餘數來選擇伺服器
餘數演算法的缺點
餘數計算的方法簡單,資料的分散性也相當優秀,但也有其缺點。那就是當新增或移除伺服器時,快取重組的代價相當巨大。新增伺服器後,餘數就會產生鉅變,這樣就無法獲取與儲存時相同的伺服器,從而影響快取的命中。
- 1
- 2
- 3
6.3Consistent Hashing(一致雜湊)
知識補充:雜湊演算法,即雜湊函式。將任意長度的二進位制值對映為較短的固定長度的二進位制值,這個小的二進位制值稱為雜湊值。雜湊值是一段資料唯一且極其緊湊的數值表示形式。如果雜湊一段明文而且哪怕只更改該段落的一個字母,隨後的雜湊都將產生不同的值。要找到雜湊為同一個值的兩個不同的輸入,在計算上是不可能的,所以資料的雜湊值可以檢驗資料的完整性。一般用於快速查詢和加密演算法。(常見的有MD5,SHA-1)
簡單的說就是設定一個圓環,固定好每個伺服器點的位置,針對每個key都算出一個數字,找出比這個數字大的最大的點。
- 1
- 2
- 3
memcache使用中的一些注意事項
1. memcache已經分配的記憶體不會再主動清理。
2. memcache分配給某個slab的記憶體頁不能再分配給其他slab。
3. flush_all不能重置memcache分配記憶體頁的格局,只是給所有的item置為過期。
4. memcache最大儲存的item(key+value)大小限制為1M,這由page大小1M限制
5.由於memcache的分散式是客戶端程式通過hash演算法得到的key取模來實現,不同的語言可能會採用不同的hash演算法,同樣的客戶端程式也有可能使用相異的方法,因此在多語言、多模組共用同一組memcached服務時,一定要注意在客戶端選擇相同的hash演算法
6.啟動memcached時可以通過-M引數禁止LRU替換,在記憶體用盡時add和set會返回失敗
7.memcached啟動時指定的是資料儲存量,沒有包括本身佔用的記憶體、以及為了儲存資料而設定的管理空間。因此它佔用的記憶體量會多於啟動時指定的記憶體分配量,這點需要注意。
8.memcache儲存的時候對key的長度有限制,php和C的最大長度都是250
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
--------------------- 本文來自 逐夢如風-畢康 的CSDN 部落格 ,全文地址請點選:https://blog.csdn.net/cabing2005/article/details/52611475?utm_source=copy