一、Redis默认缓存策略的那些事儿
Redis作为内存数据库的扛把子,默认的缓存策略其实挺"佛系"的。默认情况下它就像个不会拒绝的老好人——内存满了也不主动清理,直到你收到那讨厌的"OOM"错误。不过别担心,咱们可以通过maxmemory-policy这个参数来调教它。
先看个典型配置示例(Redis技术栈):
# redis.conf关键配置示例
maxmemory 2gb # 设置最大内存限制
maxmemory-policy allkeys-lru # 修改默认策略为LRU淘汰
这里的allkeys-lru表示对所有键采用LRU算法(最近最少使用)。就像你整理衣柜时,会把最久没穿的衣服先扔掉。其他常见策略还有:
volatile-lru:只淘汰设置了过期时间的键allkeys-random:随机淘汰所有键noeviction:默认策略,直接报错不淘汰
二、策略调整的实战陷阱
上周我们生产环境就遇到个典型问题:明明设置了10GB内存,Redis却突然开始拒绝写入。查看日志发现大量OOM command not allowed错误——原来运维同学忘记改默认的noeviction策略了!
紧急处理时我们用CONFIG SET动态调整(Redis命令行示例):
# 动态修改策略(无需重启)
CONFIG SET maxmemory-policy allkeys-lru
CONFIG REWRITE # 持久化到配置文件
# 查看当前策略(带注释说明)
127.0.0.1:6379> CONFIG GET maxmemory-policy
1) "maxmemory-policy" # 配置项名称
2) "allkeys-lru" # 当前生效值
但这里有个坑:动态修改只对当前实例有效,重启后会丢失。就像你改了手机设置却没保存,下次开机又恢复原样。所以一定要记得CONFIG REWRITE写入配置文件!
三、不同场景的策略选型指南
场景1:电商秒杀系统
推荐使用volatile-ttl策略,优先淘汰剩余存活时间短的键。比如商品库存缓存:
# 商品缓存示例(带TTL)
SET sku:10086 500 EX 60 # 60秒后自动过期
场景2:用户会话管理
适合allkeys-lru,因为最近活跃的用户会话应该保留。通过Lua脚本实现智能清理(Redis+Lua示例):
-- 会话清理脚本
local keys = redis.call('keys', 'session:*')
for _,key in ipairs(keys) do
if redis.call('ttl', key) < 3600 then -- 剩余存活时间<1小时
redis.call('del', key)
end
end
return #keys
场景3:实时监控数据
采用allkeys-random快速随机淘汰,因为监控数据通常可丢失。配合以下命令效果更好:
# 监控数据写入示例
MULTI
INCR server:load:20231101
EXPIRE server:load:20231101 86400
EXEC
四、高级调优与避坑手册
内存碎片优化:
当发现used_memory_rss远大于used_memory时,用这个魔法命令:MEMORY PURGE # 需要Redis 4.0+混合存储方案:
对于大Value可以考虑Redis+MySQL组合:# Python伪代码示例(Redis+MySQL) def get_big_data(key): data = redis.get(key) if not data: data = mysql.query("SELECT * FROM big_table WHERE id=%s", key) redis.setex(key, 3600, compress(data)) # 压缩存储 return uncompress(data)监控预警配置:
建议通过INFO memory定期采集这些关键指标:mem_fragmentation_ratio> 1.5 时报警used_memory超过maxmemory的90%时扩容
最后提醒三个死亡陷阱:
- 在Docker中运行Redis时,默认不会读取配置文件,必须通过
-v挂载 - 主从复制时,从节点的
maxmemory要设置得比主节点更大 - 使用集群模式时,每个分片都要单独配置策略
记住,没有万能的缓存策略,就像没有适合所有场合的鞋子。理解业务特征,结合实际监控数据不断调整,才能让Redis真正成为你的性能加速器!
评论