memcache学习和分析
Memcached 特点
• 具有非常快的处理速度
• 缺乏认证以及安全管制,应将其放置在防火墙之后
• 重启后数据全部丢失
• 可以给数据设置有效期
• 适合使用大量低CPU的机器搭建集群
• 各节点之间各自独立
• 通过客户端一致性哈希等分布式算法实现数据线性扩展
memcached启动参数
• memcached -m 1024 -c 10240 -p 11211 -u root -vv
• -d 守护进程
-u <username> 运行Memcached的用户,仅当作为root运行时
• -p 指定端口号(默认11211)
• -m 指定最大使用内存大小(默认64MB)
• -t 线程数(默认4)
• -l 连接的IP地址, 默认是本机
• -M 内存耗尽时返回错误,而不是删除项
• -c 最大同时连接数,默认是1024
• -f 块大小增长因子,默认是1.25
• -n 最小分配空间,key+value+flags默认48
• -vv 详细信息(还打印客户端命令/响应)
• -I 重写每个数据页尺寸。调整数据项最大尺寸。
• -R 每个连接可以连续提交的命令数。
• -B 绑定协议,ascii, binary, auto(default)
以下是源码中各参数的注释:
"a:" /* access mask for unix socket */ "A" /* enable admin shutdown commannd */ "p:" /* TCP port number to listen on */ "s:" /* unix socket path to listen on */ "U:" /* UDP port number to listen on */ "m:" /* max memory to use for items in megabytes */ "M" /* return error on memory exhausted */ "c:" /* max simultaneous connections */ "k" /* lock down all paged memory */ "hiV" /* help, licence info, version */ "r" /* maximize core file limit */ "v" /* verbose */ "d" /* daemon mode */ "l:" /* interface to listen on */ "u:" /* user identity to run as */ "P:" /* save PID in file */ "f:" /* factor? */ "n:" /* minimum space allocated for key+value+flags */ "t:" /* threads */ "D:" /* prefix delimiter? */ "L" /* Large memory pages */ "R:" /* max requests per event */ "C" /* Disable use of CAS */ "b:" /* backlog queue limit */ "B:" /* Binding protocol */ "I:" /* Max item size */ "S" /* Sasl ON */ "F" /* Disable flush_all */ "o:" /* Extended generic options */
统计命令
• stats 进程信息、连接数、请求数、网络流量、LRU
• stats slabs 显示各个slab的信息,包括chunk的大小、数目、使用情况等
• stats items 显示各个slab中item的数目,及最老item最后一次访问距离现在的秒数等
• stats settings 显示进程启动的参数信息
以下是内存分配的slab和page和chunk的关系:
这张图片里面涉及了slab_class、slab、page、chunk四个概念,它们之间的关系是:
1、MemCache将内存空间分为一组slab
2、每个slab下又有若干个page,每个page默认是1M,如果一个slab占用100M内存的话,那么这个slab下应该有100个page
3、每个page里面包含一组chunk,chunk是真正存放数据的地方,同一个slab里面的chunk的大小是固定的
4、有相同大小chunk的slab被组织在一起,称为slab_class
MemCache内存分配的方式称为allocator,slab的数量是有限的,几个、十几个或者几十个,这个和启动参数的配置相关。
MemCache中的value过来存放的地方是由value的大小决定 的,value总是会被存放到与chunk大小最接近的一个slab中,比如slab[1]的chunk大小为80字节、slab[2]的chunk大小 为100字节、slab[3]的chunk大小为128字节(相邻slab内的chunk基本以1.25为比例进行增长,MemCache启动时可以用-f指定这个比例), 那么过来一个88字节的value,这个value将被放到2号slab中。放slab的时候,首先slab要申请内存,申请内存是以page为单位的, 所以在放入第一个数据的时候,无论大小为多少,都会有1M大小的page被分配给该slab。申请到page后,slab会将这个page的内存按 chunk的大小进行切分,这样就变成了一个chunk数组,最后从这个chunk数组中选择一个用于存储数据。
如果这个slab中没有chunk可以分配了怎么办,如果MemCache启动没 有追加-M(禁止LRU,这种情况下内存不够会报Out Of Memory错误),那么MemCache会把这个slab中最近最少使用的chunk中的数据清理掉,然后放上最新的数据。针对MemCache的内存 分配及回收算法,总结三点:
1、MemCache的内存分配chunk里面会有内存浪费,88字节的value分配在128字节(紧接着大的用)的chunk中,就损失了30字节,但是这也避免了管理内存碎片的问题
2、MemCache的LRU算法不是针对全局的,是针对slab的
3、应该可以理解为什么MemCache存放的value大小是限制的,因为一个新数据过来,slab会先以page为单位申请一块内存,申请的内存最多就只有1M,所以value大小自然不能大于1M了.
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步