Redis持久化之☞AOF、AOF是怎样执行持久化的?

AOF持久化机制:

AOF(Append Of File):将redis执行过的所有写指令记录下来,在下次redis重新启动时,只要把这些指令从前到后重复执行一遍,就可以实现数据恢复了。

以独立日志的方式记录每次写命令,重启时候重新执行AOF文件中的命令达到恢复数据的目的。AOF的主要作用是解决了持久化的实时性。

开启方式:

        开启AOF功能需要设置配置:appendonly yes ,默认不开启。

        AOF文件名通过appendfilename配置设置,默认文件名是appendonly.aof        

        保存AOF文件的路径和RDB持久化一致,通过dir配置指定。

AOF持久化不断优化的过程:【先看这个流程!!】

大家都知道,redis也是基于命令式的,每天的工作就是响应业务程序员发来的命令请求,学着mysql的样子,把执行的所有写入命令都记录下来,专门写入了一个文件,并给这种持久化的方式取了一个名字,叫做AOF。

但是现在应该多久写一次文件呢?肯定不能每执行一条写入命令就记录到文件中,那会严重拖垮redis的性能。所有就有一个缓冲区,然后把要记录的命令先临时保存在这里,然后再找时机写入文件,这个临时的缓冲区就叫做aof_buf。但是随着时间的推移,这个AOF的备份文件越来越大,不仅非常占用硬盘的空间,就连加载的时候也非常耗时。

那就得想办法将文件给压缩一下,这个过程就叫做AOF重写,如果瘦身的途径是去除冗余,那样的工作量实在是太大了。原来记录一条条指令的方式太笨了,数据改来改去,有很多中间状态都没有用,直接把最终的数据状态记录下来就好了,和RDB的方式一样,fork出一个子进程来做这件事。

!子进程再重写期间,我要是修改了数据,就会出现和重写的内容不一致的问题,需要把这个漏洞给补上,所以就出现了AOF重写缓冲区 aof_rewrite_buf,从创建重写子进程的那一刻起,就把后面来的写入命令也copy一份写到这个从写缓冲区中,等到子进程重写文件结束之后,再把这个重写缓冲区中的命令写入到aof的文件中,最后再重命名新的文件,替换掉原来的文件。

AOF写入策略和AOF同步策略:

写入策略:

写入策略主要是讲如何将数据写入到AOF文件中。主要是通过“write”系统调用来实现的。写入策略决定了Reids在执行写操作时,如何将这些操作记录追加到AOF文件中。

同步策略:

同步策略说的是何时从缓存中同步到物理磁盘。主要是通过“fsync”系统调用来实现的。同步策略决定了Redis何时调用“fsync”来确保数据持久化到硬盘。

同步策略的三种模式:

 redis提供了几种不同的AOF同步策略,通过配置“appendfsync”选项来控制“write”和“fsync”调用的频率

【appendfsync 配置在redis.window.conf文件中】

1、always:每次写操作以后就立即调用“fsync”

2、everysec(这个是默认配置的):每秒调用一次“fsync“

3、no:不主动调用”fsync“,让操作系统自己决定何时将数据从页缓存写入磁盘

AOF写入和同步过程中的内核页缓存

1、写入过程(write系统调用):

        当redis将'aof_buf'的数据通过'write'系统调用写入到AOF文件中是,这些数据会先进入操作系统的内核页缓存。此时数据还没有实际写入磁盘。

2、同步过程(fsync系统调用):

        根据AOF同步策略(’always‘、’everysec‘、’no‘),reids会调用’fsync‘系统调用,将内核缓存中的数据写入到磁盘。’fsync‘确保数据从内核页缓存写入到物理磁盘,实现持久化。

具体流程:

1、当执行一个写操作(SET key value)的时候,写操作的命令会被记录。

2、写操作命令被追加到Redis内部的'aof_buf'缓冲区中。

3、Redis通过'write'系统调用将‘aof_buf’中的数据写入到AOF文件。

        数据此时被写入操作系统的内核页缓存,而不是立即写入磁盘

4、数据暂时存储在操作系统的内核页缓存中,此时数据还未持久化到磁盘。

5、根据AOF同步的策略,Redis会在合适的时机(例如每秒一次或者每次的写操作后)调用'fsync'系统调用。

        ’fysnc‘确保内核页缓存中的数据被写强制写入到磁盘中。

6、最终,数据从内核页缓存被写入到物理磁盘,确保数据持久化。

AOF重写流程:

1、执行AOF重写请求,如果当前进程在执行AOF重写,请求不执行并返回如下响应:{ ERR Background append only file rewriting already in progress }

        如果当前进程正在执行bgsave操作,重写命令延迟到bgsave完成之后在执行,返回如下的响应:{ Background append only file rewriting scheduled }

2、父进程执行frok创建子进程,开销等同于bgsave过程。

3、主进程fork操作完成后,继续响应其他命令。所有修改命令依然写入AOF缓冲区并根据appendfsync策略同步到硬盘,保证原有AOF机制的正确性。

        由于fork操作运用写时复制技术,子进程只能共享fork操作时的内部数据。由于父进程依然相应名命令,Redis使用“AOF重写缓冲区”保存这部分新数据,防止新AOF文件生成期间丢失这部分数据。

4、子进程根据内存快照,按照命令合并规则写入到新的AOF文件。每次批量写入硬盘的数据量由配置aof-rewrite-incremental-fsync控制,默认为32MB,防止单次刷盘数据过多造成硬盘阻塞。

5、新的AOF文件写入完成后,子进程发送信号给父进程,父进程更新统计信息,具体见info persistence 下的aof_* 相关统计父进程把AOF重写缓冲区的数据写入到新的AOF文件使用新AOF文件替换老文件,完成AOF重写。

总结一下流程:

1、父进程启动重写操作

2、父进程通过' fork ' 创建子进程

3、子进程在独立的缓冲区中重写AOF文件

4、子进程重写完后通知父进程

5、父进程合并增量数据并替换旧的AOF文件

AOF的优缺点:

AOF的优点:

数据保证:我们可以设置fsync策略,一般默认是Every,也可以设置每次写入追加,所以即使服务死掉了,也最多丢失一秒数据。

自动缩小:当AOF文件大小到达一定程度的时候,后台自动的去执行AOF重写,此过程不会影响主进程,重写完成后,新的写入将会写到新的AOF中,旧的就会被删除掉。但是此条如果拿出来对比RDB的话还是没有必要算成优点,只是官网显示成优点而已。

AOF的缺点:

性能相对较差:它的操作模式决定了他会对Redis的性能有所损耗。(主线程写文档)

体积相对更大:尽管是将AOF文件重写了,但是毕竟是操作过程和操作结果仍然由很大的区别,体积也毋庸置疑的更大。

恢复速度更慢:因为要重新加载每条命令的执行,恢复速度比较慢。

  • 18
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值