1. 程式人生 > >總結memcache的原理和使用

總結memcache的原理和使用

【轉】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軟體的原理

memcache原始碼分析參考部落格

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

參考
mecache引數詳解參考,感謝

--------------------- 本文來自 逐夢如風-畢康 的CSDN 部落格 ,全文地址請點選:https://blog.csdn.net/cabing2005/article/details/52611475?utm_source=copy