最新消息:

Memcached专题二、内存管理和状态监测

Linux ipcpu 2783浏览

Memcached专题二、内存管理和状态监测.md

一、Memcached内存管理

Memcached默认情况下采用了名为Slab Allocator的机制分配、管理内存。在该机制出现以前,内存的分配是通过对所有记录简单地进行malloc和free来进行的。但是,这种方式会导致内存碎片,加重操作系统内存管理器的负担,最坏的情况下,会导致操作系统比memcached进程本身还慢。Slab Allocator就是为解决该问题而诞生的。
当我们使用命令 set(key, value) 向 memcached 插入一条数据, memcached 内部是如何组织数据呢?

1.1、把数据组装成 item

memcached 接受到客户端的数据后, 把数据组装成 item, item 的格式如下:
wpid-3e923ff0f36d3b40ab5d37a608495909_58d8807f-dee1-4a06-9ec9-626ad2ee5659.jpg
1.2、为 item 分配存储空间
把数据组装成 item 之前, 必须为 item 分配存储空间, memcached 不是直接从操作系统分配内存的, memcached内部使用了类似内存池的东西, 即slab机制, 来管理内存. 内存的分配和回收都交给 slab 子系统实现. 所以我们先理解slab, 再回过头来看如何为 item 分配存储空间.

1.3、使用 slab 管理内存

memcached 中, 内存的分配和回收, 都是通过 slab 实现的, slab机制相当于内存池机制, 实现从操作系统分配一大块内存, 然后 memcached 自己管理这块内存, 负责分配与回收. 接下来我们详细剖析 slab 机制.
1.3.1 关于 slabclass
像一般的内存池一样, 从操作系统分配到一大块内存后, 为了方便管理, 把这大块内存划分为各种大小的 chunk,chunk的大小按照一定比例逐渐递增, 如下图所示:
wpid-3e923ff0f36d3b40ab5d37a608495909_5a28a450-1bac-4c6b-9705-c326b641a743.jpg
从 slab 分配内存的时候, 根据请求内存块的大小, 找到大小最合适的 chunk 所在的 slabclass, 然后从这个
slabclass 找空闲的 chunk 分配出去. 所谓最合适就是指 chunk 的大小能够满足要求, 而且碎片最小.
如下图所示:
wpid-3e923ff0f36d3b40ab5d37a608495909_c252400c-83e8-4472-b304-ea12111dbdb3.jpg
这种分配方式的缺点是存在内存碎片, 例如, 将 100字节的 item 存储到一个 128 字节的 chunk, 就有 28 字节的内存浪费, 如下图所示:
wpid-3e923ff0f36d3b40ab5d37a608495909_6a58f9a0-aaba-4c80-83f6-33ae2a20acd5.jpg
1.3.2 slabclass 的内部实现
slabclass 是由 chunk size 确定的, 同一个 slabclass 内的 chunk 大小都一样, 每一个 slabclass 要负责管理一些内存, 初始时, 系统为每个 slabclass 分配一个 slab, 一个 slab 就是一个内存块, 其大小等于 1M. 然后每个slabclass 再把 slab 切分成一个个 chunk, 算一下, 一个 slab 可以切分得到 1M/chunk_size 个chunk.
1.3.3 内存回收
当 memcached 没有足够的内存使用时, 必须选择性地回收一些 item, 回收采用 LRU 算法, 这就需要维护
一个按照最近访问时间排序的 LRU 队列. 在 memcached 中,每个 slabclass 维护一个链表, 比如 slabclass[i] 的链表头指针为 heads[i], 尾指针为 tails[i],
已分配出去的 item 都存储在链表中. 而且链表中 item 按照最近访问时间排序, 这样一些链表相当于LRU 队列.

二、Memcached状态监测

理解了上面的内存模型,我们就可以更好的查看系统参数状态了。

2.1、查看slab状态

使用memcached的创造者Brad写的名为memcached-tool的Perl脚本,可以方便地获得slab的使用情况。

  1. [root@QYER-1-17 ~]#memcached-tool 10.1.1.17:11211
  2. # Item_Size Max_age Pages Count Full? Evicted Evict_Time OOM
  3. 1 96B 1136s 17 185673 yes 183745 2837 0
  4. 2 120B 1087s 11 96118 yes 87761 1464 0
  5. 3 152B 1082s 14 96572 yes 87307 1469 0
  6. 5 240B 1087s 22 96118 yes 87763 1464 0
  7. 7 384B 0s 1 0 no 0 0 0
  8. 8 480B 0s 1 0 no 0 0 0

常用各列的含义为:

含义
# slab class编号
Item_Size Chunk大小
Max_age LRU内最旧的记录的生存时间
pages 分配给Slab的页数
Count Slab内的记录数
Full? Slab内是否含有空闲chunk
Evicted 从LRU中移除未过期item的次数
Evict_Time 最后被移除未过期缓存的时间

2.2、查看memcached当前状态

登录到memcached中,可以通过stats命令查看当前状态

  1. [root@QYER-1-17 ~]#telnet 10.1.1.17 11211
  2. Trying 10.1.1.17...
  3. Connected to 10.1.1.17.
  4. Escape character is '^]'.
  5. stats
  6. STAT pid 1242
  7. STAT uptime 289875
  8. STAT time 1482846932
  9. STAT version 1.4.4
  10. STAT pointer_size 64
  11. STAT rusage_user 913.752088
  12. STAT rusage_system 2416.142690
  13. STAT curr_connections 5
  14. STAT total_connections 17494139
  15. STAT connection_structures 9
  16. STAT cmd_get 1536160
  17. STAT cmd_set 17379219
  18. STAT cmd_flush 0
  19. STAT get_hits 1536159
  20. STAT get_misses 1
  21. STAT delete_misses 114840
  22. STAT delete_hits 2
  23. STAT incr_misses 0
  24. STAT incr_hits 0
  25. STAT decr_misses 0
  26. STAT decr_hits 0
  27. STAT cas_misses 0
  28. STAT cas_hits 0
  29. STAT cas_badval 0
  30. STAT auth_cmds 0
  31. STAT auth_errors 0
  32. STAT bytes_read 1301727208
  33. STAT bytes_written 363323660
  34. STAT limit_maxbytes 26937917440
  35. STAT accepting_conns 1
  36. STAT listen_disabled_num 0
  37. STAT threads 4
  38. STAT conn_yields 0
  39. STAT bytes 2159462219
  40. STAT curr_items 17379217
  41. STAT total_items 17379219
  42. STAT evictions 0
  43. END

常见参数分析如下
wpid-3e923ff0f36d3b40ab5d37a608495909_58084d51-0a83-4939-aa6a-3e48cb872d5f.jpg

2.3、查看memcached当前设置 (stats settings)

wpid-3e923ff0f36d3b40ab5d37a608495909_d8cfc6b2-4ea2-415e-836d-0a2914e95854.jpg
 

2.4、查看item的数据统计(stats items)

wpid-3e923ff0f36d3b40ab5d37a608495909_01896aae-23f4-4463-804f-77bd2ea1a7e2.jpg
2.5、查看slab统计数据(stats slabs)
wpid-3e923ff0f36d3b40ab5d37a608495909_be49b2d0-3faf-48c3-865a-5db408775551.jpg
被浪费内存数=(total_chunks * chunk_size) - mem_requested
如果太大,需要调整factor

三、参考资料

http://charlee.li/memcached-002.html
http://kenby.iteye.com/blog/1423989
《Memcached内存分析、调优、集群》刘中兵 搜狐TPC
.

转载请注明:IPCPU-网络之路 » Memcached专题二、内存管理和状态监测