MEMORY USAGE仅返回单个key的字节数,不携带类型、编码等元信息,无法直接按数据类型聚合统计占比;需结合TYPE、SCAN、--bigkeys等命令及后处理才能实现分类分析。

MEMORY USAGE 本身不支持按数据类型分组统计,无法直接得出“hash 占比多少”这类汇总结果——它只查单个 key。 想知道各类数据结构的内存占比,得靠组合命令 + 后处理,不是一条命令能解决的事。
为什么不能直接用 MEMORY USAGE 统计类型占比
MEMORY USAGE key_name 只返回一个整数,比如 (integer) 12480,它不告诉你这个 key 是 hash 还是 zset,更不会自动归类、求和、算百分比。你拿它扫 10 万个 key,得到 10 万个数字,但没类型标签,根本没法聚合。
- 它不返回类型信息:必须先执行
TYPE key_name才知道是什么结构 - 它不支持通配符或批量:
MEMORY USAGE user:*会报错,只能逐个调用 - 对不存在的 key 返回
0,容易被当成“小 key”混进统计,拉低平均值 - 集群环境下,key 分布在不同节点,需手动路由,脚本复杂度陡增
真正可行的类型占比分析流程
用 redis-cli --bigkeys 快速筛出高频/大体积类型,再辅以 MEMORY USAGE 抽样验证,是生产环境最稳的路径:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 先跑
redis-cli --bigkeys -i 0.1(-i 控制扫描间隔,避免阻塞),它会按string/hash/list/set/zset分组,给出每类的样本数量、平均大小、最大大小 - 对报告中 “hash: 1245 keys, avg size 1.2MB, max 48MB” 这类条目,挑几个 top key(如
user:profile:1001)执行MEMORY USAGE user:profile:1001,确认是否真占这么大 - 若发现某类(如
zset)平均值虚高,大概率是编码切换导致:用ZCARD和ZRANGE key 0 0 WITHSCORES看元素长度,再对比MEMORY USAGE结果,判断是否因跳变式扩容(比如从 ziplist 切到 skiplist) - 想导出全量类型分布?得写脚本遍历
KEYS *(仅限开发环境!)或用SCAN游标 +TYPE+MEMORY USAGE三连发,但要注意client-output-buffer-limit,大结果可能断连
INFO memory + 类型命令交叉验证更高效
比起硬扫所有 key,多数时候用内置指标 + 类型专属命令更快定位偏差点:
- 看
INFO memory中的used_memory_human,再执行DBSIZE:如果 DBSIZE 是 50 万,但used_memory_human已达 8GB,基本可断定存在大 hash/zset - 对 hash:用
HLEN key查字段数,再MEMORY USAGE key;若 HLEN=100 但 MEMORY USAGE > 10MB,说明单个 field value 极长或已转 dict 编码 - 对 list:
LLEN key若为 10 万,MEMORY USAGE key却只有 2MB,大概率还是 ziplist;若超过 15MB,基本已是 linkedlist(每个 node 额外 ~64 字节) - 注意
redis-cli --stat实时观察used_memory波动,配合业务操作,能快速锁定哪类操作引发内存突增
真正难的不是查单个 key,而是把零散的 MEMORY USAGE 结果和类型、编码、过期状态、内存对齐这些隐性因素串起来。一次 MEMORY USAGE 返回 80 字节,可能是 65 字节字符串 + 15 字节对齐填充;也可能是 4 字节 key 名 + 64 字节 value + redisObject 元数据 + lru 字段——不结合 DEBUG OBJECT(仅限测试)或 INFO memory 碎片率,根本没法归因。

















