《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 条评论
登录 后参与评论

相关文章

来自专栏Golang语言社区

Linux下突破限制实现高并发量服务器

1、修改用户进程可打开文件数限制 在Linux平台上,无论编写客户端程序还是服务端程序,在进行高并发TCP连接处理时,最高的并发 数 量都要受到系统对用户单一进...

5004
来自专栏吴伟祥

Redis实现消息队列 转

打开浏览器,输入地址,按下回车,打开了页面。于是一个HTTP请求(request)就由客户端发送到服务器,服务器处理请求,返回响应(response)内容。

511
来自专栏佳爷的后花媛

tp中遇到的相关方法

getDbFields 这个方法在tp手册的字段定义中 通常每个模型类是操作某个数据表,在大多数情况下,系统会自动获取当前数据表的字段信息。 系统会在模型...

1012
来自专栏散尽浮华

针对负载均衡集群中的session解决方案的总结

在日常运维工作中,当给Web站点使用负载均衡之后,必须面临的一个重要问题就是Session的处理办法,无论是PHP、Python、Ruby还是Java语言环境,...

19811
来自专栏杂烩

Redis linux下安装配置 原

make命令执行完成后,会在当前目录下生成本个可执行文件,分别是redis-server、redis-cli、redis-benchmark、redis-sta...

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

负载均衡集群中的session解决方案

1554
来自专栏IT笔记

Tomcat优化之配置线程池

简介 线程池作为提高程序处理数据能力的一种方案,应用非常广泛。大量的服务器都或多或少的使用到了线程池技术,不管是用Java还是C++实现,线程池都有如下的特点:...

2848
来自专栏文渊之博

MySQL常见备份方案

2100
来自专栏企鹅号快讯

MySQL主从复制的实现过程

推荐阅读 微服务:springboot系列教程学习 源码:Javaweb练手项目源码下载 调优:十五篇好文回顾 面试笔试:面试笔试整理系列 一、什么是主从复制 ...

2117
来自专栏决胜机器学习

RabbitMQ(一)简介

RabbitMQ(一)——简介 (原创内容,转载请注明来源,谢谢) 一、概述 RabbitMQ是一种消息的传输者(broker),除了消息持久化,不对消息内容本...

3024

扫描关注云+社区