如何解决 AOF 后台重写存在的数据不一致问题
为了解决上述问题,Redis 引入了 AOF 重写缓冲区(aof_rewrite_buf_blocks),这个缓冲区在服务器创建子进程之后开始使用,当 Redis 服务器执行完一个写命令之后,它会同时将这个写命令追加到 AOF 缓冲区和 AOF 重写缓冲区 。
这样一来可以保证:
1、现有 AOF 文件的处理工作会如常进行 。这样即使在重写的中途发生停机,现有的 AOF 文件也还是安全的 。
2、从创建子进程开始,也就是 AOF 重写开始,服务器执行的所有写命令会被记录到 AOF 重写缓冲区里面 。
这样,当子进程完成 AOF 重写工作后,父进程会在 serverCron 中检测到子进程已经重写结束,则会执行以下工作:
1、将 AOF 重写缓冲区中的所有内容写入到新 AOF 文件中,这时新 AOF 文件所保存的数据库状态将和服务器当前的数据库状态一致 。
2、对新的 AOF 文件进行改名,原子的覆盖现有的 AOF 文件,完成新旧两个 AOF 文件的替换 。
之后,父进程就可以继续像往常一样接受命令请求了 。
相关源码在 aof.c,核心方法是:rewriteAppendOnlyFileBackground
AOF 重写缓冲区内容过多怎么办
将 AOF 重写缓冲区的内容追加到新 AOF 文件的工作是由主进程完成的,所以这一过程会导致主进程无法处理请求,如果内容过多,可能会使得阻塞时间过长,显然是无法接受的 。
Redis 中已经针对这种情况进行了优化:
1、在进行 AOF 后台重写时,Redis 会创建一组用于父子进程间通信的管道,同时会新增一个文件事件,该文件事件会将写入 AOF 重写缓冲区的内容通过该管道发送到子进程 。
2、在重写结束后,子进程会通过该管道尽量从父进程读取更多的数据,每次等待可读取事件1ms,如果一直能读取到数据,则这个过程最多执行1000次,也就是1秒 。如果连续20次没有读取到数据,则结束这个过程 。
通过这些优化,Redis 尽量让 AOF 重写缓冲区的内容更少,以减少主进程阻塞的时间 。
到此,AOF 后台重写的核心内容基本告一段落,通过一张图来看下其完整流程 。
文章插图
相关源码在 aof.c,核心方法是:aofCreatePipes、aofChildWriteDiffData、rewriteAppendOnlyFile
RDB、AOF、混合持久,我应该用哪一个?
一般来说,如果想尽量保证数据安全性,你应该同时使用 RDB 和 AOF 持久化功能,同时可以开启混合持久化 。
如果你非常关心你的数据,但仍然可以承受数分钟以内的数据丢失,那么你可以只使用 RDB 持久化 。
如果你的数据是可以丢失的,则可以关闭持久化功能,在这种情况下,Redis 的性能是最高的 。
使用 Redis 通常都是为了提升性能,而如果为了不丢失数据而将 appendfsync 设置为 always 级别时,对 Redis 的性能影响是很大的,在这种不能接受数据丢失的场景,其实可以考虑直接选择 MySQL 等类似的数据库 。
服务启动时如何加载持久化数据
简单来说,如果同时启用了 AOF 和 RDB,Redis 重新启动时,会使用 AOF 文件来重建数据集,因为通常来说,AOF 的数据会更完整 。
而在引入了混合持久化之后,使用 AOF 重建数据集时,会通过文件开头是否为“REDIS”来判断是否为混合持久化 。
完整流程如下图所示:
文章插图
相关源码在 server.c,核心方法是:loadDataFromDisk
【面试必问的 Redis:RDB、AOF、混合持久化】
推荐阅读
- 富春山居图是中国十大传名画之一这幅画的作者是 富春山居图是中国十大传世名画之一这幅画的作者是什么
- 聊聊golang的zap的ReflectType
- 端午节又称什么 端午节的别称分别是什么
- 提高微服务安全性的11个方法
- 绿茶的保质期,红茶的保质期
- 8款药膳花茶,茶药膳疗法对保健起着不可忽视的作用
- 白福鼎老白茶价格,白茶的价格
- 老公眼里觉得你很“贱”的7个举动
- 男人不同时期想要的女人
- 女人单身太久的十大负面表现