Redis高级之底层源码7——数据持久化(AOF方式)

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

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

geminigoth

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值