Redis配置文件那些不太好说清楚的细节和配置技巧分享
- 问答
- 2025-12-24 08:02:30
- 1
说到Redis的配置文件,很多设置光看名字和官方注释还是挺让人迷糊的,感觉懂了,但具体怎么用、为什么用又说不上来,这里就分享一些不那么直观的细节和技巧。
maxmemory-policy:内存满了之后,到底怎么“删”?
这个配置是当Redis使用的内存达到maxmemory限制时,决定淘汰哪些键的策略,光说“淘汰”太笼统了,具体行为差别很大。
volatile-lruvsallkeys-lru: 这是最常用的两种。volatile-lru只会在那些设置了过期时间的键中,挑最近最少使用的进行淘汰,而allkeys-lru会在所有键中挑最近最少使用的淘汰,关键区别在于,如果你的业务中有些关键数据是永不失效的(比如基础配置),用volatile-lru能保护这些数据不被淘汰,但如果你觉得所有数据都可以被淘汰,只是希望保留最热门的,那么allkeys-lru通常效果更好,因为它淘汰的池子更大,能更精准地淘汰掉真正的冷数据。allkeys-lfu和volatile-lfu: 这是Redis 4.0引入的,基于使用频率(LFU)而不是最近使用时间(LRU),LRU的弱点是,一个很久以前被大量访问但现在已经是冷数据的大键,可能因为最近被访问了一次,就不会被淘汰,反而挤占了真正热键的空间,LFU通过统计访问频率能更好地解决这个问题,对于访问模式波动较大的场景更智能。noeviction: 这是默认策略,意思是“不淘汰”,当内存不够时,所有会申请更多内存的命令(比如写入新键、让某个键值变大)都会报错,但读操作和删除操作正常,这个策略看似“保守”,但在你把Redis当作纯缓存时是危险的,因为它会导致服务不可写,它更适合你把Redis当数据库用的场景,要求数据绝对不能丢失,宁愿写不进去也不能丢。
save:持久化的“定时任务”陷阱
配置文件里默认会有几行像save 900 1这样的配置,意思是“900秒内至少有1个键被改动,就触发一次快照(RDB)”,很多人会觉得多设几条规则更安全,比如save 60 10000,认为1分钟内有1万次写入也备份。

但这里有个隐藏问题:save指令是递进的,不是独立的。 它不是同时开多个定时器,它的工作机制是,只要满足任意一个save条件,就会开始一次备份,并且这次备份开始后,所有save条件的计数器都会重置,这意味着,如果你设置了一个非常频繁的条件(如save 60 10000),那么很可能因为达到这个条件而频繁触发备份,如果你的数据量很大,一次RDB备份需要好几秒,那么这个频繁的备份可能会对性能造成周期性冲击,设置save规则要结合你的数据重要性和写入量,不是越多越好,对于写入量巨大的缓存场景,甚至可以考虑关闭RDB,只使用AOF。
repl-backlog-size:主从同步的“后悔药”
主从复制时,主节点会把写命令同步给从节点,但如果从节点网络不好或者重启了,断开了一小段时间,重新连接上之后,怎么把断开期间丢失的数据补上呢?靠的就是这个repl-backlog(复制积压缓冲区)。
它是一个固定大小的环形缓冲区,主节点在把写命令发给从节点的同时,也会存一份到这个backlog里,从节点重连后,会把自己的复制偏移量发给主节点,如果这个偏移量还在backlog的范围内,主节点就直接把backlog里从那之后的所有命令发给从节点,完成增量同步,非常高效。

但如果从节点断开太久,它需要的偏移量已经不在backlog里了(因为backlog是环形的,旧数据被新数据覆盖了),那么主节点就只能进行全量同步,即生成一个完整的RDB文件发给从节点,这对主节点和网络都是巨大开销。
repl-backlog-size的大小,决定了你的从节点可以“掉线”多久还能吃到“后悔药”,默认是1MB,在写入量大的场景下可能几分钟就被覆盖了,适当调大这个值(比如100MB或更大),可以极大地降低全量同步的概率,提升集群稳定性,计算大小可以参考:backlog_size = (写入速度 MB/s) * (允许从节点最大断开时间 s)。
client-output-buffer-limit:看不见的“慢客户端”杀手
Redis需要把命令结果返回给客户端,如果客户端处理得很慢(比如网络差,或者客户端代码卡住了),结果数据就会在Redis服务器端的输出缓冲区里堆积,默认情况下,这个缓冲区大小是无限制的,这很危险,一个慢客户端可能会耗尽Redis的所有内存,导致它崩溃。

这个配置就是用来限制每个客户端的输出缓冲区大小的,它分为三种类型:
normal:普通客户端。replica:从节点客户端,用于主从复制,这个通常要设得很大,因为全量同步时主节点要发送整个RDB文件。pubsub:订阅了频道的客户端,如果发布消息很快而订阅者消费很慢,缓冲区也容易积压。
一个常见的坑是,对normal客户端没有设置限制,或者限制得太宽松,当有慢连接出现时,Redis会持续为它分配内存,直到触发OOM,一个合理的设置是给普通客户端一个软性限制(soft limit)和一个硬性限制(hard limit)以及一个软性限制的持续时间,client-output-buffer-limit normal 256mb 128mb 60,意思是普通客户端的缓冲区超过256MB,或者持续60秒都超过128MB,就断开这个客户端的连接,这相当于一种自我保护机制。
hz:Redis的“心跳”与CPU消耗
这个参数默认是10,表示Redis一秒钟会执行10次后台任务循环,这些任务包括:清理过期键、对哈希表进行渐进式Rehash、关闭超时的客户端连接、更新统计信息等。
提高hz的值(比如到100)会让这些后台任务执行得更频繁,好处是:过期键能被更及时地清理,内存回收更快;Rehash过程更平滑,避免单次Rehash耗时过长导致的延迟毛刺。
但代价是:CPU消耗会增加,因为Redis是单线程的,它做这些后台任务也会占用主线程的时间,如果你的系统对延迟非常敏感,且CPU资源充足,可以适当调高hz,但在CPU已经是瓶颈的实例上,盲目调高hz会让情况恶化,这是一个在CPU和响应速度之间的权衡。
配置Redis不是简单地打开文件改几个数字,而是要理解每个配置项背后的场景和权衡,结合自己业务的数据特性、访问模式和资源情况来做决策,最好的方法就是先在测试环境进行压测,观察调整配置后的效果。
本文由芮以莲于2025-12-24发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://www.haoid.cn/wenda/67429.html
