灵魂拷问-Redis-主从复制中为什么需要两个Buffer(replication buffer 、repl backlog buffer)?

1,499 阅读3分钟

背景

我们都知道在Redis主从同步分为两个阶段:全量复制阶段和增量复制阶段,这两个阶段很好理解。但是这两个阶段中具体涉及到缓存区问题,对于在这两个阶段使用缓冲区能够理解,核心作用:暂存数据,避免发送网路请求阻塞主线程处理命令,而自己在其学习过程中有点费解,出现了一个触及灵魂的问题:为什么需要设计两个,只保留其中一个行吗

为什么需要设计两个,只保留其中一个行吗?

首先,我们了解一下replication buffer 、repl backlog buffer基本情况:

  1. replication buffer 是在全量复制阶段会出现,主库会给每个新连接的从库,分配一个replication buffer;repl backlog buffer 是在增量复制阶段出现,一个主库只分配一个repl backlog buffer。
  2. 每个Buffer都有大小限制的,当缓冲区满了之后。repl backlog buffer,因为是环形结构,会直接覆盖起始位置数据,replication buffer则会导致连接断开,删除缓存,从库重新连接,重新开始全量复制 其次,我思考这两个阶段的特点如下: | 阶段 | 特点 | | --- | --- | | 全量复制 | 1.不同从库连接上主库的时机大不一致(有些可能已经复制完毕,进入下个阶段;有些可能刚刚开始复制),导致初始复制数据也不一样 2.这个阶段,从库接收到数据之后,处理时间会很比较长,然后处理好了在跟主库同通信| | 增量复制 | 1.从库间处理进度差距不大 2.从库会频繁的与主库进行通信,同步增量数据,每次处理数据量不大,同时很快|

然后,做个方案对比:

方案优点缺点适用场景
replication buffer相互隔离,不会数据覆盖情况每次执行的命令都需要复制N分到对应的Buffer里面、消耗内存、影响性能从库间处理进度大不一样
repl backlog buffer节省内存,不影响性能数据覆盖,影响从库想同步的数据,缓冲区里面没有,会导致从库要么丢失数据,要么重新全量复制从库间处理进度差距不大,而且主要处理速度快

其实通过优缺点可以看出来他们两个刚好是互补的,然后结合自我思考的全量复制、增量复制阶段的特点,刚好和这两个优点对应上,采用两两种结构,刚好也避免其缺点。这下算是明白为什么需要两种而不是只需要一种了。

总结

  1. replication buffer 、repl backlog buffer设计都是紧紧结合不同处理流程的特点,其实我们日常设计技术方案的时候也一定要紧密的和我们的业务场景特点相结合,每个技术方案都有其优缺点,只有和其正确场景所对应上,才能使其最大限度做到扬长避短。
  2. replication buffer 、repl backlog buffer 对于自身大小溢出之后的处理方式也不太一样,这个也需要注意关注的
  3. replication buffer和repl backlog buffer个人认为是有联系的,因为当从库同步好了replication buffer数据之后,需要转向从repl backlog buffer开始同步数据,这里就涉及到从repl backlog buffer哪里开始同步呢?我们都知道repl backlog buffer存在偏移量的说法,我觉得这个偏移量不仅在repl backlog buffer存在,也存在于replication buffer至少保持一致了的,这样做到无痕切换,知道从哪里读取数据?

(PS:其中涉及特点、优缺点总结等等都是个人思考,如有理解错误或者与官方设计/官方源码处理存在出入,欢迎指出,可以更正学习)