memory stats 不提供 per-db 实际内存占用,因 redis 各库共享内存池;准确定位需离线解析 rdb 或在线 scan+memory usage;关键字段包括 allocator_、overhead.hashtable.、dataset.* 及 fragmentation。

MEMORY STATS 输出里没有 db_index 字段,别指望它直接显示每个库内存
很多人执行 MEMORY STATS 后翻半天,想找到类似 db0.memory_bytes 这样的字段,结果发现只有 db.0 开头的一小段,里面全是 overhead.hashtable.main 这类元数据开销,**不包含任何键值数据的实际内存占用**。这是因为 Redis 的 database 是逻辑命名空间,不是内存隔离单元——所有 db 共享同一块内存池,MEMORY STATS 天然就不支持按库拆分数据内存。
真正能定位 per-DB 内存分布的,只有两种可行路径
官方没提供 MEMORY STATS db0 这种语法(会报 ERR unknown command),也不能靠 INFO memory 或 MEMORY USAGE 单点扫描蒙混过关。必须用以下方式之一:
- 离线解析 RDB 文件:执行
redis-cli bgsave触发快照,再用redis-rdb-tools解析:rdb -c memory dump.rdb,输出含每 key 的db、type、size,可按 db 聚合求和——这是最准、对线上零影响的方式 - 在线逐 key 扫描(仅限低流量环境):先
SELECT 0,再SCAN 0 MATCH * COUNT 1000获取一批 key,对每个调用MEMORY USAGE <key></key>,记录结果后切到下一个 db 重复——但注意:MEMORY USAGE对复杂结构(如 ziplist 编码的 hash)要反序列化评估,单 key 耗时可能达毫秒级,百万 key 会卡住主线程
MEMORY STATS 里真正有用的字段是这些
虽然它不给 per-DB 数据,但对诊断内存异常非常关键。重点关注这几组值:
-
allocator_activevsallocator_resident:如果后者显著大于前者,说明 jemalloc 没把空闲内存还给 OS,属于外部碎片 -
allocator_allocatedvsused_memory:如果前者远大于后者,说明内部碎片严重(比如大量小 hash 键未合并成 hashtable) -
db.N下的overhead.hashtable.expires和overhead.hashtable.main:反映过期键哈希表和主键哈希表的元数据开销,数值异常高可能意味着过期键未及时清理或 key 名过长 -
dataset.bytes和dataset.percentage:表示实际数据体(非元数据)占总分配内存的比例,低于 60% 就该怀疑 overhead 或碎片问题了
宝塔面板里跑 MEMORY STATS 要加 grep 筛选,否则信息太多看花眼
在宝塔终端直接敲 redis-cli MEMORY STATS 会输出 30+ 行嵌套结构,容易漏掉关键项。建议固定搭配:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
redis-cli MEMORY STATS | grep -E "(allocator_|db\.|dataset\.|fragmentation)"
这样能快速聚焦到内存分配器状态、各 db 元数据开销、数据集占比和碎片率四类核心指标。注意 fragmentation 字段是比率(比如 "1.1039986610412598"),不是百分比——超过 1.3 就该警惕,配合 MEMORY PURGE 主动释放(仅对 jemalloc/tcmalloc 有效)。
别忘了:Redis 的 db 切换不影响内存归属,SELECT 1 后写入的 key,其内存依然混在全局池里;所谓“哪个 db 占得多”,本质是统计“哪些 key 在哪个 db”,而不是“哪块内存属于哪个 db”。这个认知偏差,是绝大多数人查不出 per-DB 内存的根本原因。










