memcache基础知识

memcached的内存存储机制

 Memcached默认情况下采用了名为Slab Allocator的机制分配、管理内存。在该机制出现以前,内存的分配是通过对所有记录简单地进行malloc和free来进行的。但是,这种方式会导致内存碎片,加重操作系统内存管理器的负担,最坏的情况下,会导致操作系统比memcached进程本身还慢。Slab Allocator就是为解决该问题而诞生的。

      Slab Allocator的基本原理是按照预先规定的大小,将分配的内存以page为单位,默认情况下一个page是1M,可以通过-I参数在启动时指定,分割成各种尺寸的块(chunk), 并把尺寸相同的块分成组(chunk的集合),如果需要申请内存时,memcached会划分出一个新的page并分配给需要的slab区域。page一旦被分配在重启前不会被回收或者重新分配,以解决内存碎片问题。

Page

分配给Slab的内存空间,默认是1MB。分配给Slab之后根据slab的大小切分成chunk。

Chunk

用于缓存记录的内存空间。

Slab Class

特定大小的chunk的组。

      Memcached并不是将所有大小的数据都放在一起的,而是预先将数据空间划分为一系列slabs,每个slab只负责一定范围内的数据存储。memcached根据收到的数据的大小,选择最适合数据大小的slab。memcached中保存着slab内空闲chunk的列表,根据该列表选择chunk,然后将数据缓存于其中。

      如图所示,每个slab只存储大于其上一个slab的size并小于或者等于自己最大size的数据。例如:100字节大小的字符串会被存到slab2(88-112)中,每个slab负责的空间是不等的,memcached默认情况下下一个slab的最大值为前一个的1.25倍,这个可以通过修改-f参数来修改增长比例。

      Slab Allocator解决了当初的内存碎片问题,但新的机制也给memcached带来了新的问题。chunk是memcached实际存放缓存数据的地方,这个大小就是管理它的slab的最大存放大小。每个slab中的chunk大小是一样的,如上图所示slab1的chunk大小是88字节,slab2是112字节。由于分配的是特定长度的内存,因此无法有效利用分配的内存。例如,将100字节的数据缓存到128字节的chunk中,剩余的28字节就浪费了。这里需要注意的是chunk中不仅仅存放缓存对象的value而且保存了缓存对象的key,expire time, flag等详细信息。所以当set 1字节的item,需要远远大于1字节的空间存放。

memcached在启动时指定 Growth Factor因子(通过-f选项), 就可以在某种程度上控制slab之间的差异。默认值为1.25。

slab的内存分配具体过程如下:

      Memcached在启动时通过-m参数指定最大使用内存,但是这个不会一启动就占用完,而是逐步分配给各slab的。如果一个新的数据要被存放,首先选择一个合适的slab,然后查看该slab是否还有空闲的chunk,如果有则直接存放进去;如果没有则要进行申请,slab申请内存时以page为单位,无论大小为多少,都会有1M大小的page被分配给该slab(该page不会被回收或者重新分配,永远都属于该slab)。申请到page后,slab会将这个page的内存按chunk的大小进行切分,这样就变成了一个chunk的数组,再从这个chunk数组中选择一个用于存储数据。若没有空闲的page的时候,则会对改slab进行LRU,而不是对整个memcache进行LRU。

1、stats :显示服务器信息、统计数据等

pid:守护进程的id

uptime:进程已经运行的时间,以秒为单位

time:当前的unix时间

version:服务器版本

pointer_size:操作系统默认的指针长度

rusage_user:进程累计的user time(秒:毫秒)

rusage_system:进程累计的system time(秒:毫秒)

curr_items:当前的items数量

total_items:进程启动开始存储过的items数量

bytes:当前用于存储items的byte数量

curr_connections:打开的连接数量

total_connections:进程启动开始打开过的连接数量

connection_structures:服务分配的连接结构数量

cmd_get:提取请求次数

cmd_set:存储请求次数

get_hits:get命中次数

get_misses:get未命中次数

evictions:为了添加新item而回收的合法item数量

bytes_read:服务从network读取的byte数量

