当前位置:首页 > 问答 > 正文

Redis配置那些事儿,聊聊怎么调才能跑得更顺畅一点

综合参考了Redis官方文档、多位技术博客作者如Antirez(Redis之父)和Peter Zaitsev等人的实践经验分享,以及《Redis实战》等书籍中的常见优化建议)

Redis配置那些事儿,聊聊怎么调才能跑得更顺畅一点

想让Redis这个速度本来就很快的家伙再快一点,或者更稳定地为你服务,光靠默认配置很多时候是不够的,这就像买了一辆好车,默认设置能开,但根据你的路况和驾驶习惯调一调,开起来会更得心应手,下面我们就聊聊几个关键部位的“调校”。

Redis配置那些事儿,聊聊怎么调才能跑得更顺畅一点

最基础也最重要的一点:别让内存拖后腿,Redis的所有数据都放在内存里,内存不够了,性能立马跳水,你得时刻关注内存使用情况,如果发现内存快满了,有两个主要方向:一是扩大内存,这是最直接的;二是启用数据淘汰策略,默认情况下,Redis在内存不足时会拒绝新的写入操作,这显然不是我们想要的,你可以在配置文件里找到 maxmemory-policy 这个设置,把它改成比如 allkeys-lru,这意味着当内存不够时,Redis会尝试淘汰那些最近最少使用的键,给新数据腾地方,还有针对带过期时间的键的淘汰策略,你可以根据业务特点选择,关键是,别让Redis因为内存问题而“罢工”。(此点参考了Redis官方文档关于内存管理的章节)

持久化配置是性能和可靠性的平衡木,Redis有两种主要的持久化方式:RDB和AOF,RDB像是给内存数据拍个快照,恢复起来快,但可能会丢失最后一次快照之后的数据,AOF则是记录下每一个写操作命令,数据安全性高,最多丢一秒的数据(如果配置为每秒同步),但文件会越来越大,重启恢复速度慢,默认可能只开了RDB,对于数据不能丢的服务,建议同时开启AOF(appendonly yes),但开了AOF后,要注意 appendfsync 这个配置,它控制着写操作的同步频率:always 是每个命令都同步,最安全但最慢;everysec 是每秒同步,是安全与性能的良好折衷,也是默认推荐;no 则由操作系统决定,最快但可能丢失较多数据,大多数场景用 everysec 就挺好,可以定期对AOF文件进行重写,压缩体积,这个Redis可以自动完成。(持久化机制的细节和权衡在《Redis实战》一书中有详细讨论)

Redis配置那些事儿,聊聊怎么调才能跑得更顺畅一点

再来,网络和连接池的设置也别忽视,有时候感觉Redis慢,不是它本身处理得慢,而是网络或者建立连接的开销大,如果客户端和服务端网络延迟高,那再快的Redis也白搭,频繁地创建和关闭连接代价很高,好在大多数Redis客户端都支持连接池,确保你的应用程序使用了连接池,并且设置了合理的池大小,太小了会导致请求等待连接,太大了又会浪费资源,这个值需要根据你的并发量来测试调整,在Redis服务端,有个 tcp-keepalive 配置,默认是300秒,它有助于检测死连接并及时清理,对于网络环境不稳定的情况有帮助。(关于连接池的重要性,多位资深工程师在技术分享中反复提及)

还有个小技巧是关于 Key的设计,虽然这不是配置文件里的参数,但直接影响性能,避免使用过长的Key名,比如用 user:123:profile 就比 user_account_information_for_id_123 好得多,因为每个Key都会完全存储在内存中,更重要的是,要警惕“大Key”,比如一个Hash键里面存了几十万个字段,或者一个List有几百万个元素,操作这种大Key会非常耗时,可能会阻塞其他请求,尽量把数据打散,也要避免“热Key”,即某个Key被超高并发地访问,如果这个Key恰好是个大Key,问题就更严重了,可以通过拆分、增加本地缓存等方式来缓解。(Antirez本人在博客中多次强调过不合理的数据结构设计对性能的负面影响)

操作系统层面也有优化空间,有一个叫 vm.overcommit_memory 的Linux内核参数,最好把它设置为1,这是为了防止在极端情况下,Redis执行持久化(比如生成RDB快照)时,系统因内存不足而杀掉Redis进程,虽然听起来有点技术性,但设置一下能避免很多诡异的故障,操作很简单,以root身份执行 echo 1 > /proc/sys/vm/overcommit_memory 即可。(这个建议广泛出现在各种Redis生产环境部署指南中)

调优Redis不是一个一劳永逸的动作,而是一个持续观察和微调的过程,你需要结合自己的业务特点,比如是读多写少还是写多读少,对数据丢失的容忍度如何,并发量有多大,来有针对性地调整这些配置,最好的方法是,在调整任何参数前后,都进行压力测试,用数据说话,这样才能真正让你的Redis跑得既快又稳。