Redis 4.0 从节点写入不同步问题

redis4.0出现了很多新的特性,删除键值unlink,slowlog记录来源ip。内存统计信息等。其中一个重要的同步祭祀是Psync2。psync2主要让redis在从实例重启和主实例故障切换场景下,也能使用部分重新同步。在redis故障切换,新增从库,网络波动。都可以有效的避免网络风暴。但也存在一个问题。从节点的写入是不会同步给下一级从节点的。如 A>B>C    在B执行set test xxxx 。C是接收不到key test的。同步信息必须是来源于最根据的master节点。

这与psync2的实现有关:

master_replid  :长度为41个字节的字符串。每个实例都有。如果是主节点,则标志这个节点的自身id。如果是从节点。则master_replid 是起最终主节点的master_replid 。

master_replid2:用于存在该节点上一次连接主实例的实例master_replid。

有复制链A(100.100)>B(100.88)>C (1.37):

A echo "info Replication" | redis-cli -h 192.168.100.100  -p 6013

B

C

此时 B C 的master_replid 都来源于 A 的master_replid:28ab33a841d0b1db7d0586b120e213970bed2261 。在C 只接收来自于A的写入。 B的写入不能同步到C 。如下:

如果B slaveof no one 提升B 为主。复制链变成了B>C   B是根节点。此时B写入C可以正常接收。注意看master_replid

B

C

B生成了新的master_replid:1014ea08c4c84cd51cccaa7c9c723c067dcd7b06。并且其从节点的master_replid 变为B 的master_replid 1014ea08c4c84cd51cccaa7c9c723c067dcd7b06 。原来的 A的master_replid 归档进了master_replid2。

4.0在整个复制集群中通过master_replid 和master_repl_offset 使得每个从节点的偏移量都是相对于最原始的主节点(无论串型还是星型)。这样复制从节点的切换主节点,不需要再进行全同步。只需部分同步。A>B>C   变为 A>B A>C    。或者B>A B>A>C

或者 B>A (B slave no one后 。A 根据自身master_replid向B 请求部分同步 。B 的master_replid2存放了Amaster_replid 。所以可以部分同步 )

逻辑是。每次slaveof 本节点会拿自身的master_replid  master_repl_offset 去寻找目标节点的 master_replid  master_replid2 和offset。如果匹配到则可增量同步。

重启从节点的时候。一定要把slaveof写入到配置文件中再重启。这样才可以部分同步。如果启动完节点再自行slaveof则需要全同步。

同样的,在扩展从节点的时候也可以先在主节点dump一份数据。然后rsync到别的机器。在配置文件配置好slaveof。启动redis这样可以部分同步,避免网络风暴。

但主节点A重启会导致 master_replid 变动。最终导致从节点重新全同步。是否有办法保持master_replid不变??? 

除了本身是master节点。slave节点执行slave one 导致master_replid 更新。且 master_replid2 不会保留自身生成的master_replid 。如slaveof no one之后再slave xx xx 。master_replid2 会是空的。

A>B>C 。B执行slave no one 不会导致C全同步,此时B是master。但是B 再slaveof xx xx (那么是slaveof A ) 都会导致C重新全同步。因为B master_replid2 保留自身slave no one后生成的master_replid 。C在同步的时候在B中找不到replid

 

posted @ 2018-06-03 21:40  vansky  阅读(2197)  评论(0编辑  收藏  举报