总结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

猜你喜欢

转载自blog.csdn.net/mw_nice/article/details/82864023