memcached 的 stats slabs 命令用于查看 每个 slab class 的内存分配和使用情况 ,是分析 内存碎片、slab 分布、chunk 大小、页面分配 的核心工具。
命令格式
stats slabs
输出字段详解
示例输出
STAT 1:chunk_size 104
STAT 1:chunks_per_page 10084
STAT 1:total_pages 1
STAT 1:total_chunks 10084
STAT 1:used_chunks 850
STAT 1:free_chunks 9234
STAT 1:free_chunks_end 9234
STAT 1:mem_requested 68232
STAT 1:get_hits 12500
STAT 1:cmd_set 900
STAT 1:delete_hits 10
STAT 1:incr_hits 0
STAT 1:decr_hits 0
STAT 1:cas_hits 0
STAT 1:cas_badval 0
STAT 1:touch_hits 0
...
STAT 2:chunk_size 136
...
STAT active_slabs 12
STAT total_malloced 125829120
END
字段说明(按 slab 分类)
字段 说明 <id>:chunk_size该 slab 中每个 chunk 的字节大小 (固定) <id>:chunks_per_page每页(默认 1MB)能容纳的 chunk 数量 <id>:total_pages为该 slab 分配的 内存页数 (1 page = 1MB) <id>:total_chunkstotal_pages × chunks_per_page<id>:used_chunks当前 正在使用的 chunk 数 (即存储了 item) <id>:free_chunks空闲但已分配 的 chunk 数(可立即使用)<id>:free_chunks_endLRU 尾部可回收的 chunk 数(包含过期 item) <id>:mem_requested所有 item 实际请求的内存总和 (不含 overhead) <id>:get_hits从该 slab 读取成功的次数 <id>:cmd_set向该 slab 写入的次数 <id>:delete_hits删除命中次数 <id>:incr_hits / decr_hits自增/自减命中 <id>:cas_hitsCAS 操作成功次数 <id>:cas_badvalCAS 失败(值已变)次数 <id>:touch_hitstouch 命令命中次数
全局统计字段
字段 说明 active_slabs当前 正在使用的 slab class 数量 total_mallocedMemcached 总共向系统申请的内存字节数 (≈ 所有 slab 页面总和)
配合 stats items 使用
命令 作用 stats slabs查看 内存分配结构 (chunk 大小、页面数) stats items查看 item 数量、年龄、驱逐
推荐组合分析内存问题
实用分析技巧
1. 查看每个 slab 的实际内存占用
stats slabs | grep -E "^STAT [0-9]+:" | grep -v ":" | \
awk '
/:total_pages/ {pages[$1]=$2}
/:chunk_size/ {size[$1]=$2}
END {
for(s in pages) {
total_mb = pages[s] * 1024 * 1024 / 1024 / 1024;
printf "%s: %d pages × %d B/chunk = %.2f GB\n", s, pages[s], size[s], total_mb
}
}'
2. **找出“浪费严重”的 slab(碎片化高)
stats slabs | awk '
/:chunk_size/ {chunk=$1; size=$2}
/:used_chunks/ {used=$2}
/:total_chunks/ && $1==chunk {
total=$2;
if(total>0) {
util=used/total*100;
if(util<50) print chunk, "util:", util"%", "used:", used, "total:", total
}
}'
利用率 < 50% 表示该 slab 内存碎片严重
3. 找出“最热门”的 slab(高命中)
stats slabs | grep get_hits | sort -nk3 | tail -10
4. 计算总内存使用率
stats | grep -E "bytes|limit_maxbytes" | awk '
/limit_maxbytes/ {limit=$2/1024/1024}
/bytes/ {used=$2/1024/1024; printf "Memory: %.2f MB / %.2f MB (%.1f%%)\n", used, limit, used/limit*100}'
5. 完整分析脚本(推荐)
#!/bin/bash
echo "=== Memcached Slab Analysis ==="
echo
# 总体内存
stats | awk '
/limit_maxbytes/ {limit=$2}
/bytes/ {used=$2; printf "Total Memory: %.2f MB used / %.2f MB limit (%.1f%%)\n", used/1024/1024, limit/1024/1024, used/limit*100}
'
echo
# 每个 slab 详情
echo "SlabID ChunkSize Pages TotalMB UsedChunks Util% GetHits CmdSet"
stats slabs | grep -E "^STAT [0-9]+:" | grep -v "active_slabs\|total_malloced" | \
awk '
/:chunk_size/ {id=$1; gsub(/:.*/,"",id); chunk[id]=$2}
/:total_pages/ {pages[id]=$2}
/:used_chunks/ {used[id]=$2}
/:total_chunks/ {total[id]=$2}
/:get_hits/ {hits[id]=$2}
/:cmd_set/ {set[id]=$2}
END {
for(i in chunk) {
if(total[i]>0) {
mb = pages[i] / 1024.0;
util = used[i]/total[i]*100;
printf "%-6s %8d %6d %8.2f %10d %6.1f%% %8d %8d\n",
i, chunk[i], pages[i], mb, used[i], util, hits[i]+0, set[i]+0
}
}
}' | sort -k4,4n
常见问题与建议
症状 原因 建议 某 slab total_pages 很大但 used_chunks 很少 key 大小分布不均,落入大 chunk slab 优化 key/value 大小,尽量统一 free_chunks 很多但 OOM内存碎片,chunk 太大装不下新 item 重启或使用 -o modern 启用动态 slab active_slabs 过多(>50)key 大小差异太大 控制 value 大小,或使用一致性哈希分片 get_hits 集中在少数 slab热点数据集中 可拆分热点 key,或使用多实例
相关参数调优
参数 说明 建议 -f <factor>slab 增长因子(默认 1.25) 设为 1.1~1.2 减少碎片 -n <min_size>最小 chunk 大小(默认 48) 设为 88(包含 key+value+overhead) -o modern启用新 slab 分配器(推荐) 减少碎片,支持动态调整
示例启动:
memcached -m 1024 -f 1.1 -n 88 -o modern
相关命令总结
命令 用途 stats总体运行状态 stats slabsslab 内存分配详情 stats itemsitem 数量、年龄、驱逐 stats sizes(已废弃) get <key>查看具体 item 所在 slab
官方文档
https://github.com/memcached/memcached/wiki/Commands#stats-slabs
需要我帮你分析实际的 stats slabs 输出? 直接贴输出,我可以告诉你:
哪个 slab 浪费最多?
是否需要扩容?
如何优化 -f 和 -n 参数?