《Redis设计与实现》读书笔记(二十五) ——Redis主从复制具体过程

《Redis设计与实现》读书笔记(二十五)

——Redis主从复制具体过程

(原创内容,转载请注明来源,谢谢)

一、PSYNC命令执行过程

psync是新版redis复制使用的命令,下面讨论其执行过程。

psync命令调用方法有两种:

1)从服务器以前如果没有复制过任何主服务器,或者执行过slaveof no one命令,则第一次复制会发送psync ? -1命令,表示强制要求主服务器进行完全重同步。

2)如果从服务器以前复制过主服务器,则会发送psync <runid> <offset>,将主服务器的运行ID和从服务器当前自身复制偏移量发送给主服务器,由主服务器判断是要部分重同步还是完全重同步。

主服务器的回复有三种:

1)+fullresync<runid> <offset>,则表示要完全重同步。从服务器会记录runid,作为下次断线重连发送的内容;将offset作为从服务器当前的偏移量。

2)+continue,表示部分重同步,从服务器只需要等待主服务器将缺少的部分发送过来,再进行同步即可。

3)-err,表示主服务器版本低于2.8,不支持psync,则从服务器会再发送sync命令,进行完整同步。

如下图所示:

二、复制的实现

复制采用的命令是slaveof<masterip> <masterport>,详细实现步骤如下:

1、设置主服务器的ip和端口

执行上述命令后,从服务器会将主服务器的ip和端口设置在自身redisServer结构体中的属性中,ip设置到char数组的masterhost名称,port设置到int的masterport。

设置完成后,从服务器会向客户端返回OK。

2、建立套接字连接

执行slaveof命令后,从服务器将根据ip和端口号,与主服务器建立套接字连接。

从服务器成功连接主服务器后,从服务器将为该连接专门创建一个用于复制工作的文件事件处理器,这个处理器接收rdb文件、处理主服务器的命令传播等。

主服务器接收到从服务器的套接字连接后,为套接字创建相应的状态,并将从服务器看作一个连接到主服务器的客户端,此时从服务器同时具有客户端和服务器两个身份,从服务器可以向主服务器发送命令请求,主服务器会向从服务器发送命令回复。

3、发送PING命令

从服务器连接上主服务器后,会先发送一个PING命令,具有两个作用:

1)检查主从服务器的套接字读写状态是否正常。

2)检查主服务器当前可以正常处理请求。

从服务器会收到主服务器的三种回复的一种:

1)主服务器向从服务器回复内容,从服务器不能在规定时限内读取命令内容,则认为主从服务器当前网络不佳,无法处理后续的同步工作。从服务器会断开套接字,再自动重连并重新创建向主服务器的套接字。

2)主服务器向从服务器回复一个错误,表示主服务器当前无法处理从服务器的请求,从服务器会断开并重新创建向主服务器的套接字。

3)从服务器接收到主服务器的PONG回复,表示主从服务器网络正常,主服务器当前可以处理从服务器的命令,则从服务器会进入后续的步骤。

PING命令判断流程如下:

4、身份验证

从服务器收到PONG后,将进入身份验证阶段。

如果其有设置masterauth选项,则开始身份验证,否则不验证。如果需要验证,则从服务器接下来会给主服务器发送auth命令,并带上masterauth选项的值作为参数。

身份验证阶段会有以下几个结果:

1)主服务器没有设置requirepass选项,从服务器也没有设置masterauth,则跳过身份验证。

2)主服务器没有设置requirepass,而从服务器设置masterauth,会报noauth错误。

3)主服务器设置requirepass,而从服务器没有设置masterauth,会报nopassword is set错误。

所有错误都会终止当前的复制工作,并从创建套接字开始重新执行复制,直到验证通过。

5、发送端口信息

身份验证通过后,从服务器会向主服务器发送replconf listening-port <port-number>命令,向从服务器监听端口号。

主服务器接收到端口号后,会将其记录在对应客户端redisClient结构体中的属性中,类型是int,名称是slave-listening-port。该属性目前唯一作用是主服务器执行info replication命令时,打印出从服务器的端口号。

6、同步

完成上述步骤后,从服务器会发送psync给主服务器。

在同步操作之前,只有从服务器是主服务器的客户端,而同步之后,主服务器也是从服务器的客户端,即互为客户端。

这样主服务器才可以将保存在缓冲区的写命令(完整重同步)、保存在复制积压缓冲区(部分重同步)中的写命令发给从服务器。

7、命令传播

完成同步后,后续只要主服务器状态改变,都会给从服务器发送写命令,从服务器执行写命令后,就保证主从一致性。

六、心跳检测

在命令传播阶段,从服务器默认每秒1次的频率,向主服务器发送如下命令:

         replconfack <replication_offset>

