# 线上发现 Redis 机器爆了,如何优化?
4 min read
Table of Contents
线上发现 Redis 机器爆了,如何优化?
【核心定义】
线上 Redis 机器“爆了”通常指内存或 CPU 资源耗尽,导致服务不可用或性能骤降,需从资源监控、数据结构优化、配置调优、架构升级四方面系统性解决。
【关键要点】
- 紧急止血:立即扩容实例内存或切换至从节点,恢复服务可用性。
- 定位根因:通过
INFO memory、MONITOR(慎用)、慢查询日志分析内存增长点与热点 Key。 - 数据结构优化:将 String 存储的 JSON 拆分为 Hash,对大 Key 进行分片(如
user:1000:{field})。 - 内存控制:设置
maxmemory并启用 LRU/LFU 淘汰策略,对冷数据设置 TTL。 - 配置调优:关闭透明大页(
transparent_hugepage),调整tcp-backlog与timeout防连接堆积。 - 架构升级:数据分片(Cluster/Codis)、读写分离、热数据加本地缓存(如 Caffeine)。
【深度推导/细节】
内存爆满场景拆解:
- 大 Key 问题:单个 Key 值过大(如 List 存百万元素)导致序列化阻塞、迁移失败。
优化:用SCAN扫描并拆分,或改用SSTable结构存储(如 RocksDB)。 - 内存碎片:频繁增删改导致
mem_fragmentation_ratio > 1.5。
解决:启用activedefrag yes或重启实例整理碎片。 - 淘汰策略失效:
allkeys-lru在弱访问模式下可能误删热点数据。
调优:结合OBJECT idletime分析访问模式,改用allkeys-lfu(Redis 4.0+)。
CPU 飙升场景拆解:
- 慢查询阻塞:
O(N)命令(如KEYS *、全量HGETALL)占用单线程。
定位:slowlog get 10分析,用SCAN替代KEYS,复杂计算移至客户端。 - 持久化冲突:
bgsave子进程与 AOF 重写同时触发导致fork延迟。
控制:错峰配置save规则,或改用混合持久化(AOF+RDB)。
【关联/对比】
- Redis vs Memcached:Redis 单线程模型更易受 CPU 密集型操作影响,需避免 Lua 脚本长时间运行。
- Cluster vs Codis:Cluster 原生分片但运维复杂,Codis 支持平滑扩容但需代理层。
『面试官追问』
- 如何发现热 Key?
- 客户端统计(如 Jedis 的 KeyTracker)、代理层收集、
redis-cli --hotkeys(Redis 5.0+)。
- 客户端统计(如 Jedis 的 KeyTracker)、代理层收集、
- 内存达到 maxmemory 后写入会怎样?
- 根据
maxmemory-policy决定:默认noeviction拒绝写入,生产环境建议volatile-lru。
- 根据
- AOF 重写期间内存暴涨怎么办?
- 控制
aof-rewrite-incremental-fsync yes,或升级至 Redis 7.0 使用多部分 AOF 减少阻塞。
- 控制
【优化体系总结】
- 短期:扩容 + 大 Key/热 Key 治理。
- 中期:配置调优 + 架构分层(热点数据本地缓存)。
- 长期:数据分片 + 监控告警(如 Prometheus + Grafana 设置内存 80% 阈值)。