介绍
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
日志重写操作。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。