bytes_written:服务写入network的byte数量

limit_maxbytes:服务可使用的用于存储数据的最大值

threads:被请求的工作线程数量

2、stats reset  清空统计数据

  1. stats reset
  2. RESET
  3.  
  4. stats
  5. STAT pid 2305
  6. STAT uptime 40596
  7. STAT time 1294906749
  8. STAT version 1.2.6
  9. STAT pointer_size 64
  10. STAT rusage_user 1.671745
  11. STAT rusage_system 2.803573
  12. STAT curr_items 86642
  13. STAT total_items 0
  14. STAT bytes 29865212
  15. STAT curr_connections 14
  16. STAT total_connections 0
  17. STAT connection_structures 16
  18. STAT cmd_get 0
  19. STAT cmd_set 0
  20. STAT get_hits 0
  21. STAT get_misses 0
  22. STAT evictions 0
  23. STAT bytes_read 9
  24. STAT bytes_written 14
  25. STAT limit_maxbytes 67108864
  26. STAT threads 4
  27. END

3、stats malloc 显示内存分配数据

  1. stats malloc
  2. STAT arena_size 708608
  3. STAT free_chunks 4
  4. STAT fastbin_blocks 0
  5. STAT mmapped_regions 65
  6. STAT mmapped_space 66752512
  7. STAT max_total_alloc 0
  8. STAT fastbin_space 0
  9. STAT total_alloc 614032
  10. STAT total_free 94576
  11. STAT releasable_space 94272
  12. END

4、stats maps  是把/proc/self/maps的数据显示出来。

如果远程攻击者连接到了memcached的TCP端口(默认11211)并发布了stats maps命令,Memcached就会直接将/proc/self/maps的输出管道传输给客户端。这可能导致泄漏所分配内存区域的地址。

  1. stats maps
  2. 00365000-00378000 r-xp 00000000 08:01 149004     /lib/libnsl-2.3.4.so
  3. 00378000-00379000 r--p 00012000 08:01 149004     /lib/libnsl-2.3.4.so
  4. 00379000-0037a000 rw-p 00013000 08:01 149004     /lib/libnsl-2.3.4.so
  5. 0037a000-0037c000 rw-p 0037a000 00:00 0
  6. 0070c000-00722000 r-xp 00000000 08:01 147620     /lib/ld-2.3.4.so
  7. 00722000-00723000 r--p 00015000 08:01 147620     /lib/ld-2.3.4.so
  8. 00723000-00724000 rw-p 00016000 08:01 147620     /lib/ld-2.3.4.so
  9. 00726000-0084c000 r-xp 00000000 08:01 147621     /lib/tls/libc-2.3.4.so
  10. 0084c000-0084e000 r--p 00125000 08:01 147621     /lib/tls/libc-2.3.4.so
  11. 0084e000-00850000 rw-p 00127000 08:01 147621     /lib/tls/libc-2.3.4.so
  12. 00850000-00852000 rw-p 00850000 00:00 0
  13. 00891000-0089f000 r-xp 00000000 08:01 147624     /lib/tls/libpthread-2.3.4.so
  14. 0089f000-008a0000 r--p 0000d000 08:01 147624     /lib/tls/libpthread-2.3.4.so
  15. 008a0000-008a1000 rw-p 0000e000 08:01 147624     /lib/tls/libpthread-2.3.4.so
  16. 008a1000-008a3000 rw-p 008a1000 00:00 0
  17. 008a5000-008b4000 r-xp 00000000 08:01 147628     /lib/libresolv-2.3.4.so
  18. 008b4000-008b5000 r--p 0000f000 08:01 147628     /lib/libresolv-2.3.4.so
  19. 008b5000-008b6000 rw-p 00010000 08:01 147628     /lib/libresolv-2.3.4.so
  20. 008b6000-008b8000 rw-p 008b6000 00:00 0
  21. 009c7000-009cf000 r-xp 00000000 08:01 149005     /lib/tls/librt-2.3.4.so
  22. 009cf000-009d0000 r--p 00007000 08:01 149005     /lib/tls/librt-2.3.4.so
  23. 009d0000-009d1000 rw-p 00008000 08:01 149005     /lib/tls/librt-2.3.4.so
  24. 009d1000-009db000 rw-p 009d1000 00:00 0
  25. 00d28000-00d3b000 r-xp 00000000 08:02 688822     /usr/local/sinawap/lib/libevent-1.4.so.2.0.0
  26. 00d3b000-00d3c000 rw-p 00013000 08:02 688822     /usr/local/sinawap/lib/libevent-1.4.so.2.0.0
  27. 00d3c000-00d3d000 rw-p 00d3c000 00:00 0
  28. 08048000-08052000 r-xp 00000000 08:02 905179     /usr/local/sinawap/bin/memcached
  29. 08052000-08053000 rw-p 0000a000 08:02 905179     /usr/local/sinawap/bin/memcached
  30. 08053000-08056000 rw-p 08053000 00:00 0
  31. 08499000-084ba000 rw-p 08499000 00:00 0
  32. b7f64000-b7fa8000 rw-p b7f64000 00:00 0
  33. bff9f000-c0000000 rw-p bff9f000 00:00 0
  34. ffffe000-fffff000 r-xp 00000000 00:00 0
  35.  

