Redis——主从复制

摘要:
前言Redis高可用性解决方案包括持久性、主从复制、哨兵和集群。Persistence专注于Redis数据的独立备份;主从复制侧重于多台机器上数据的热备用。默认情况下,每个Redis服务器都是主节点;主节点可以有多个从节点,但从节点只能有一个主节点。上述三种方法是等效的。让我们以客户端命令方法为例,看看执行slaveof后Redis主节点和从节点的变化。
前言

Redis高可用的方案包括持久化、主从复制(及读写分离)、哨兵和集群。其中持久化侧重解决的是Redis数据的单机备份问题(从内存到硬盘的备份);

而主从复制则侧重解决数据的多机热备。此外,主从复制还可以实现负载均衡和故障恢复。

一、主从复制概述

主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave);数据的复制是单向的,只能由主节点到从节点。

默认情况下,每台Redis服务器都是主节点;且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。

主从复制的作用

  1. 数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
  2. 故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。
  3. 负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。
  4. 高可用基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础。
二、如何使用主从复制

 为了更直观的理解主从复制,在介绍其内部原理之前,先说明我们需要如何操作才能开启主从复制。

1. 建立复制

需要注意,主从复制的开启,完全是在从节点发起的;不需要我们在主节点做任何事情。

从节点开启主从复制,有3种方式:

  • (1)配置文件

在从服务器的配置文件中加入:slaveof <masterip> <masterport>

  • (2)启动命令

redis-server启动命令后加入 --slaveof <masterip> <masterport>

  • (3)客户端命令

Redis服务器启动后,直接通过客户端执行命令:slaveof <masterip> <masterport>,则该Redis实例成为从节点。

上述3种方式是等效的,下面以客户端命令的方式为例,看一下当执行了slaveof后,Redis主节点和从节点的变化。

2. 实例

  • 准备工作:启动两个节点

方便起见,实验所使用的主从节点是在一台机器上的不同Redis实例,其中主节点监听6379端口,从节点监听6380端口;从节点监听的端口号可以在配置文件中修改:

Redis——主从复制第1张

启动后可以看到:

Redis——主从复制第2张

两个Redis节点启动后(分别称为6379节点和6380节点),默认都是主节点。

  • 建立复制

此时在6380节点执行slaveof命令,使之变为从节点:

Redis——主从复制第3张

  • 观察效果

下面验证一下,在主从复制建立后,主节点的数据会复制到从节点中。

(1)首先在从节点查询一个不存在的key:

Redis——主从复制第4张

(2)然后在主节点中增加这个key:

Redis——主从复制第5张

(3)此时在从节点中再次查询这个key,会发现主节点的操作已经同步至从节点:

Redis——主从复制第6张

(4)然后在主节点删除这个key:

Redis——主从复制第7张

(5)此时在从节点中再次查询这个key,会发现主节点的操作已经同步至从节点:

Redis——主从复制第8张

3. 断开复制

通过slaveof <masterip> <masterport>命令建立主从复制关系以后,可以通过slaveof no one断开。需要注意的是,从节点断开复制后,不会删除已有的数据,只是不再接受主节点新的数据变化。

从节点执行slaveof no one后,打印日志如下所示;可以看出断开复制后,从节点又变回为主节点。

Redis——主从复制第9张

主节点打印日志如下:

Redis——主从复制第10张

三、主从复制实现原理

主从复制过程大体可以分为3个阶段:连接建立阶段(即准备阶段)、数据同步阶段、命令传播阶段;下面分别进行介绍。

1. 连接建立阶段

该阶段的主要作用是在主从节点之间建立连接,为数据同步做好准备。

  • 步骤1:保存主节点信息

从节点服务器内部维护了两个字段,即masterhost和masterport字段,用于存储主节点的ip和port信息。

需要注意的是,slaveof是异步命令,从节点完成主节点ip和port的保存后,向发送slaveof命令的客户端直接返回OK,实际的复制操作在这之后才开始进行。

这个过程中,可以看到从节点打印日志如下:

Redis——主从复制第11张

  • 步骤2:建立socket连接

从节点每秒1次调用复制定时函数replicationCron(),如果发现了有主节点可以连接,便会根据主节点的ip和port,创建socket连接。如果连接成功,则:

从节点:为该socket建立一个专门处理复制工作的文件事件处理器,负责后续的复制工作,如接收RDB文件、接收命令传播等。

主节点:接收到从节点的socket连接后(即accept之后),为该socket创建相应的客户端状态,并将从节点看做是连接到主节点的一个客户端,后面的步骤会以从节点向主节点发送命令请求的形式来进行。

这个过程中,从节点打印日志如下:

Redis——主从复制第12张

  • 步骤3:发送ping命令

从节点成为主节点的客户端之后,发送ping命令进行首次请求,目的是:检查socket连接是否可用,以及主节点当前是否能够处理请求。

