Redis 的数据持久化机制
Redis 的持久化主要有两大机制:AOF(Append Only File) 日志和 RDB 快照。
AOF
AOF 记录 Redis 的操作日志,它是在主线程中执行的。AOF 和数据库的写前日志(Write Ahead Log, WAL)不同,WAL 是在执行命令前先把修改的数据写到日志文件中,而 AOF 是在命令执行成功之后再记录日志,这样有两个好处:
- 可以减少额外的检查命令是否正确的开销。
- 因为是在命令执行后记录,所以不会阻塞当前的写操作。
AOF 日志的格式
AOF 中的命令是以文本形式记录的,以 “set testkey testvalue” 为例:Redis 会先以 *3 来表示当前命令有三个部分,每部分会先以 $+数字 来表示长度,然后跟上具体的命令、键或值。例如:
潜在风险
- 可能在命令执行之后,写入 AOF 之前机器宕机,那么相应数据就有丢失的风险。
- 上面说到 AOF 是在主线程执行的,如果磁盘写入很慢,那么就有可能阻塞下一个命令的执行。
写回策略
根据上述的潜在风险,Redis 提供了三种写回策略供用户评估选择,可以在 AOF 配置项 appendfsync 配置:
配置项 | 写回时间 | 优点 | 缺点 |
---|---|---|---|
Always | 同步写回 | 可靠性高,数据基本不丢失 | 每个写命令都要落盘,性能影响较大 |
Everysec | 每秒写回 | 性能适中 | 宕机时丢失1秒内的数据 |
No | 操作系统控制的写回 | 性能好 | 宕机时丢失数据较多 |
AOF 重写机制
背景
当 Redis 接收的命令越来越多,那么 AOF 文件就会越来越大,AOF 文件过大带来性能问题:
- 文件系统本身对文件大小有限制,无法保存过大的文件;
- 文件过大时,追加命令记录效率会变低;
- 如果发生宕机,AOF 中的记录要一个个回放恢复数据,文件过大时会导致这个过程非常缓慢,影响 Redis 的正常使用。
重写机制
重写机制是指 Redis 会根据当前的数据状态创建一个新的 AOF 文件,即读取当前 Redis 中的所有的记录,将其一一写入新的 AOF 文件中。
为什么重写机制可以缩小 AOF 文件的大小呢?正常使用过程中,使用者可能会对一个 key 进行多次操作,而这些操作都会被记录到 AOF 中,而重写机制会忽略这些过程,只将最后的结果记录到 AOF 中,多条记录合并成了一条。
重写过程和 AOF 日志不同,它是由后台子进程 bgrewriteaof 来完成的,这样可以避免阻塞主线程导致的性能下降。
重写过程的主要流程如下:
- 每次执行重写时,主线程会 fork 一个 bgrewiteaof 子进程,因为 fork 的特性,同时会把主进程的内存拷贝一份给子进程。
- 因为此时主线程没有被阻塞,AOF 日志还会正常执行。
- 主线程的操作还会被记录到重写缓冲区中,等拷贝数据重写完成后,重写缓冲区的日志也会被写入新的 AOF 文件,都完成后,新的 AOF 文件会替代就文件。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/278774.html