replication_offset是从服务器的偏移量,发送此命令有三个作用:

1、检测主从服务器网络状态。

如果主服务器超过1秒没有接收到从服务器的replconfack命令,表示主从间的连接出问题了。info replication命令可以查看从服务器最后一次发送该命令的时间,属性值是lag,即lag大于1表示出问题了。

2、辅助实现min-slaves选项。

redis的min-slaves-to-write和min-slaves-max-lag两个选项可以在主服务器不安全的情况下,防止执行客户端的写命令。

例如min-slaves-to-write3,min-slaves-max-lag 10,表示少于3个从服务器或三个从服务器的延迟(lag)值都大于等于10秒,主服务器将拒绝执行写命令。

3、检测命令丢失。

由于每次发送replconfack命令,都带上当前的偏移量,这样就可以保证如果主服务器发送给从服务器的命令传播,由于网络问题导致数据丢失的问题能1秒内被主服务器发现。主服务器发现后,会将相应偏移量的内容从复制积压缓冲区取出,并发送给从服务器。

replconfack命令和复制积压缓冲区的概念,都是从redis2.8开始有的,在此之前的版本,主服务器无法发现从服务器的数据丢失。因为使用主从的情况下,为了数据一致性,尽量使用2.8以上版本的redis。

七、总结

1、redis2.8之前的版本,主从复制中,每次从服务器断线重连后,都要进行整个服务器的同步;而2.8版本开始,在一定情况下,可以实现部分重同步。

2、部分重同步是通过复制偏移量来判断是否需要,通过复制积压缓冲区来取出偏移量范围内的全部数据,通过从服务器发送给主服务器的主服务器运行ID来判断上一次从服务器连接的主服务器与此次连接是否一致。

3、如果复制偏移量超出复制积压缓冲区,或者从服务器发送的运行ID和主服务器当前运行ID不一致,或者主服务器的redis版本在2.8之前,都会进行完全重同步。

4、复制刚开始,从服务器是客户端,到开始同步的时候,主从服务器互为客户端。

5、复制过程包括:从服务器设置主服务器ip和端口;建立套接字;发送PING命令;身份验证;发送端口信息;同步;命令传播。

6、当主从进入命令传播阶段,从服务器每秒(时间可配置)给主服务器发送一条命令,内容是当前从服务器的偏移量,以确保主从网络正常,并且如果偏移量和主服务器当前的不一致,也便于主服务器再次发送偏移数据,以保证主从数据一致性。

7、由于效率以及数据一致性,如果要采用主从同步,建议使用redis2.8或以上的版本。

——written by linhxx 2017.09.12

原文发布于微信公众号 - 决胜机器学习(phpthinker)

原文发表时间:2017-09-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏我是攻城师

如何在Scala中读取Hadoop集群上的gz压缩文件

2874
来自专栏性能与架构

使用Docker创建MongoDB复制集

MongoDB复制集由一组MongoDB实例节点组成,包含一个Primary节点、多个Secondary节点 客户端写入的数据会被写入Primary节点,Sec...

3535
来自专栏待你如初见

Zookeeper与Solr 概述 部署 Solr Cloud

845
来自专栏Laoqi's Linux运维专列

Tomcat搭建高可用/负载均衡/动静分离的Web服务器集群

1532
来自专栏Hadoop实操

如何在CDH中使用HBase的ACLs进行授权

1894
来自专栏Linux运维学习之路

Linux中如何恢复rm命令误删除的文件之extundelete编译安装及使用

1、下载extundelete包,安装依赖 我用的是Centos系统,在安装extundelete之前需要安装e2fsprogs,e2fsprogs-libs,...

4608
来自专栏张戈的专栏

【 ES 私房菜】ElasticSearch 详细部署教程

Elasticsearch 是一个分布式的 RESTful 风格的搜索和数据分析引擎,能够解决不断涌现出的各种用例。本文详细介绍了elasticserch的部署...

8131
来自专栏Java后端技术

Centos7下安装redis实战(单机版以及集群)

  因项目需要,要引入redis做缓存,就在centos7下亲自安装了一遍redis,刚好趁着这个机会就来把redis的概念以及单机版和集群版redis安装步骤...

631
来自专栏蓝天

安装hue-3.11.0

1) 配置HDFS HttpFS和WebHDFS 如果HDFS是HA方式部署的,则只能使用HttpFS,而不能用WebHDFS。 2) 安装依赖: ...

571
来自专栏Python研发

五分钟看懂Celery定时任务

1, Web应用。 当用户触发的一个操作需要很长时间才能执行完成,那么就可以把它当做一个任务去交给Celery去异步执行, 执行完成之后再返回给用户,这短时间用...

692

扫码关注云+社区