从节点发送ping命令后,可能出现3种情况:

(1)返回pong:说明socket连接正常,且主节点当前可以处理请求,复制过程继续。

(2)超时:一定时间后从节点仍未收到主节点的回复,说明socket连接不可用,则从节点断开socket连接,并重连。

(3)返回pong以外的结果:如果主节点返回其他结果,如正在处理超时运行的脚本,说明主节点当前无法处理命令,则从节点断开socket连接,并重连。

在主节点返回pong情况下,从节点打印日志如下:

Redis——主从复制第13张

  • 步骤4:身份验证

如果从节点中设置了masterauth选项,则从节点需要向主节点进行身份验证;没有设置该选项,则不需要验证。从节点进行身份验证是通过向主节点发送auth命令进行的,auth命令的参数即为配置文件中的masterauth的值。

如果主节点设置密码的状态,与从节点masterauth的状态一致(一致是指都存在,且密码相同,或者都不存在),则身份验证通过,复制过程继续;如果不一致,则从节点断开socket连接,并重连。

  • 步骤5:发送从节点端口信息

身份验证之后,从节点会向主节点发送其监听的端口号(前述例子中为6380),主节点将该信息保存到该从节点对应的客户端的slave_listening_port字段中;

该端口信息除了在主节点中执行info Replication时显示以外,没有其他作用。

2. 数据同步阶段

主从节点之间的连接建立以后,便可以开始进行数据同步,该阶段可以理解为从节点数据的初始化。具体执行的方式是:从节点向主节点发送psync命令(Redis2.8以前是sync命令),开始同步。

数据同步阶段是主从复制最核心的阶段,根据主从节点当前状态的不同,可以分为全量复制和部分复制,下面会有一章专门讲解这两种复制方式以及psync命令的执行过程,这里不再详述。

需要注意的是,在数据同步阶段之前,从节点是主节点的客户端,主节点不是从节点的客户端;而到了这一阶段及以后,主从节点互为客户端。

原因在于:在此之前,主节点只需要响应从节点的请求即可,不需要主动发请求,而在数据同步阶段和后面的命令传播阶段,主节点需要主动向从节点发送请求(如推送缓冲区中的写命令),才能完成复制。

3. 命令传播阶段

数据同步阶段完成后,主从节点进入命令传播阶段;在这个阶段主节点将自己执行的写命令发送给从节点,从节点接收命令并执行,从而保证主从节点数据的一致性。

在命令传播阶段,除了发送写命令,主从节点还维持着心跳机制:PING和REPLCONF ACK。由于心跳机制的原理涉及部分复制,因此将在介绍了部分复制的相关内容后单独介绍该心跳机制。

延迟与不一致

需要注意的是,命令传播是异步的过程,即主节点发送写命令后并不会等待从节点的回复;因此实际上主从节点之间很难保持实时的一致性,延迟在所难免。

数据不一致的程度,与主从节点之间的网络状况、主节点写命令的执行频率、以及主节点中的repl-disable-tcp-nodelay配置等有关。

repl-disable-tcp-nodelay no:该配置作用于命令传播阶段,控制主节点是否禁止与从节点的TCP_NODELAY;默认no,即不禁止TCP_NODELAY。

当设置为yes时,TCP会对包进行合并从而减少带宽,但是发送的频率会降低,从节点数据延迟增加,一致性变差;具体发送频率与Linux内核的配置有关,默认配置为40ms。

当设置为no时,TCP会立马将主节点的数据发送给从节点,带宽增加但延迟变小。

一般来说,只有当应用对Redis数据不一致的容忍度较高,且主从节点之间网络状况不好时,才会设置为yes;多数情况使用默认值no。

四、应用中的问题

1. 复制相关的配置

这一节总结一下与复制有关的配置,说明这些配置的作用、起作用的阶段,以及配置方法等;通过了解这些配置,一方面加深对Redis复制的了解,另一方面掌握这些配置的方法,可以优化Redis的使用,少走坑。

配置大致可以分为主节点相关配置、从节点相关配置以及与主从节点都有关的配置,下面分别说明。

  • 主从节点都有关的配置

首先介绍最特殊的配置,它决定了该节点是主节点还是从节点:

1)   slaveof <masterip> <masterport>:Redis启动时起作用;作用是建立复制关系,开启了该配置的Redis服务器在启动后成为从节点。该注释默认注释掉,即Redis服务器默认都是主节点。

2)   repl-timeout 60:与各个阶段主从节点连接超时判断有关,见前面的介绍。

  • 主节点相关配置

1)   repl-diskless-sync no:作用于全量复制阶段,控制主节点是否使用diskless复制(无盘复制)。所谓diskless复制,是指在全量复制时,主节点不再先把数据写入RDB文件,而是直接写入slave的socket中,整个过程中不涉及硬盘;diskless复制在磁盘IO很慢而网速很快时更有优势。需要注意的是,截至Redis3.0,diskless复制处于实验阶段,默认是关闭的。