5、stats size

6、stats slabs

详细介绍stats slabs

  1. STAT 1:chunk_size 88
  2. STAT 1:chunks_per_page 11915
  3. STAT 1:total_pages 1
  4. STAT 1:total_chunks 11915
  5. STAT 1:used_chunks 11915
  6. STAT 1:free_chunks 0
  7. STAT 1:free_chunks_end 11914
  8. STAT active_slabs 1
  9. STAT total_malloced 1048520
  10. END

chunk_size:每个chunk(块)使用的空间数量,一个item存储到一个近似大小的chunk中

chunk_per_page:每page存在的chunk数量,slabs是按页(page)分配的,一页一般为1M,每个slab(也即每页)又划分为若干chunk,这里涉及到memcached的内存管理,这里不多解释,可以参考后面的附文。

total_pages:该slabclass分配到的page数量

total_chunks:该slabclass拥有的chunk数量

used_chunks:已经分配给item的chunk数量(不一定已经装填了item)

free_chunks:尚未分配给item的chunk数量,或者由delete释放的chunk

free_chunks_end:slabclass中最后一页的自由块数量,即该slabclass尚有多少自由块可以用来装填item

active_slabs:已分配的slabclass数量

total_malloced:已分配给slab page的内存数量

7、stats items 显示各个slab中item的数目和最老item的年龄(最后一次访问距离现在的秒数)stats detail [on|off|dump]

设置或者显示详细操作记录

参数为on,打开详细操作记录

参数为off,关闭详细操作记录

参数为dump,显示详细操作记录(每一个键值get、set、hit、del的次数)

  1. stats items dump
  2. STAT items:1:number 7
  3. STAT items:1:age 23124
  4. STAT items:1:evicted 0
  5. STAT items:1:outofmemory 0
  6. .........
  7. END

8、stats cachedump slab_id limit_num   显示某个slab中的前limit_num个key列表

显示格式如下:ITEM key_name [ value_length b; expire_time|access_time s]其中,memcached 1.2.2及以前版本显示的是  访问时间(timestamp) 1.2.4以上版本,包括1.2.4显示 过期时间(timestamp)

如果是永不过期的key,expire_time会显示为服务器启动的时间

  1. stats cachedump 7 2
  2. ITEM copy_test1 [250 b; 1207795754 s]
  3. ITEM copy_test [248 b; 1207793649 s]stats slabs

显示各个slab的信息,包括chunk的大小、数目、使用情况等

9、stats detail dump  ( stats detail  [on|off|dump]  )

    1. PREFIX copy_test2 get 1 hit 1 set 0 del 0
    2. PREFIX copy_test1 get 1 hit 1 set 0 del 0
    3. PREFIX cpy get 1 hit 0 set 0 del 0
原文地址:https://www.cnblogs.com/dim2046/p/6255095.html