used_memory_dataset表示Redis数据本身占用的内存(不含缓冲区、连接开销等),单位字节,≈used_memory−used_memory_overhead;used_memory_dataset_human为其可读格式。

直接看 INFO memory 里的 used_memory_dataset
这个值就是 Redis 数据本身占用的内存(不含缓冲区、连接开销等),单位是字节,used_memory_dataset_human 是它的可读格式。它不区分类型,但能告诉你“纯数据”占了多少——如果这个值已经接近 maxmemory,说明真有大量数据在内存里,不是碎片或缓冲区撑起来的。
注意:used_memory_dataset ≈ used_memory - used_memory_overhead,而 used_memory_overhead 包括客户端输出缓冲、AOF 重写缓冲、复制 backlog 等。所以别只盯着 used_memory,否则可能把缓冲区暴涨误判成数据膨胀。
用 redis-cli --bigkeys 快速定位高占比类型
它不是查总占比,而是按 string/hash/list/set/zset 分组统计样本,给出每类的 key 数量、平均大小、最大大小。这是生产环境最安全的第一步:
-
redis-cli -h host -p port --bigkeys -i 0.1:加-i 0.1避免阻塞,适合线上 - 结果里看到类似
hash: 892 keys, avg size 2.4MB, max 42MB,就说明 hash 类型大概率是内存主力 - 它底层用的是
SCAN+TYPE+MEMORY USAGE组合,但做了采样和聚合,不会扫全量 - 对集群环境,它默认只连一个节点;要全集群分析,得手动路由或改用脚本
抽样验证时,必须搭配 TYPE 和 MEMORY USAGE
MEMORY USAGE 只返回数字,不带类型;单独调用等于白忙——你拿到 15MB,但不知道是 zset 还是 hash,更没法归类求和。
正确姿势是三连发:
- 先
TYPE key_name确认结构类型 - 再
MEMORY USAGE key_name拿实际字节数 - 对
hash补HLEN key_name,看字段数是否合理;对zset补ZCARD key_name+ZRANGE key_name 0 0 WITHSCORES,判断是否因编码切换(如 ziplist → skiplist)导致体积暴增 - 对不存在的 key,
MEMORY USAGE返回0,容易污染平均值,记得过滤
真正想算各类型占比?别硬扫全量 key
用 KEYS * 在生产环境等于自毁;SCAN 虽安全,但遍历 100 万 key + 每个都 TYPE + MEMORY USAGE,网络往返和 client-output-buffer-limit 容易触发断连。
更现实的做法是交叉验证:
- 看
DBSIZE和used_memory_dataset比值:若 DBSIZE 是 20 万,used_memory_dataset却达 6GB,基本锁定存在少数超大结构(比如单个hash存了 10 万字段) - 对疑似类型,用
redis-rdb-tools解析 RDB 文件生成 CSV,字段含type和size,可本地聚合统计——这比实时扫描准,且不压实例 - 集群环境下,
--bigkeys结果只能代表单节点;需在每个分片上分别跑,并人工加总,注意槽位分布不均带来的偏差
类型占比不是靠一条命令能算出来的数字,而是靠指标交叉、抽样验证、离线分析拼出来的图景。最容易被忽略的是:MEMORY USAGE 的结果受编码影响极大,同一个 hash,ziplist 和 dict 编码可能差 3 倍内存,光看字节数不看 DEBUG OBJECT 或 OBJECT ENCODING,优化就无从下手。


















