在 Redis 中, AOF 缓冲区和 AOF 重写缓冲区的区别是什么? - V2EX
shiziwen
V2EX    Redis

在 Redis 中, AOF 缓冲区和 AOF 重写缓冲区的区别是什么?

  •  
  •   shiziwen May 25, 2015 7099 views
    This topic created in 4004 days ago, the information mentioned may be changed or developed.

    请问在Redis中,AOF缓冲区和AOF重写缓冲区的区别是什么?
    设置AOF重写缓冲区,是为了在Redis在进行AOF重写期间引起的数据不一致问题,
    但是,所有的写命令都会写到AOF缓冲区和AOF重写缓冲区,这样的话,AOF缓冲区的内容应该是和AOF重写缓冲区的内容是一致的呀,AOF缓冲区也就可以替代AOF重写缓冲区了。

    是不是我哪里理解错了,多谢。

    8 replies    2018-06-20 21:53:08 +08:00
    nekoyaki
        1
    nekoyaki  
       May 26, 2015
    aof实际上就是文本格式的追加指令,所以随着使用,会变得越来越大越来越大。比如我有一个API,会让某值自增1。如果我调用一万次这个API,那这个指令在aof里就会记录一万次。
    aof重写的作用是,把这个很大很大的aof文件给重写,变得小一点。那一万次自增,会变成一条直接加到一万零一的数据。
    那么,有几个问题。
    1、aof重写的时候,是不是不应该阻塞主线程?
    2、如果重写的时候被中断了,怎么办?

    所以AOF重写缓冲区的意义就在这儿了。另起一个缓冲区,在别的线程里重写AOF,便于在重写完成前保证原aof的安全。
    /td>
    shiziwen
        2
    shiziwen  
    OP
       May 26, 2015
    @nekoyaki ,多谢。
    AOF重写缓冲区的作用,是为了避免数据不一致的发生,在重写完成后,会将AOF重写缓冲区的内容,同步到AOF缓冲区中。

    问题是,AOF重写的过程中,写操作是否也会追加到AOF缓冲区中。如果这样的话,AOF缓冲区和AOF重写缓冲区的内容,将会是一致的。
    看来得去看一下源码。
    fszaer
        3
    fszaer  
       May 28, 2015
    @shiziwen
    不对,并不是在重写完成后,将AOF重写缓冲区的内容,同步到AOF缓冲区中。
    实际上的过程应该是
    开始aof重写
    主程继续处理命令请求。
    将写命令追加到现有的 AOF 文件中。
    将写命令追加到 AOF 重写缓存中
    (这时aof缓存的内容由于已经写到aof文件和重写缓存中,不再需要保留,已经被释放了)。
    重写完成后将缓存写入到重写文件尾
    将文件改名覆盖原来的aof文件

    重写缓存主要是为了记录重写过程中的不同(主要是新增写/删等命令),并不会和缓存区保持一致,要保持一致的重写前的aof文件,aof重写文件还有数据库本身

    要了解redis设计与实现除了读官方源码以外,我无脑推荐《Redis 设计与实现 第二版》这本书,以及作者对源码的中文注释(对新手更友好)
    shiziwen
        4
    shiziwen  
    OP
       May 28, 2015
    @fszaer
    重写过程中,新建一个子进程进行重写。
    主进程继续处理客户端的命令请求,此时,写命令是追加到AOF缓存,还是追加到现有的AOF文件?
    重写的过程中,AOF缓存和AOF文件是一个什么状态?

    多谢。
    fszaer
        5
    fszaer  
       May 28, 2015
    @shiziwen
    啊,对不起 我也搞混了一点

    首先要说明的一点是,重写时并不影响aof持久化正常执行也不影响现有的aof缓存区跟aof文件。

    如果我们简化aof持久化的正常过程是新命令->缓存区->aof文件的顺序

    那么在执行重写时,而又有新命令的话
    就只是在新命令->缓存区
    这一过程的之间把命令复制一份到重写缓存区中
    事实上每次缓存区写入文件时都会检查是否在重写以判断需不需要写多一份到重写缓存区。
    所以我早上说的缓存区冲洗到aof文件之后再写到重写缓存区是错的

    但是两个缓存区依然是很难保持一致的
    虽然两个缓存区在新命令->缓存区这一步之后看上去是一致的(?),但是这是暂时的
    因为aof缓存区在写到aof文件中之后,会被清空或者直接指向一片新的内存空间,以便确保有足够的空间继续接受新的命令。显然,这之后两个缓存区就不再一致了。

    aof重写缓存区会一直保持从重写开始到结束所有写命令
    而aof缓存区会不断 写入-冲洗到aof文件-清除-写入 这一过程,因而只会保存一部分的命令
    他们并不一致

    假如只保留一个缓存区,就可能有以下麻烦
    没有办法很好分离两个功能互不影响
    标识重写过程中新增命令变得麻烦
    内存利用不够充分

    最后继续推荐《Redis 设计与实现 第二版》这本书,以及作者对源码的中文注释版
    fszaer
        6
    fszaer  
       May 29, 2015
    @fszaer
    勘误,
    事实上每次缓存区写入文件时都会检查是否在重写以判断需不需要写多一份到重写缓存区。
    这里应该是
    每次有新命令写入缓存区时时都会检查是否在重写,以判断需不需要写多一份到重写缓存区。
    最近脑子老是秀逗=、=
    ccqy66
        7
    ccqy66  
       May 4, 2018
    说一下个人的理解吧:
    AOF 缓冲区的作用:目的是维持主线程 AOF 文件的正常写入,保证在重写阶段,AOF 文件写入的逻辑不变。
    AOF 重写缓存区作用:目的是记录 AOF 重写开始之后的键增删改的命令。
    这两个缓冲区缺一不可。具体原因如下:
    AOF 缓冲区的内容会根据 appendfsync 策略的不同而不同,如果 appendfsync=always,那么每次命令都会立即被刷入到磁盘里,可能 AOF 缓存区就没有数据。而 AOF 重写缓存区一定是从重写开始之后所有的键增删改的命令。两个缓冲区从存在意义上来看是完全不一样的,前者侧重于功能,后者更加侧重于备份。
    XDMonkey
        8
    XDMonkey  
       Jun 20, 2018
    @ccqy66 实际上两个缓冲区就是对应重写前后的两个 AOF 文件吧 我的理解
    About     Help     Advertise     Blog     API     FAQ     Solana     3485 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 42ms UTC 12:09 PVG 20:09 LAX 05:09 JFK 08:09
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86