总结memcache的原理和使用

大纲

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服务

更详细的说明

    -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            重写每个数据页尺寸。调整数据项最大尺寸

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));

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
不能压缩/解压缩或序列化/反序列化值。

memcache的监控和命中率

查看看mc状态

echo stats | nc xx.xx.xx.xx 11211

主要观察:

缓存命中率 = get_hits/cmd_get * 100%

查询次数    STAT cmd_get 34251580
查询命中次数 STAT get_hits 1840400
get未命中次数 STAT get_misses 32411180
缓存数据的大小  STAT bytes 161860110  

提高命中率的方案

其一,提高服务获取的内存总量
其二,提高空间利用率,这实际上也是另一种方式的增加内存总量
其三,应用一级别上再来一次LRU
其四,对于整体命中率,可以采取有效的冗余策略,减少分布式服务时某个server发生服务抖动的情况

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

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 不会互相通信以共享信息。那么,怎样进行分布式呢?这完全取决于客户端的实现。

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 的组
内存使用的过程
    memcached 根据收到的数据的大小,选择最适合数据大小的slab,memcached 中保存着slab 内空闲chunk 的列表,根据该列表选择chunk,然后将数据缓存于其中

    由于分配的是特定长度的内存,因此无法有效利用分配的内存。例如,将100 字节的数据缓存到128 字节的chunk 中,剩余的28字节就浪费了

    对于该问题目前还没有完美的解决方案,但在文档中记载了比较有效的解决方案。就是说,如果预先知道客户端发送的数据的公用大小,或者仅缓存大小相同的数据的情况下,只要使用适合数据大小的组的列表,就可以减少浪费。但是很遗憾,现在还不能进行任何调优,只能期待以后的版本了。但是,我们可以调节slab class 的大小的差别。接下来说明growth factor 选项。
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,以获得最恰当的设置。内存是珍贵的资源,浪费就太可惜了。
一个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

memcache删除数据

memcache删除数据的方式
memcached 是缓存,不需要永久的保存到服务器上,本章介绍memcache 的删除机制
Memcached 不会释放已经分配的内存,记录过期之后,客户端无法再看到这一条记录,其存储空间就可以利用。
Lazy Expiration
memcached 内部不会监视记录是否过期,而是在get 时查看记录的时间戳,检查记录是否过期。
这种技术被称为lazy(惰性)expiration。因此,memcached不会在过期监视上耗费CPU 时间
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 机制反倒会造成麻烦。
memcache -M 内存用尽后返回错误
memcached 启动时通过“M”参数可以禁止LRU,如下所示:
$ memcached -M –m 1024
启动时必须注意的是,小写的“m”选项是用来指定最大内存大小的。不指定具体数值则使用默认值64MB。
指定“M”参数启动后,内存用尽时memcached 会返回错误。话说回来,memcached 毕竟不是存储器,而是缓存,所以推荐使用LRU
memcache 的分布式算法[ 第一次哈希时的算法]

memcached 虽然称为“分布式”缓存服务器,但服务器端并没有“分布式”功能。memcached 的分布式,则是完全由客户端程序库实现的。这种分布式是memcached 的最大特点。

一致哈希慢,因为有更多的计算,某台服务宕机的时候,只会丢失这台服务器上的数据。
余数分布式算法,某台服务宕机的时候,只会丢失绝大部分的数据。

6.2 余数分布式算法

就是“根据服务器台数的余数进行分散”。求得键的整数哈希值,再除以服务器台数,根据其余数来选择服务器
余数算法的缺点
余数计算的方法简单,数据的分散性也相当优秀,但也有其缺点。那就是当添加或移除服务器时,缓存重组的代价相当巨大。添加服务器后,余数就会产生巨变,这样就无法获取与保存时相同的服务器,从而影响缓存的命中。

6.3Consistent Hashing(一致哈希)

知识补充:哈希算法,即散列函数。将任意长度的二进制值映射为较短的固定长度的二进制值,这个小的二进制值称为哈希值。哈希值是一段数据唯一且极其紧凑的数值表示形式。如果散列一段明文而且哪怕只更改该段落的一个字母,随后的哈希都将产生不同的值。要找到散列为同一个值的两个不同的输入,在计算上是不可能的,所以数据的哈希值可以检验数据的完整性。一般用于快速查找和加密算法。(常见的有MD5,SHA-1)

简单的说就是设置一个圆环,固定好每个服务器点的位置,针对每个key都算出一个数字,找出比这个数字大的最大的点。

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   

参考
mecache参数详解参考,感谢

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Yaf 是一个高效的 PHP 框架,它支持多种缓存机制,其中之一便是 Memcache。下面以一个简单的示例来说明如何在 Yaf 中使用 Memcache。 首先,确保已经安装了 Memcache 扩展,并在 php.ini 文件中启用了该扩展。 接下来,在 Yaf 的配置文件中添加以下代码: ```php // application.ini [product] application.directory = APP_PATH "/application/" ; Memcache 缓存配置 cache.memcache.enable = true cache.memcache.server = "127.0.0.1" cache.memcache.port = 11211 cache.memcache.prefix = "yaf_" ``` 这里定义了一个名为 `cache.memcache` 的缓存配置,启用了 Memcache 缓存,并指定了 Memcache 服务器的地址、端口和缓存前缀。 接着,在 Yaf 的 Bootstrap 文件中添加以下代码: ```php // Bootstrap.php class Bootstrap extends Yaf_Bootstrap_Abstract { public function _initCache() { // 获取缓存配置 $config = Yaf_Application::app()->getConfig()->cache->memcache; // 初始化 Memcache $cache = new Memcache(); $cache->connect($config->server, $config->port); // 将 Memcache 实例注册到 Yaf 的全局注册表中 Yaf_Registry::set("cache", $cache); } } ``` 这里通过 Yaf 的 Bootstrap 机制来初始化 Memcache,将其实例注册到 Yaf 的全局注册表中,方便在整个应用程序中使用。 最后,可以在 Yaf 的控制器中使用 Memcache。例如: ```php // IndexController.php class IndexController extends Yaf_Controller_Abstract { public function indexAction() { // 从 Yaf 的全局注册表中获取 Memcache 实例 $cache = Yaf_Registry::get("cache"); // 尝试从缓存中获取数据 $data = $cache->get("example"); if ($data === false) { // 如果缓存中不存在,则从数据库或其他数据源获取数据 $data = "Hello, world!"; // 将数据存入缓存中 $cache->set("example", $data); } // 输出数据 echo $data; } } ``` 这里通过 Yaf 的全局注册表来获取在 Bootstrap 中注册的 Memcache 实例,尝试从缓存中获取数据,如果缓存中不存在,则从数据库或其他数据源获取数据,并将其存入缓存中。最后输出数据。 这样,就完成了在 Yaf 中使用 Memcache 的示例。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值