目录
-
-
- 一、先了解整体内存状态
- 二、定位"大key"(占用内存多的key)
-
- [1. 用redis-cli的--bigkeys快速扫描](#1. 用redis-cli的--bigkeys快速扫描)
- [2. 用MEMORY USAGE命令精确查看单个key的内存](#2. 用MEMORY USAGE命令精确查看单个key的内存)
- [3. 批量扫描所有key并统计内存(适合脚本自动化)](#3. 批量扫描所有key并统计内存(适合脚本自动化))
- [三、离线分析RDB文件 - Redis 7.0 以下版本(更全面,不影响在线服务)](#三、离线分析RDB文件 - Redis 7.0 以下版本(更全面,不影响在线服务))
-
- [1. 安装redis-rdb-tools](#1. 安装redis-rdb-tools)
- [2. 解析RDB文件生成内存报告](#2. 解析RDB文件生成内存报告)
- [3. 分析报告](#3. 分析报告)
- [四、离线分析RDB文件 - Redis 7.0 以上版本(更全面,不影响在线服务)](#四、离线分析RDB文件 - Redis 7.0 以上版本(更全面,不影响在线服务))
- 五、分析key的分布与过期情况
- 六、总结与优化建议
-
Redis内存使用率居高不下,开发要求帮提供下Redis内存占用的key的占比的信息,运维如何处理呢?
当Redis内存使用率过高时,分析key的占用情况可以按以下步骤进行,结合Redis内置命令和第三方工具定位问题:
一、先了解整体内存状态
首先通过 INFO memory
命令查看Redis整体内存使用情况,重点关注以下指标:
bash
redis-cli info memory
关键指标解析:
used_memory
:Redis实际使用的内存(字节)used_memory_peak
:内存使用峰值used_memory_lua
:Lua脚本引擎使用的内存mem_fragmentation_ratio
:内存碎片率(理想值1.0~1.5,过高说明碎片严重)maxmemory
:配置的最大内存限制(若为0则无限制)expired_keys
:已过期的key数量(判断是否有大量过期key未清理)
内存使用率高,有可能是"大key"占用的多,也有可能是小key的数量多导致的,需要根据实际情况分析。
二、定位"大key"(占用内存多的key)
大key是导致内存过高的常见原因(如超大字符串、包含百万级元素的哈希/集合等)。
1. 用redis-cli的--bigkeys快速扫描
Redis自带的 redis-cli
提供 --bigkeys
选项,可扫描所有key,按类型统计最大的key(字符串按字节数,集合/哈希等按元素数):
bash
redis-cli --bigkeys -i 0.1 # -i 0.1表示每扫描100个key休息0.1秒,降低对Redis的影响
输出示例:
# 字符串最大key(字节数)
Biggest string found 'user:1000' has 1048576 bytes
# 哈希最大key(字段数)
Biggest hash found 'products' has 50000 fields
注意:
- 此命令会遍历所有key,可能阻塞Redis(尤其是大实例),建议在低峰期执行。
- 仅统计"元素数"或"字节数",不直接返回内存占用(但可作为大key的初步筛选)。
2. 用MEMORY USAGE命令精确查看单个key的内存
对 --bigkeys
筛选出的可疑key,用 MEMORY USAGE
命令查看其实际占用的内存(包括数据结构本身的开销):
bash
# 查看key为"user:1000"的内存占用(字节)
redis-cli memory usage "user:1000"
说明:内存占用不仅包含数据本身,还包括Redis内部的元数据(如key名称、过期时间、数据结构的指针等)。
3. 批量扫描所有key并统计内存(适合脚本自动化)
若需批量分析大量key,可结合 SCAN
命令(非阻塞遍历)和 MEMORY USAGE
批量统计:
bash
# 示例:用bash脚本扫描并记录内存超过1MB的key
redis-cli scan 0 MATCH "*" COUNT 1000 | while read -r key; do
size=$(redis-cli memory usage "$key")
if [ "$size" -gt 1048576 ]; then # 1MB = 1048576字节
echo "Key: $key, Size: $size bytes" >> big_keys.txt
fi
done
注意 :SCAN
的 COUNT
参数可调整(默认10),值越大扫描越快但消耗资源越多。
三、离线分析RDB文件 - Redis 7.0 以下版本(更全面,不影响在线服务)
如果Redis开启了RDB持久化(默认开启),可通过解析RDB文件获取所有key的内存详情(推荐用 redis-rdb-tools
工具)。
redis-rdb-tools 是一个 python 的解析 rdb 文件的工具。 源码地址: https://github.com/sripathikrishnan/redis-rdb-tools/
1. 安装redis-rdb-tools
bash
pip install rdbtools python-lzf
2. 解析RDB文件生成内存报告
bash
# 导出所有key的内存信息(包括类型、大小、过期时间等)
rdb -c memory /var/lib/redis/dump.rdb > redis_memory_report.csv
生成的CSV文件包含以下字段:
database
:所属数据库type
:key的类型(string/hash/list等)key
:key名称size_in_bytes
:总内存占用(字节)expiry
:过期时间(时间戳,-1表示永不过期)
3. 分析报告
用Excel或命令行筛选排序,找出内存占用最高的key:
bash
# 按内存占用降序排序,取前100条
sort -t ',' -k 4nr redis_memory_report.csv | head -n 100
四、离线分析RDB文件 - Redis 7.0 以上版本(更全面,不影响在线服务)
可惜的是redis-rdb-tools 工具,后期没有新的更新,基于Redis 7.0 版本生成的 rdb文件解析会报错:
Exception: ('verify_version', 'Invalid RDB version number 10')

对于Redis7版本的rdb文件,可以使用 golang版本的工具:
https://github.com/HDT3213/rdb
RDB 文件的整体结构:
https://www.cnblogs.com/Finley/p/16251360.html
五、分析key的分布与过期情况
除了大key,还需关注:
-
是否有大量无过期时间的key :导致内存持续增长。
用
SCAN
结合TTL
命令统计:bash# 统计永不过期的key数量(TTL为-1) redis-cli scan 0 MATCH "*" COUNT 1000 | while read -r key; do ttl=$(redis-cli ttl "$key") if [ "$ttl" -eq -1 ]; then echo "$key" >> no_expire_keys.txt fi done
-
key的类型分布 :某些类型(如未压缩的哈希)可能比其他类型更耗内存。
用
INFO keyspace
查看各类型key的数量:bashredis-cli info keyspace
六、总结与优化建议
- 清理大key:对非必要的大key直接删除,或拆分(如将大哈希拆分为多个小哈希)。
- 设置合理的过期时间 :对临时数据(如缓存)通过
EXPIRE
设置过期时间,利用Redis自动清理。 - 优化数据结构 :
- 字符串:若存储JSON等结构化数据,可改用哈希(hash)节省内存。
- 哈希/集合:启用压缩列表(ziplist)配置(如
hash-max-ziplist-entries 512
),小数据更高效。
- 处理内存碎片 :若
mem_fragmentation_ratio
过高(如>1.5),可重启Redis(需提前做好持久化)。