【转】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