1 概述
RDB全量备份是非常耗时的,而且不能提供强一致性,如果Redis进程崩溃,那么在最近一次RDB备份之后的数据也会随之消失。AOF以独立日志的方式记录每次的写命令,可以很好的解决数据持久化的实时性。系统重启时可以重新执行AOF文件中的密令来恢复数据。AOF会先把命令追加在AOF缓冲区,然后根据对应的策略写入硬盘。
2 AOF持久化流程
AOF持久化流程如下图:

AOF的实现流程有三个步骤(append——write——fsync):
首先append把命令追加到AOF缓冲区,然后write将缓冲区的命令写入到程序缓冲区,最后fsync将程序缓冲区的内容写入文件。当AOF持久化功能处于开启状态时,服务器每执行完一个命令就会将命令以协议格式追加写入redisServer结构体的aof_buf缓冲区。而在服务重启的时候会把AOF文件加载到缓冲区中。
AOF有以下三种触发机制:

always:每次发生数据变更都会被记录到磁盘,性能差,但数据完整性比较好。
everysec:每秒将aof_buf缓冲区的内容写入AOF文件,如果宕机,就会有1秒内的数据丢失。
no:将数据同步操作交给操作系统来处理,性能最好,但数据可靠性最差。在配置文件中设置appendonly yes 后,若没有指定appendfsync,默认会使用everysec选项。
AOF持久化源码如下:
//AOF定时触发的源码
int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
/* AOF延迟刷新,如果fsync速度慢,则在每个cron周期内尝试完成 */
if (server.aof_flush_postponed_start) flushAppendOnlyFile(0);
/* AOF些错误,在这种情况下,还有一个缓冲区要刷新,如果成功,清除AOF错误,是数据库重新可写 */
run_with_period(1000) {
if (server.aof_last_write_status == C_ERR)
flushAppendOnlyFile(0);
}
}
//执行write和fsync操作
void flushAppendOnlyFile(int force) {
ssize_t nwritten;
int sync_in_progress = 0;
mstime_t latency;
//检查是否有数据
if (sdslen(server.aof_buf) == 0) {
/* 使用bio_pending来判断是否有后台fsync操作正在进行 */
if (server.aof_fsync == AOF_FSYNC_EVERYSEC &&
server.aof_fsync_offset != server.aof_current_size &&
server.unixtime > server.aof_last_fsync &&
!(sync_in_progress = aofFsyncInProgress())) {
goto try_fsync;
} else {
return;
}
}
if (server.aof_fsync == AOF_FSYNC_EVERYSEC)
sync_in_progress = aofFsyncInProgress();
//如果没有设置强制刷盘的选项,可能不会立即进行,而是延迟执行AOF刷盘
if (server.aof_fsync == AOF_FSYNC_EVERYSEC && !force) {
if (sync_in_progress) {
if (server.aof_flush_postponed_start == 0) {
server.aof_flush_postponed_start = server.unixtime;
return;
}
//如果距离上次执行刷盘操作没有超过2秒,直接返回
else if (server.unixtime - serv

本文详细介绍了Redis的AOF(AppendOnlyFile)和RDB持久化机制,包括AOF的工作原理、触发机制、重写操作,以及RDB和AOF的优缺点,讨论了AOF+RDB混合模式的配置和数据恢复流程。
最低0.47元/天 解锁文章
2083

被折叠的 条评论
为什么被折叠?



