美文网首页程序员
Redis持久化之----同步策略fsync

Redis持久化之----同步策略fsync

作者: 奔跑的Robi | 来源:发表于2019-08-01 15:08 被阅读7次

    这里先要了解redis的执行机制:redis主进程本身是以事件循环的形式运行,主要分为处理写指令的文件事件,和处理定时任务的时间事件。
    在处理写操作时,文件事件会将命令追加到aof缓冲区,由时间事件执行serverCron函数,调用flushAppendOnly函数进行文件的写入和同步。
    这里涉及write和save两个函数:

    • write: 将命令写入到AOF缓冲区中
    • save:调用fsync或fdatasync函数将AOF缓冲区中内容写到磁盘

    三种同步策略(即内存中AOF文件什么时候写入磁盘):

    appendfsync no  // 不保存 (write和save命令都由主进程完成)
    appendfsync everysec  // 每秒钟保存(write由主进程完成,save由子进程完成)
    appendfsync always // 每次执行命令都保存(write和save都由主进程执行)
    
    AOF_FSYNC_NO:

    每次flushAppendOnlyFile函数调用时都执行一次write方法,但不执行save方法。
    在这种策略下只有三种情况会执行save方法:

    • redis服务被关闭
    • aof功能被关闭
    • 系统的缓存被写满,或是定期保存操作被执行
      这三种情况的save都是由主进程完成,因此会造成主进程的阻塞,如果长时间没有执行save命令,会导致缓冲区内容过多,阻塞时间变得很长。
    AOF_FSYNC_EVERYSEC:

    每隔一秒钟执行一次save,在这种策略下,save操作由fork出的子进程调用,因此磁盘IO并不会阻塞主进程。根据Redis的状态,每当flushAppendOnlyFile被调用时,write和save的命令执行又分为几种情况:


    image.png

    由上图可以发现,在此策略下,如果情况1下发生宕机,最多只是损失2秒钟内的数据,如果是情况2下宕机,因为很久不执行save命令,有大量内容在缓冲区堆积,就可能损失超过2秒的数据。

    AOF_FSYNC_ALWAYS:

    每次执行完一个命令后,都会执行write和save操作,都由主进程直接执行,导致主进程阻塞

    三种策略的比较

    AOF_FSYNC_NO:在save不执行时的效率会很高,但是因为大量内容放在缓存中,在定时执行save的时候可能导致长时间的阻塞,并且如果在save执行前redis宕机,则缓冲区中的数据全部丢失,因此不适用于数据安全性要求严格的场景
    AOF_FSYNC_EVERYSEC:这个策略是redis的默认策略,是在安全性和性能当中比较折中的一个策略。
    AOF_FSYNC_ALWAYS: 此策略是安全性最高的策略,能够保证每一条命令都被持久化保存下来,至多丢失最后一条。但是主进程每一次都要执行write,save操作,对于性能影响很大

    相关文章

      网友评论

        本文标题:Redis持久化之----同步策略fsync

        本文链接:https://www.haomeiwen.com/subject/iboqdctx.html