线上 Redis 机器爆了,如何优化?
当 Redis 机器出现爆满(CPU 100%、内存溢出、请求超时等情况),需要迅速排查问题并采取优化措施。可以从 排查 Redis 负载、优化数据结构、降级限流、扩展集群 等方面入手。
一、问题排查
先查看 Redis 运行状态
使用 info 命令,检查 Redis 关键指标:
redis-cli info
重点关注:

检查 Redis CPU 负载
css
top -p $(pgrep redis)
• CPU 100%:
• 可能是**大 key 处理、阻塞操作(如 keys )、Lua 脚本执行时间长*。
• 内存占满:
• 检查 maxmemory 是否配置正确,是否发生了数据驱逐。
查看 Redis 慢查询
arduino
redis-cli slowlog get 10
• 如果 SLOWLOG 发现某些命令执行时间过长,可能是:
• 大 Key 读写(get/set 超大对象)。
• LRANGE、HGETALL 这类大范围查询。
• 事务(MULTI/EXEC)执行时间过长。
二、优化方案
优化大 Key
• 如何检查大 Key
css
redis-cli --bigkeys
• 单个 Key 过大(如 List、Hash 过长) :
• 拆分 Key,减少单个 Key 存储量。
• 对 List 类型,尽量使用 LPUSH + LTRIM 控制长度。
• 如何删除大 Key(避免阻塞)
bash
UNLINK big_key # 非阻塞删除
-
限流降级
(1)限制 QPS,避免 Redis 过载
• 使用 令牌桶算法,限制高并发请求:
lua
local key = KEYS[1]
local limit = tonumber(ARGV[1])
local current = tonumber(redis.call('incr', key))
if current > limit then
return 0
else
redis.call('expire', key, 1)
return 1
end
• 如果返回 0,表示超出 QPS 限制,前端可降级。
(2)缓存降级
• 减少 Redis 依赖:
• 热点 Key 设置本地缓存,减少 Redis 访问:
ini
from cachetools import TTLCache
local_cache = TTLCache(maxsize=10000, ttl=60) # 60s 过期
• 改用 CDN/数据库兜底:如果 Redis 爆了,可以查询数据库,但要加限流。
增加 Redis 集群
(1)主从复制(读写分离)
• 读请求分流到从库:
xml
slaveof <master-ip> <port>
• 业务端用 READONLY 访问从库,减少主库压力。
(2)分片(Redis Cluster)
• 如果单机存储压力大,可使用 Cluster:
css
redis-cli --cluster create 192.168.1.1:6379 192.168.1.2:6379 192.168.1.3:6379 --cluster-replicas 1
• 哈希槽分片,自动扩展,避免单点 Redis 爆掉。
内存优化
(1)调整数据淘汰策略
• 检查 maxmemory-policy:
arduino
config get maxmemory-policy
推荐策略:
• LRU(最近最少使用) :allkeys-lru
• LFU(最近最少频率使用) :allkeys-lfu
• TTL 到期清理:volatile-ttl
(2)压缩数据
• 减少 Redis 内存占用:
• JSON 改为 MessagePack,减少数据量:
kotlin
import msgpack
data = {"user_id": 123, "name": "Alice"}
packed = msgpack.packb(data)
redis.set("user:123", packed)
• Hash 存储小对象(避免 String 过多):
sql
HSET user:123 name "Alice" age 25
-
避免阻塞操作
• 避免使用 KEYS * 查询
• 替代方案:用 SCAN 分页查询。
• Lua 脚本优化
• 避免长时间执行脚本,改用小批量执行。
三、总结

如果 Redis 爆了,先降级流量 ,再优化存储结构 ,最终通过分片扩展解决长期负载问题。