V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
main1234
V2EX  ›  程序员

redis aof 持久化,设置 everysec 极端情况下会丢失 1 秒还是 2 秒数据?

  •  
  •   main1234 · 19 天前 · 886 次点击

    懵了,网上文章越看越懵,求大佬指点

    网上文章总结为 everysec 时候,会启动一个后台线程每隔一秒进行一次 fsync ,每次 fsync 结束就会记录刷盘时间

    1.主线在执行写命令时候,会检查刷盘时间

    2.如果 fsync 已完成,主线程直接写 AOF buf

    3.如果 fsync 未完成,检查上次刷盘时间

    a).上次刷盘时间在 2 秒内,主线程直接返回,不写 AOF buf
    
    b).上次刷盘时间在 2 秒外,主线程强制写 AOF buf
    

    我不理解 3a 步骤,不写 AOF buf 那这个命令不就丢了么?

    比如第 100ms 开始执行 fsync ,第 101ms 收到新的写命令为 set a 123 ,不写 AOF buf ,第 105ms 刷盘结束,那 set 命令不就丢了么

    求大佬指教

    11 条回复    2024-04-11 22:11:57 +08:00
    main1234
        1
    main1234  
    OP
       19 天前
    1.第 100ms 开始执行 fsync
    2.第 101ms 收到新的写命令为 set a 123 ,由于此时 fsync 没有完成切距离上次刷盘时间 2 秒内,不写 AOF buf
    3.第 105ms 刷盘结束,此时 AOF buf 中是没有 set a 123 命令的
    4.第 106ms 收到新的写命令为 hset ,写 AOF buf

    我不知道我理解的对不对,总感觉怪怪的,如果没问题的话那么岂不是会丢命令
    lsk569937453
        2
    lsk569937453  
       19 天前
    我理解 aof 的刷新策略为"appendfsync everysec"的时候,指的是异步线程刷盘的时间为 1 秒钟一次。主线程只要是写命令都会去继续写 AOF buf 。

    这样不断电的情况下是不会丢数据的。断电的情况下也只会丢失内存里 1 秒的 AOF buf 指令。

    https://github.com/redis/redis/blob/e3550f01dde29d5d1eaa37dbb4533692c5680f06/src/aof.c#L1052
    codegenerator
        3
    codegenerator  
       19 天前
    你这不是瞎掰么
    判断时间和控制都是主线程,写入和刷盘都是后台线程
    根本没有记录刷盘结束时间
    main1234
        4
    main1234  
    OP
       19 天前
    @codegenerator aof_last_fsync 这个字段就是刷盘时间
    zhuisui
        5
    zhuisui  
       19 天前
    你好像搞错了这一套流程。
    aof buffer 存放的是写命令,在内存里
    aof write 是把 aof buffer 写到文件里
    fsync 是把文件缓存内容同步到磁盘上
    zhuisui
        6
    zhuisui  
       19 天前
    至于 2s 的问题,fsync 的异步任务如果正在进行中,即使超过 2s ,也不会强制 fsync
    如果在这类场景,比如 bio fsync 任务的系统调用一直没返回、redis 出了 bug 、断电,出现问题,都不是该考虑的
    main1234
        7
    main1234  
    OP
       19 天前
    @zhuisui https://cloud.tencent.com/developer/article/1809891 所以这个文章里面说的是错的么
    zhuisui
        8
    zhuisui  
       19 天前
    @main1234 这 21 年的文章,我看的今天的源码。。。
    当时啥逻辑不知道了,你有兴趣去翻翻吧
    main1234
        9
    main1234  
    OP
       19 天前
    @zhuisui 求教下,也就是说命令都会写到 aof buffer ,如果 write 到 aof file 时候发现正在 fsync 则不会 write
    zhuisui
        10
    zhuisui  
       19 天前   ❤️ 1
    @main1234 如果 write 到 aof file 时候发现正在 fsync 则不会 "重复 fsync"
    codegenerator
        11
    codegenerator  
       18 天前
    @main1234 你对整个过程理解都是错的
    aof_last_fsync 是开始写文件的时间,而不是写完文件的时间
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2550 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 13:15 · PVG 21:15 · LAX 06:15 · JFK 09:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.