2)   repl-diskless-sync-delay 5:该配置作用于全量复制阶段,当主节点使用diskless复制时,该配置决定主节点向从节点发送之前停顿的时间,单位是秒;只有当diskless复制打开时有效,默认5s。之所以设置停顿时间,是基于以下两个考虑:(1)向slave的socket的传输一旦开始,新连接的slave只能等待当前数据传输结束,才能开始新的数据传输 (2)多个从节点有较大的概率在短时间内建立主从复制。

3)   client-output-buffer-limit slave 256MB 64MB 60:与全量复制阶段主节点的缓冲区大小有关,见前面的介绍。

4)   repl-disable-tcp-nodelay no:与命令传播阶段的延迟有关,见前面的介绍。

5)   masterauth <master-password>:与连接建立阶段的身份验证有关,见前面的介绍。

6)   repl-ping-slave-period 10:与命令传播阶段主从节点的超时判断有关,见前面的介绍。

7)   repl-backlog-size 1mb:复制积压缓冲区的大小,见前面的介绍。

8)   repl-backlog-ttl 3600:当主节点没有从节点时,复制积压缓冲区保留的时间,这样当断开的从节点重新连进来时,可以进行部分复制;默认3600s。如果设置为0,则永远不会释放复制积压缓冲区。

9)   min-slaves-to-write 3与min-slaves-max-lag 10:规定了主节点的最小从节点数目,及对应的最大延迟,见前面的介绍。

  • 从节点相关配置

1)   slave-serve-stale-data yes:与从节点数据陈旧时是否响应客户端命令有关,见前面的介绍。

2)   slave-read-only yes:从节点是否只读;默认是只读的。由于从节点开启写操作容易导致主从节点的数据不一致,因此该配置尽量不要修改。

2. info Replication

在Redis客户端通过info Replication可以查看与复制相关的状态,对于了解主从节点的当前状态,以及解决出现的问题都会有帮助。

主节点:

Redis——主从复制第14张

从节点:

Redis——主从复制第15张

对于从节点,上半部分展示的是其作为从节点的状态,从connectd_slaves开始,展示的是其作为潜在的主节点的状态。

五、总结

主从复制虽然解决或缓解了数据冗余、故障恢复、读负载均衡等问题,但其缺陷仍很明显:故障恢复无法自动化;写操作无法负载均衡;存储能力受到单机的限制;

这些问题的解决,需要哨兵和集群的帮助。

转载:https://www.cnblogs.com/kismetv/p/9236731.html

免责声明:文章转载自《Redis——主从复制》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇JAVA中事物以及连接池ActivePerl 安装下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

redis发布订阅

三个角色,提供的redis命令 1.发布者 publish 频道 消息 给频道发消息 2.订阅者 SUBSCRIBE 频道 订阅频道 PSUBSCRIBE 频道*支持模糊匹配的订阅 3.频道 channel 频道名 自定义 redis持久化之RDB 1.在配置文件中添加参数,开启rdb...

网络编程,从socket到epoll

网络编程,从socket到epoll 参考链接:https://www.bilibili.com/video/BV11Z4y157RY?p=2&spm_id_from=pageDriver socket基本知识: socket分类: socekt提供了流和数据报两种通信机制,即流socket和数据报socket。 简单的socket通信流程: 先...

redis的搜索组件 redis-search4j

redis-search4j是一款基于redis的搜索组件。 特点 1.基于redis,性能高效 2.实时更新索引 3.支持Suggest前缀、拼音查找(AutoComplete功能) 4.支持单个或多个分词搜索 5.可根据字段进行结果排序 环境 1.jdk 1.6+ 2.redis 2.2+ 依赖包 1.Jedis-2.1.0 2.commons-...

自建 Gitlab (邮箱配置、拆分 PostgreSQL、Redis) + 随想

前言 最近折腾了一番自建 gitlab,在此做个记录,供君参考。整个构建过程基于 Docker Swarm(近期有计划将微服务移植到 Kubernetes,但还没倒腾顺手,暂时先沿用旧的方案),主题配图与主题无关,请忽略...... 1. 快速启用 配置的一般原则是先可用再优化,简单启动 gitlab 只需要一条命令: sudo docker run --...

Linux 7.6查看开机自启

[root@tz-yycs-db01 etc]# systemctl list-unit-files |grep enable brandbot.path enabled auditd.service enabled autov...

查询Redis缓存

packageme.zhengjie.monitor.rest; importme.zhengjie.common.aop.log.Log; importme.zhengjie.monitor.domain.vo.RedisVo; importme.zhengjie.monitor.service.RedisService; importorg.s...