美文网首页架构技术干货
Redis入门——复制原理(一)

Redis入门——复制原理(一)

作者: 小汉同学 | 来源:发表于2018-07-17 23:19 被阅读209次
池田依来沙(女神(〃'▽'〃))

Redis入坑第二步,也是学起来有点吃力的内容。在分布式系统中为了解决单点问题,经常会把数据复制多个副本部署到其他机器上,实现负载均衡和故障恢复等需求。Redis也提供了复制功能,实现相同数据的多个副本。复制功能是Redis很常用、很重要的基础,学习研究吃透复制原理,对Redis的使用以及日后开发运维都有很大的帮助。(参考付磊、张益军两位大神的《Redis开发与运维》

复制过程

主从节点复制流程图.jpg

1、保存主节点(Master)信息
执行slaveof命令后从节点只保存主节点的地址信息便直接返回了,这时建立复制流程还没有开始。

2、从节点(Slave)内部通过每秒运行的定时任务维护复制相关逻辑,当定时任务发现存在新的节点后,会尝试与该节点建立网络连接。


从节点与主节点建立socket连接

从节点会建立一个socket(如图中的127.0.0.1:6379套接字),专门用于接受主节点发送的复制命令。
当然,如果无法建立连接,定时任务会无限重试直到连接成功或者执行slaveof no one取消复制。

3、发送ping命令
连接建立成功后从节点发送ping请求进行首次通信,ping请求的主要目的是:

  • 检测主从节点之间socket是否可用
  • 检测主从节点当前是否可接受处理命令
    如果发送ping命令后,从节点没有收到主节点的pong回复或者超时,比如网络超时或者主节点正在阻塞无法响应命令,从节点会断开复制连接,下次定时任务会发起重连。如下图


    主从节点建立连接过程
从节点发送ping命令过程

4、权限验证。
如果主节点设置了requirepass参数,则需要密码验证,从节点必须配置masterauth参数保证与主节点相同的密码才能通过验证。如果验证失败复制将终止,从节点重新发起复制流程。

5、同步数据集。
主从复制连接正常通信后,对于首次建立复制的场景,主节点会把持有的数据全部发送到从节点,这部分操作是耗时最长的步骤。
PS.Redis在2.8之后采用了新复制命令psync进行数据同步,原来的sync命令依然支持。新版同步分为:全量同步和部分同步

6、命令持续复制。
当主节点把当前的数据同步到从节点后,便完成了复制的建立流程。接下来主节点会持续地把写命令发送给从节点,保证主从数据一致性。

数据同步

Redis在2.8及以上版本使用psync命令完成主从数据同步,同步过程分为:全量复制和部分复制。
psync命令运行需要以下组件支持:

  • 主从节点各自复制偏移量
  • 主节点复制积压缓冲区
  • 主节点运行id

1、复制偏移量
参与复制的主从节点都会维护自身复制偏移量。主节点(master)在处理完写入命令后,会把命令的字节长度做累加记录,统计信息在info replication中的master_repl_offset指标中。
从节点(slave)每秒钟上报自身的复制偏移量给主节点,因此主节点也会保存从节点的复制偏移量。从节点在接收到主节点发送的命令后,也会累加记录自身的偏移量。其统计信息在info replication中的slave_repl_offset指标值中。
所以我们可以通过对比主从节点的复制偏移量,来判断主从节点数据是否一致。计算master_repl_offset-slave_repl_offset字节量,判断相差的数据量。如果相差不大,则说明复制比较健康,反之,则可能出现网络延迟或命令阻塞。

2、复制积压缓冲区
复制积压缓冲区是保存在主节点上的一个固定长度的队列,默认大小为1MB。
当主节点有连接的从节点时,主节点(master)响应写命令时,不但会把命令发送给从节点,还会写入复制积压缓存区。
由于缓冲区本质上是先进先出的定长队列,所以能实现保存最近已复制数据的功能,用于部分复制和复制命令丢失的数据补救。

3、主节点运行ID
每个Redis节点启动后都会动态分配一个40位的十六进制字符串作为运行ID。运行ID的主要作用是用来唯一识别Redis节点,比如从节点保存主节点的运行ID识别自己正在复制的是具体哪个主节点。
如果使用ip+port方式识别主节点,那么主节点重启变更了整体数据集(如替换RDB/AOF文件),从节点再基于偏移量复制数据将会不安全,所以当运行ID变化后从节点将做全量复制。(全量复制等具体会在下一节讲解)

4、psync命令
前面有讲到Redis 2.8之后同步使用psync命令,但也支持sync命令,不过建议使用psync命令和Redis 2.8以上版本。
命令格式:pysnc {runId} {offset}

  • runId: 从节点所复制主节点的运行id
  • offset:当前从节点已复制的数据偏移量
psync运行流程

如上图所示,具体流程为:

  • 从节点(slave)发送psync命令给主节点(master),参数runId是当前从节点保存的主节点运行ID,如果没有则默认为?,参数offset是当前从节点保存的复制偏移量,如果是第一次参与复制则默认为-1.
  • 主节点(master)根据psync参数和自身数据情况决定响应结果:
    1)如果回复+FULLRESYNC {runId} {offset},则说明触发全量复制流程
    2)如果回复+CONTINUE,则说明触发部分复制流程
    3)如果回复-ERR,说明Redis版本低于2.8,psync命令识别不了,从节点将会发送旧版的sync命令触发全量复制。

小结
写这个入门博客的同时,我也在学习研究,文中有很多内容是借鉴学习书籍和其他博客的,有些偏理论性,接下来的博客会尽量用些代码实例、比喻例子,希望这个入门博客既能总结自己学习成果,又能分享给大家一些知识。接下来,要更加努力,加把劲!

相关文章

网友评论

    本文标题:Redis入门——复制原理(一)

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