redis持久化方式分别有两种,rdb快照以及aof日志的方式,需要持久化的生产环境大都使用aof的方式,主要说说aof持久化的情况


aof为日志追加的方式,增加到设置的大小自动压缩(重做),这个压缩其实就是把内存中当前的数据全部解析为aof日志,创建一个新的aof文件替换当前的

控制参数分别有两个:

auto-aof-rewrite-percentage:增长百分比设置,当达到设置的百分百增长就自动压缩

auto-aof-rewrite-min-size:触发压缩的最小值,当aof文件压缩过后的大小超过这个设置的值时,该选项就会失效


aof rewrite原理:

redis为单线程应用,在触发rewrite机制时,redis的主进程会fork一个子进程来完成该操作,同时也需要复制一份内存的元数据信息,子进程在进rewrite时需要读取,该操作会阻塞正常的业务读取(latest_fork_usec状态可以看到最近一次该操作阻塞时间),需注意内存大小控制,在子线程进行rewrite操作时会维护两个buffer,新增的aof日志buffer、copy-on-write的buffer,以fork线程的时间点作为快照时间点,子线程写入aof的数据都为这个时间点之前的数据,copy-on-write buffer就是记录修改前数据(可以百度下copy-on-write机制),新数据在完成快照部分数据之后会从aof buffer中读取并追加到文件,redis对这两个buffer大小并未做限制,也就是只要子进程未完成操作该buffer会一直膨胀,查看redis日志在每次rewrite完成时都会记录这次使用的buffer大小:

0?wx_fmt=png


坑及注意项:

1、默认情况下aof rewrite时新产生的aof日志也会写进当前的aof文件,参数no-appendfsync-on-rewrite默认为no,这个参数采用默认设置时在一个高ops的redis上影响可能会非常大,很可能因为追加日志到当前的aof文件影响IO争抢从而影响rewrite的效率,导致copy-one-writebuffer占用过多内存,甚至占用swap,导致后面的redis效率和rewrite的效率更加的低,建议该参数在生产环境中设置为yes,在rewrite过程中不追加新日志到当前的aof文件,可以有效降低rewrite过程中出现故障的几率

2、在内存剩余紧张的节点上只要开启aof持久化,在aof日志追加的过程中会逐步占用swap,需及时清理,不然会影响redis效率以及rewrite的效率

3、swap占用在rewrite过程中会造成正常业务、rewire两方的IO争抢,如果在追加当前aof就会造成三分争抢,且swap的IO方式为随机IO,联系到第一点可能直接造成redis宕机

4、使用方式不当会产生很多内存碎片,内存碎片会挤压内存,造成rewrite时可用内存更少


redis出现的定义为业务二级缓存,持久化本是应急措施,只能起到宕机恢复的作用,在生产环境中为了效率和方便大量使用redis,不合理控制数据量及数据操作方式会造成大量的

aof rewrite的故障,很多建议限制最大可用内存、关闭swap,在不能很好控制redis的使用时这些选项都能临时救命,架构上能做到可以不需要持久化,redis可以避免80%以上的问题,如果一定需要持久化建议自定义rewrite时间,auto-aof-rewrite-percentage设置为0代表关闭rewrite,避开业务高峰期定时执行,可以避免业务带来的不可控因素,aof-rewrite-incremental-fsync这个参数也建议设置为yes分批刷入aof文件,可以有效利用顺序IO