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了.

原文地址:https://www.cnblogs.com/phpzhou/p/6113757.html