介绍
Redis 是内存型数据库,一旦主进程退出就会造成数据丢失。它的持久化主要有两大机制,即 AOF 日志和 RDB 快照,本文主要关心 AOF 日志。
过程
Redis 执行完一个写命令后,将写命令以协议文本的形式追加到 AOF 缓冲区末尾,再通过同步策略来决定是否将 AOF 缓冲区中的内容写入 & 同步到 AOF 日志。
同步策略
AOF 机制提供了三个选择,也就是配置项 appendfsync 的三个可选值:
- always:将
AOF缓冲区中的所有内容写入并同步到AOF日志。 - everysec:将
AOF缓冲区中的所有内容写入到AOF日志,如果上次同步AOF日志的时间距离现在超过 1 秒钟,那么对AOF日志进行同步。 - no:将
AOF缓冲区中的所有内容写入到 AOF 日志,但并不对 AOF 日志进行同步, 何时同步由操作系统来决定。
三种策略的优缺点也显而易见了,always 可靠性高性能低、no 可靠性低性能高,everysec 取两者折中。
重写机制
AOF 日志是以文件的形式记录接收到的所有写命令。随着接收的写命令越来越多,文件体积会越来越大。这也就意味着会带来一些问题。
- 操作系统对文件体积有限制,不能保存过大的文件。
- 对体积比较大的文件进行追加写入,效率会降低。
AOF日志体积过大,故障恢复过程缓慢。
为了解决上面的问题,Redis 提供了重写功能。通过该功能,Redis 可以创建一份新的 AOF 日志来代替现有的 AOF 日志。
- 两份
AOF日志所保存的数据库状态相同。 - 新
AOF日志不会包含浪费空间的冗余命令。 - 新
AOF日志体积小于等于原AOF日志。
重写过程
为什么要放在子进程里执行?
不会造成主线程阻塞,子进程进行 AOF 重写期间,主线程可以继续处理命令请求。
重写过程中有写命令,会造成数据不一致吗?
不会,Redis 维护了 AOF 重写缓冲区,在主线程创建重写子进程后开始使用。如果重写期间有写命令请求,Redis 会追加写入 AOF 缓冲区和 AOF重写缓冲区。当子进程完成创建新 AOF 日志后,主线程会将 AOF 重写缓冲区中的所有内容追加写入新 AOF 日志,此时新旧两份 AOF日志所保存的数据库状态完全一致。最后,用新 AOF 日志覆盖旧 AOF 日志,完成 AOF 日志重写操作。
本文转载自: 掘金