MEMORY USAGE 无法直接统计 String 类型占比,因为它仅返回单个 key 的字节数,不提供类型、编码、TTL 等元信息,且不支持通配符或批量查询,无法自动聚合计算各类型内存占比。

MEMORY USAGE 不能直接给出“String类型键的内存使用率”,它只返回单个 key 的字节数,不带类型标签,也没法自动聚合统计占比。想算出 String 类型占总内存多少,得靠组合命令 + 后处理。
为什么 MEMORY USAGE 无法直接统计 String 类型占比
MEMORY USAGE 只接受一个 key 名,比如 MEMORY USAGE user:123,返回一个整数(如 (integer) 4820),但不会告诉你这个 key 是 string、hash 还是 zset;也不会告诉你它是否过期、是否带 TTL、用的是哪种编码(embstr 还是 raw)。你扫完所有 key,拿到一堆数字,却没类型字段,根本没法按 string/group 求和算百分比。
- 对不存在的 key,
MEMORY USAGE返回0,容易污染平均值 -
MEMORY USAGE user:*会报错:ERR wrong number of arguments,不支持通配符 - 集群环境下,key 分散在不同节点,脚本需手动路由 + 并发协调,极易超时或漏统计
生产环境推荐:用 redis-cli --bigkeys 快速定位 String 大 key
这是最轻量、最安全的起点——它不阻塞主线程(默认每 100 次 SCAN 休眠 0.01 秒),且自带类型分组统计:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 执行
redis-cli --bigkeys -i 0.1,输出里会明确标出Biggest string found so far和汇总行:34699strings with45262599bytes (99.99% of keys, avg size1304.44) - 注意看
avg size和Biggest string的差距:如果平均才 1KB 但最大有 37MB,说明存在异常大 string,要单独查MEMORY USAGE验证 - 搭配
INFO memory中的used_memory_human,可粗略估算:比如 total 内存 2GB,string 总 bytes 是 45MB,占比约 2.2%
需要精确占比?用 SCAN + TYPE + MEMORY USAGE 三连发(仅限开发/低峰期)
全量遍历必须用游标避免阻塞,但要注意结果截断风险:
- 先设好 client-output-buffer-limit,防止 SCAN 返回太大导致连接断开:
CONFIG SET client-output-buffer-limit "normal 0 0 0"(临时放宽) - 脚本逻辑必须是:SCAN → 对每个 key 执行 TYPE → 若为
string,再执行MEMORY USAGE→ 累加字节数 - 别用
KEYS *:在万级 key 以上会阻塞 Redis 数秒,线上禁止 - Python 示例片段(核心逻辑):
cursor = 0 total_string_bytes = 0 while True: cursor, keys = redis.scan(cursor, count=100) for k in keys: t = redis.type(k).decode() if t == 'string': mem = redis.memory_usage(k) # 注意:部分客户端需用 eval 或 pipeline 避免多次 round-trip total_string_bytes += mem if cursor == 0: break
容易被忽略的细节:String 编码影响实际内存,但 MEMORY USAGE 不体现
同一个 string 值,在不同长度下可能用 embstr 或 raw 编码,内存布局差异很大,而 MEMORY USAGE 只给总数,不拆解:
- 短 string(≤ 44 字节)走
embstr:key 和 value 共享一块内存,头部紧凑 - 长 string 走
raw:key 和 value 分开分配,额外多一个 SDS header 和指针开销 - 实测:存
"123"和存 1KB JSON,前者可能只占 64 字节,后者可能达 1.2KB ——MEMORY USAGE都只返回数字,看不出结构差异 - 真要深挖,得结合
DEBUG OBJECT key_name(仅开发环境)看 encoding 字段,但该命令线上通常禁用

















