在高并发场景下,Redis 作为高性能的键值对数据库,常被用于缓存、会话存储等核心业务场景。但在实际运维中,大key 和 热key 会引发性能瓶颈,内存策略配置不当也会导致数据丢失或服务阻塞。本文结合实战经验,详细拆解 Redis 大key、热key的排查与优化方案,梳理核心监控指标,并解读最大内存策略的配置思路。
一、大key的排查与优化
大key是指占用内存过大的键值对,这类key会导致Redis内存碎片率升高、集群数据倾斜,甚至在删除时阻塞服务,严重影响Redis的稳定性。
1. 如何定位大key
针对大key的查找,主要有三种实用方法,适用于不同的运维场景:
-
Redis客户端原生命令
使用redis-cli的--bigkeys参数,可快速定位每种数据类型中最大的key,命令如下:bashredis-cli -p 7001 -a IdfaUqTcdad82 --bigkeys该方法的优势是操作简单、耗时短,缺点是仅能获取每种类型的最大key,无法遍历所有大key。
-
自定义程序扫描
通过编写程序遍历Redis所有key,逐个计算key的内存占用。这种方式能精准筛选出所有大key,但会扫描全量key,在数据量大时耗时较长,可能对Redis性能造成一定压力。 -
RDB文件分析工具rdbtools
先导出Redis的RDB持久化文件,再通过rdbtools分析文件并生成CSV报告,在报告中可直观筛选出大key。该方法离线操作,不影响线上服务,适合大规模集群的大key排查。
2. 大key的优化方案
找到大key后,需根据业务场景选择合理的优化手段,核心原则是避免直接阻塞Redis服务。
- 安全删除无用大key
直接使用del命令删除复杂类型大key(如hash、list)时,会触发Redis单线程阻塞,因此需分类型处理:- 字符串(string)类型:可直接执行
del命令删除; - 哈希(hash)、列表(list)等集合类型:通过
hscan/sscan等命令分批获取元素,再用hdel/srem逐个删除; - Redis 4.0+版本:支持
unlink命令实现惰性删除,将删除操作放到后台线程执行,不阻塞主线程; - Redis 6.0+版本:开启
lazyfree-lazy-user-del参数后,执行del命令等效于unlink,默认启用惰性删除。
- 字符串(string)类型:可直接执行
- 拆分大key
对于仍需使用的大key,可通过拆分降低单key内存占用:- 字符串类型:将一个大字符串拆分为多个小字符串,例如用户信息拆分为
user:1:name、user:1:age等; - 集合类型:将一个大hash/list拆分为多个小hash/list,例如订单列表按时间拆分为
order:202501、order:202502。
- 字符串类型:将一个大字符串拆分为多个小字符串,例如用户信息拆分为
- 更换存储介质
对于长文本、大文件等数据,Redis并非最优选择,可迁移至MongoDB等文档型数据库,或直接缓存到CDN,减少Redis的存储压力。
二、热key的发现与优化
热key是指在短时间内被高频访问的key,这类key会导致Redis节点的CPU使用率飙升、网络带宽被占满,引发集群负载不均衡。
1. 热key的查找方法
- 客户端/代理层统计
在业务代码或Redis代理层(如Twemproxy、Codis)中,通过字典记录每个key的访问次数,定期上报统计数据。该方法的缺点是存在内存泄漏风险,且仅能统计当前客户端/代理的热key,多语言SDK维护成本较高。 - redis-faina工具分析
基于Redis的monitor命令,实时抓取一段时间内的命令请求,通过redis-faina工具统计热key的访问频率。需注意,monitor命令会影响Redis性能,不建议在生产环境长时间开启。 - hotkeys原生命令
Redis支持--hotkeys参数直接获取热key,但需满足前提条件:将最大内存策略设置为volatile-lfu或allkeys-lfu。这两种策略会记录key的访问频率,从而支持热key的快速识别。
2. 热key的优化策略
针对热key的优化,核心思路是分散访问压力,具体可采用以下三种方案:
- 拆分、迁移或复制热key
- 拆分:若热key为hash类型,可将其拆分为多个小hash,分布到不同Redis节点;
- 迁移:在Redis Cluster集群中,将热key所在的哈希槽单独迁移至独立节点,避免影响其他业务;
- 复制:创建多个内容相同、名称不同的热key(如
hot:key:1、hot:key:2),分散到不同节点,业务层随机访问。
- 读写分离架构
若热key的操作以读请求为主,可搭建主从集群,主节点负责写入,从节点负责读取,通过增加从节点数量分担读压力。 - 本地缓存+发布订阅
将热key数据缓存到业务服务器的本地内存(如本地HashMap),同时通过Redis的发布订阅机制,保证本地缓存与Redis数据的一致性。这种方式可大幅减少Redis的访问次数,降低集群压力。
三、Redis核心监控指标
要保障Redis的稳定运行,需建立完善的监控体系,重点关注以下9类核心监控项:
| 监控分类 | 核心监控项 | 获取方式 | 监控意义 |
|---|---|---|---|
| 连接监控 | 连接失败、客户端连接数 | redis-cli ping、info clients中的connected_clients |
检测Redis服务可用性,防止连接数超限 |
| 变量监控 | 最大内存、最大内存策略 | config get maxmemory、config get maxmemory-policy |
验证内存配置是否符合预期 |
| 主从复制监控 | 角色、复制状态、主从延迟、从库是否只读 | info replication中的role、info replication中的master_link_status、info replication中的master_repl_offset和slave0字段的offset之间的差值、info replication中的slave_read_only |
确保主从同步正常,避免数据不一致 |
| 吞吐量监控 | QPS、网络总入量、网络总出量、每秒输入量、每秒输出量 | info stats的instantaneous_ops_per_sec、info stats的total_net_input_bytes、info stats的total_net_output_bytes、info stats的instantaneous_input_kbps、info stats的instantaneous_output_kbps |
评估Redis服务负载能力 |
| 内存监控 | 内存使用率、碎片率、缓存命中率 | used_memory/maxmemory、info memory中的mem_fragmentation_ratio、info stats中, keysspace_hits/(keysspace_hits + keysspace_misses) |
优化内存使用效率,降低碎片率 |
| 持久化监控 | 上一次RDB持久化状态、上一次RDB持久化的持续时间、AOF文件大小 | info persistence中的rdb_last_bgsave_status、info persistence中的rdb_last_bgsave_time_sec、info persistence中的aof_current_size |
保障数据持久化可靠性 |
| key监控 | key总数、大key、热key | info keyspace中的keys、从RDB分析结果中获取、使用monitor、客户端或者代理层、redis-cli --hotkeys |
及时发现key相关的性能问题 |
| 慢查询监控 | 慢查询日志 | slowlog get |
定位耗时命令,优化执行效率 |
| 集群监控 | 集群状态、哈希槽状态、集群节点数量 | cluster info中的cluster_state、cluster info中的cluster_slots_fail、cluster info中的cluster_known_nodes |
确保Redis Cluster集群稳定运行 |
四、Redis最大内存策略解析
当Redis内存达到maxmemory限制时,会触发内存淘汰策略。Redis共提供8种内存策略,不同策略适用于不同的业务场景。
1. 8种内存淘汰策略
| 策略名 | 核心逻辑 |
|---|---|
| noeviction | 达到内存限制时,写入操作报错,不删除任何key |
| allkeys-lru | 淘汰所有key中最近最少使用的key |
| allkeys-lfu | 淘汰所有key中最不常用的key |
| volatile-lru | 淘汰设置过期时间的key中最近最少使用的key |
| volatile-lfu | 淘汰设置过期时间的key中最不常用的key |
| allkeys-random | 随机淘汰所有key中的部分key |
| volatile-random | 随机淘汰设置过期时间的部分key |
| volatile-ttl | 淘汰设置过期时间且剩余生存时间最短的key |
2. 策略配置建议
- 缓存场景(有明显冷热数据) :推荐使用
allkeys-lru。淘汰冷数据后,若后续需要访问,可从后端数据库加载,兼顾性能与数据可用性。 - 核心数据+非核心数据混合场景 :推荐使用
volatile-lru。核心数据不设置过期时间,不会被淘汰;非核心数据设置过期时间,按LRU规则淘汰。 - 数据库场景(不允许数据丢失) :推荐使用
noeviction。达到内存上限时拒绝写入,避免因淘汰策略导致核心数据丢失。
五、Redis运维补充知识点
1. 数据备份策略
数据备份是Redis运维的核心环节,需根据业务对数据一致性的要求选择方案:
- 高可用场景(不允许数据丢失) :采用RDB+AOF混合持久化。RDB适合大规模数据恢复,AOF保证数据的完整性。
- 允许分钟级数据丢失:仅使用RDB持久化。RDB生成的快照文件体积小,恢复速度远快于AOF。
- 集群备份建议:优先在从节点执行备份操作,避免影响主节点的业务处理。
2. 数据迁移方案
Redis数据迁移需根据版本和部署架构选择工具:
- 跨版本/跨架构迁移(如机房→云、单实例→集群) :使用
redis-shake工具,支持多种拓扑结构的数据同步。 - 同版本迁移:直接利用Redis主从复制功能,将目标实例设为源实例的从节点,同步完成后切换角色即可。
六、总结
Redis运维的核心是提前规避风险、实时监控状态、精准优化问题。大key和热key的排查与优化是提升Redis性能的关键,合理配置内存策略和监控指标,能有效保障Redis在高并发场景下的稳定性。同时,结合持久化备份和数据迁移方案,可进一步提升Redis集群的可用性和容灾能力。