Redis - 主从复制

ops/2024/11/12 8:34:30/

        在分布式系统中为了解决单点问题,通常会把数据复制多个副本部署到其他服务器,满⾜故障恢 复和负载均衡等需求。Redis也是如此,它为我们提供了复制的功能,实现了相同数据的多个Redis副 本。复制功能是⾼可⽤Redis的基础,哨兵和集群都是在复制的基础上构建的。本章内容如下:

  • 介绍复制的使⽤⽅式:如何建⽴或断开复制、安全性、只读等。
  • 说明复制可⽀持的拓扑结构,以及每个拓扑结构的适⽤场景。
  • 分析复制的原理,包括:建⽴复制、全量复制、部分复制、⼼跳检测等。

一、配置

1.1、建⽴复制

        参与复制的Redis实例划分为主节点(master)和从节点(slave)。每个从结点只能有⼀个主节点, ⽽⼀个主节点可以同时具有多个从结点。复制的数据流是单向的,只能由主节点到从节点。配置复制 的⽅式有以下三种:

  1. 在配置⽂件中加⼊slaveof{masterHost}{masterPort}随Redis启动⽣效。
  2. redis-server 启动命令时加⼊--slaveof{masterHost}{masterPort}⽣效。
  3. 直接使⽤redis命令:slaveof{masterHost}{masterPort}⽣效。

接下来,将redis.conf配置⽂件复制⼀份redis-slave.conf,并且修改其daemonize为yes。

 # By default Redis does not run as a daemon. Use 'yes' if you need it.# Note that Redis will write a pid file in /var/run/redis.pid when daemonized.daemonize yes

接下来,默认启动的redis作为主Redis,重新通过命令⾏启动⼀个Redis实例作为从Redis:

 # ubunturedis-server /etc/redis/redis-slave.conf --port 6380 --slaveof 127.0.0.1 6379# centosredis-server /etc/redis-slave.conf --port 6380 --slaveof 127.0.0.1 6379

注 意:修改配置主要是修改从机的配置.主机配置不变.

通过netstat-nlpt确保两个Redis均已正确启动。

 [root@host ~]# netstat -nlptActive Internet connections (only servers)   Proto Recv-Q Send-Q Local Address      Foreign Address     StatePID/Program name           tcp        0      0 127.0.0.1:6379     0.0.0.0:*           LISTEN49264/redis-server  tcp        0      0 127.0.0.1:6380     0.0.0.0:*           LISTEN 272418/redis-server                                

通过redis-cli 可以连接主Redis实例,通过redis-cli-p6380连接从Redis。并且观察复制关系。

 127.0.0.1:6379> set hello worldOK127.0.0.1:6379> get hello"world"
 127.0.0.1:6380> get hello"world"

        从运⾏结果中看到复制已经⼯作了,针对主节点6379的任何修改都可以同步到从节点6380中,复制 过程如图所⽰。

Redis 主从节点复制过程

可以通过inforeplication命令查看复制相关状态。

1)主节点6379复制状态信息

 127.0.0.1:6379> info replication# Replicationrole:masterconnected_slaves:1slave0:ip=127.0.0.1,port=6380,state=online,offset=100,lag=0master_replid:2fbd35a8b8401b22eb92ff49ad5e42250b3e7a06master_replid2:0000000000000000000000000000000000000000master_repl_offset:100second_repl_offset:-1repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:1repl_backlog_histlen:100

2)从节点6380复制状态信息

 127.0.0.1:6380> info replication# Replicationrole:slavemaster_host:127.0.0.1master_port:6379master_link_status:upmaster_last_io_seconds_ago:1master_sync_in_progress:0slave_repl_offset:170slave_priority:100slave_read_only:1connected_slaves:0master_replid:2fbd35a8b8401b22eb92ff49ad5e42250b3e7a06master_replid2:0000000000000000000000000000000000000000master_repl_offset:170second_repl_offset:-1repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:1repl_backlog_histlen:170

1.2、断开复制

        slaveof 命令不但可以建⽴复制,还可以在从节点执⾏slaveofnoone来断开与主节点复制关系。 例如在6380节点上执⾏slaveofnoone来断开复制。

断开复制主要流程:

  1. 断开与主节点复制关系。
  2. 从节点晋升为主节点。

从节点断开复制后并不会抛弃原有数据,只是⽆法再获取主节点上的数据变化。

        通过slaveof命令还可以实现切主操作,将当前从节点的数据源切换到另⼀个主节点。执⾏ slaveof {newMasterIp} {newMasterPort} 命令即可。

切主操作主要流程:

1)断开与旧主节点复制关系。

2)与新主节点建⽴复制关系。

3)删除从节点当前所有数据。

4)从新主节点进⾏复制操作。

1.3、安全性

        对于数据⽐较重要的节点,主节点会通过设置requirepass参数进⾏密码验证,这时所有的客⼾ 端访问必须使⽤auth命令实⾏校验。从节点与主节点的复制连接是通过⼀个特殊标识的客⼾端来完 成,因此需要配置从节点的masterauth参数与主节点密码保持⼀致,这样从节点才可以正确地连接到 主节点并发起复制流程。

1.4、只读

        默认情况下,从节点使⽤slave-read-only=yes配置为只读模式。由于复制只能从主节点到从节 点,对于从节点的任何修改主节点都⽆法感知,修改从节点会造成主从数据不⼀致。所以建议线上不 要修改从节点的只读模式。

1.5、传输延迟

        主从节点⼀般部署在不同机器上,复制时的⽹络延迟就成为需要考虑的问题,Redis为我们提供 了repl-disable-tcp-nodelay 参数⽤于控制是否关闭TCP_NODELAY,默认为no,即开启tcp nodelay 功能,说明如下:

  • 当关闭时,主节点产⽣的命令数据⽆论⼤⼩都会及时地发送给从节点,这样主从之间延迟会变⼩, 但增加了⽹络带宽的消耗。适⽤于主从之间的⽹络环境良好的场景,如同机房部署。
  • 当开启时,主节点会合并较⼩的TCP数据包从⽽节省带宽。默认发送时间间隔取决于Linux的内 核,⼀般默认为40毫秒。这种配置节省了带宽但增⼤主从之间的延迟。适⽤于主从⽹络环境复杂 的场景,如跨机房部署。

二、拓扑

        Redis 的复制拓扑结构可以⽀持单层或多层复制关系,根据拓扑复杂性可以分为以下三种:⼀主⼀ 从、⼀主多从、树状主从结构。

2.1、⼀主⼀从结构

        ⼀主⼀从结构是最简单的复制拓扑结构,⽤于主节点出现宕机时从节点提供故障转移⽀持,如图 所⽰。当应⽤写命令并发量较⾼且需要持久化时,可以只在从节点上开启AOF,这样既可以保证数据 安全性同时也避免了持久化对主节点的性能⼲扰。但需要注意的是,当主节点关闭持久化功能时,如 果主节点宕机要避免⾃动重启操作。

⼀主⼀从拓扑

 

2.2、⼀主多从结构 

        ⼀主多从结构(星形结构)使得应⽤端可以利⽤多个从节点实现读写分离,如图5-3所⽰。对于 读⽐重较⼤的场景,可以把读命令负载均衡到不同的从节点上来分担压⼒。同时⼀些耗时的读命令可 以指定⼀台专⻔的从节点执⾏,避免破坏整体的稳定性。对于写并发量较⾼的场景,多个从节点会导 致主节点写命令的多次发送从⽽加重主节点的负载。

⼀主多从拓扑

 

2.3、树形主从结构

        树形主从结构(分层结构)使得从节点不但可以复制主节点数据,同时可以作为其他从节点的主 节点继续向下层复制。通过引⼊复制中间层,可以有效降低住系欸按负载和需要传送给从节点的数据 量,如图6-4所⽰。数据写⼊节点A之后会同步给B和C节点,B节点进⼀步把数据同步给D和E节 点。当主节点需要挂载等多个从节点时为了避免对主节点的性能⼲扰,可以采⽤这种拓扑结构。

图5-4树形拓扑

三、 原理

3.1、复制过程

如图所⽰,下⾯详细介绍建⽴复制的完整流程。从图中可以看出复制过程⼤致分为6个过程:

主从节点建⽴复制流程图

 1)保存主节点(master)的信息。

        开始配置主从同步关系之后,从节点只保存主节点的地址信息,此时建⽴复制流程还没有开始, 在从节点6380执⾏inforeplication可以看到如下信息:

 master_host: 127.0.0.1master_port: 6379master_link_status: down

从统计信息可以看出,主节点的ip和port被保存下来,但是主节点的连接状态 (master_link_status)是下线状态。

2)从节点(slave)内部通过每秒运⾏的定时任务维护复制相关逻辑,当定时任务发现存在新的主节 点后,会尝试与主节点建⽴基于TCP的⽹络连接。如果从节点⽆法建⽴连接,定时任务会⽆限重试直 到连接成功或者⽤⼾停⽌主从复制。

3)发送ping命令。连接建⽴成功之后,从节点通过ping命令确认主节点在应⽤层上是⼯作良好的。 如果ping命令的结果pong回复超时,从节点会断开TCP连接,等待定时任务下次重新建⽴连接。

4)权限验证。如果主节点设置了requirepass参数,则需要密码验证,从节点通过配置masterauth 参数来设置密码。如果验证失败,则从节点的复制将会停⽌。

5)同步数据集。对于⾸次建⽴复制的场景,主节点会把当前持有的所有数据全部发送给从节点,这步 操作基本是耗时最⻓的,所以⼜划分称两种情况:全量同步和部分同步,下⼀节重点介绍。

6)命令持续复制。当从节点复制了主节点的所有数据之后,针对之后的修改命令,主节点会持续的把 命令发送给从节点,从节点执⾏修改命令,保证主从数据的⼀致性。

3.2、数据同步psync

Redis 使⽤psync命令完成主从数据同步,同步过程分为:全量复制和部分复制。

  • 全量复制:⼀般⽤于初次复制场景,Redis早期⽀持的复制功能只有全量复制,它会把主节点全部 数据⼀次性发送给从节点,当数据量较⼤时,会对主从节点和⽹络造成很⼤的开销。
  • 部分复制:⽤于处理在主从复制中因⽹络闪断等原因造成的数据丢失场景,当从节点再次连上主节 点后,如果条件允许,主节点会补发数据给从节点。因为补发的数据远⼩于全量数据,可以有效避 免全量复制的过⾼开销。

PSYNC的语法格式

 PSYNC replicationid offset

如果replicationid 设为?并且offset设为-1 此时就是在尝试进⾏全量复制.

如果replicationid offset 设为了具体的数值,则是尝试进⾏部分复制.

3.2.1、replicationid/replid (复制id)

        主节点的复制id.主节点重新启动,或者从节点晋级成主节点,都会⽣成⼀个replicationid.(同⼀个节 点,每次重启,⽣成的replicationid也会变化).

从节点在和主节点建⽴连接之后,就会获取到主节点的replicationid.

通过 info replication 即可看到replicationid

 127.0.0.1:6379> info replication# Replicationrole:masterconnected_slaves:0master_replid:1da596acecf5a34b4b2aae45bd35be785691ae69master_replid2:0000000000000000000000000000000000000000master_repl_offset:0second_repl_offset:-1repl_backlog_active:0repl_backlog_size:1048576repl_backlog_first_byte_offset:0repl_backlog_histlen:0

关于master_replid和master_replid2

每个节点需要记录两组master_replid.这个设定解决的问题场景是这样的:

⽐如当前有两个节点A和B,A为master,B为slave.

此时B就会记录A的master_replid.

如果⽹络出现抖动,B以为A挂了,B⾃⼰就会成为主节点.于是B给⾃⼰分配了新的master_replid.

此时就会使⽤master_replid2来保存之前A的master_replid.

  • 后续如果⽹络恢复了,B就可以根据master_replid2找回之前的主节点.
  • 后续如果⽹络没有恢复,B就按照新的master_replid⾃成⼀派,继续处理后续的数据

3.2.2、offset (偏移量)

        参与复制的主从节点都会维护⾃⾝复制偏移量。主节点(master)在处理完写⼊命令后,会把命令的 字节⻓度做累加记录,统计信息在inforeplication中的master_repl_offset指标中。

 127.0.0.1:6379> info replication# Replicationrole:master...master_repl_offset:1055130

        从节点(slave)每秒钟上报⾃⾝的复制偏移量给主节点,因此主节点也会保存从节点的复制偏移量, 统计指标如下:

 127.0.0.1:6379> info replicationconnected_slaves:1slave0:ip=127.0.0.1,port=6380,state=online,offset=1055214,lag=1...

        从节点在接受到主节点发送的命令后,也会累加记录⾃⾝的偏移量。统计信息在inforeplication中的 slave_repl_offset 指标中:

 127.0.0.1:6380> info replication# Replicationrole:slave...slave_repl_offset:1055214

复制偏移量的维护如图所⽰。通过对⽐主从节点的复制偏移量,可以判断主从节点数据是否⼀致。

3.3、复制偏移量维护

 这个偏移量,就相当于"学习进度"

replid+offset共同标识了⼀个"数据集". 如果两个节点,他们的replid和offset都相同,则这两个节点上持有的数据,就⼀定相同.

3.4、psync运⾏流程

 1)从节点发送psync命令给主节点,replid和offset的默认值分别是?和-1.

 2)主节点根据 psync 参数和自身数据情况决定响应结果:

  •  如果回复+FULLRESYNC replid offset,则从节点需要进⾏全量复制流程。
  • 如果回复+CONTINEU,从节点进⾏部分复制流程。
  • 如果回复-ERR,说明Redis主节点版本过低,不⽀持psync命令。从节点可以使⽤sync命令进⾏ 全量复制。
    • psync⼀般不需要⼿动执⾏.Redis会在主从复制模式下⾃动调⽤执⾏.
    • sync会阻塞redisserver处理其他请求.psync则不会

3.5、全量复制

        全量复制是Redis最早⽀持的复制⽅式,也是主从第⼀次建⽴复制时必须经历的阶段。全量复制的运 ⾏流程如图所⽰。

全量复制流程

 1)从节点发送psync命令给主节点进⾏数据同步,由于是第⼀次进⾏复制,从节点没有主节点的运 ⾏ID和复制偏移量,所以发送psync?-1。

2)主节点根据命令,解析出要进⾏全量复制,回复+FULLRESYNC响应。

3)从节点接收主节点的运⾏信息进⾏保存。

4)主节点执⾏bgsave进⾏RDB⽂件的持久化。

5)从节点发送RDB⽂件给从节点,从节点保存RDB数据到本地硬盘。

6)主节点将从⽣成RDB到接收完成期间执⾏的写命令,写⼊缓冲区中,等从节点保存完RDB⽂件 后,主节点再将缓冲区内的数据补发给从节点,补发的数据仍然按照rdb的⼆进制格式追加写⼊到收 到的rdb⽂件中.保持主从⼀致性。

7)从节点清空⾃⾝原有旧数据。

8)从节点加载RDB⽂件得到与主节点⼀致的数据。

9)如果从节点加载RDB完成之后,并且开启了AOF持久化功能,它会进⾏bgrewrite操作,得到最 近的AOF⽂件。

        通过分析全量复制的所有流程,我们会发现全量复制是⼀件⾼成本的操作:主节点bgsave的时间, RDB在⽹络传输的时间,从节点清空旧数据的时间,从节点加载RDB的时间等。所以⼀般应该尽可能 避免对已经有⼤量数据集的Redis进⾏全量复制。

有磁盘复制vs⽆磁盘复制(diskless)

        默认情况下,进⾏全量复制需要主节点⽣成RDB⽂件到主节点的磁盘中,再把磁盘上的RDB ⽂件通过发送给从节点.

        Redis 从2.8.18版本开始⽀持⽆磁盘复制.主节点在执⾏RDB⽣成流程时,不会⽣成RDB⽂ 件到磁盘中了,⽽是直接把⽣成的RDB数据通过⽹络发送给从节点.这样就节省了⼀系列的写 硬盘和读硬盘的操作开销.

3.6、部分复制

        部分复制主要是Redis针对全量复制的过⾼开销做出的⼀种优化措施,使⽤psyncreplicationId offset 命令实现。当从节点正在复制主节点时,如果出现⽹络闪断或者命令丢失等异常情况时,从节点 会向主节点要求补发丢失的命令数据,如果主节点的复制积压缓冲区存在数据则直接发送给从节点, 这样就可以保持主从节点复制的⼀致性。补发的这部分数据⼀般远远⼩于全量数据,所以开销很⼩。 整体流程如图所⽰。

图部分复制过程

1)当主从节点之间出现⽹络中断时,如果超过repl-timeout时间,主节点会认为从节点故障并终端 复制连接。

2)主从连接中断期间主节点依然响应命令,但这些复制命令都因⽹络中断⽆法及时发送给从节点,所 以暂时将这些命令滞留在复制积压缓冲区中。

3)当主从节点⽹络恢复后,从节点再次连上主节点。

4)从节点将之前保存的replicationId和复制偏移量作为psync的参数发送给主节点,请求进⾏部分 复制。

5)主节点接到psync请求后,进⾏必要的验证。随后根据offset去复制积压缓冲区查找合适的数据, 并响应+CONTINUE给从节点。

6)主节点将需要从节点同步的数据发送给从节点,最终完成⼀致性。

3.7、复制积压缓冲区

        复制积压缓冲区是保存在主节点上的⼀个固定⻓度的队列,默认⼤⼩为1MB,当主节点有连接的从节 点(slave)时被创建,这时主节点(master)响应写命令时,不但会把命令发送给从节点,还会写⼊ 复制积压缓冲区,如图所⽰。

         由于缓冲区本质上是先进先出的定⻓队列,所以能实现保存最近已复制数据的功能,⽤于部分复制和 复制命令丢失的数据补救。复制缓冲区相关统计信息可以通过主节点的inforeplication中:

 127.0.0.1:6379> info replication# Replicationrole:master...repl_backlog_active:1                // 开启复制缓冲区repl_backlog_size:1048576            // 缓冲区最⼤⻓度repl_backlog_first_byte_offset:7479  // 起始偏移量,计算当前缓冲区可⽤范围repl_backlog_histlen:1048576         // 已保存数据的有效⻓度

根据统计指标,可算出复制积压缓冲区内的可⽤偏移量范围:[repl_backlog_first_byte_offset,repl_backlog_first_byte_offset + repl_backlog_histlen]。

这个相当于⼀个基于数组实现的环形队列.上述区间中的值就是"数组下标".

如果当前从节点需要的数据,已经超出了主节点的积压缓冲区的范围,则⽆法进⾏部分复制,只 能全量复制了.

3.8、实时复制

        主从节点在建⽴复制连接后,主节点会把⾃⼰收到的修改操作,通过tcp⻓连接的⽅式,源源不断的传 输给从节点.从节点就会根据这些请求来同时修改⾃⾝的数据.从⽽保持和主节点数据的⼀致性.

另外,这样的⻓连接,需要通过⼼跳包的⽅式来维护连接状态.(这⾥的⼼跳是指应⽤层⾃⼰实现的⼼跳, ⽽不是TCP⾃带的⼼跳).

1)主从节点彼此都有⼼跳检测机制,各⾃模拟成对⽅的客⼾端进⾏通信。

2)主节点默认每隔10秒对从节点发送ping命令,判断从节点的存活性和连接状态。

3)从节点默认每隔1秒向主节点发送replconfack{offset}命令,给主节点上报⾃⾝当前的复制偏移 量。

如果主节点发现从节点通信延迟超过repl-timeout配置的值(默认60秒),则判定从节点下线,断 开复制客⼾端连接。从节点恢复连接后,⼼跳机制继续进⾏。

四、本章重点回顾

主从复制解决的问题:

单点问题

  1. 单个redis节点,可⽤性不⾼.
  2. 单个redis节点,性能有限.

主从复制的特点:

  1. Redis 通过复制功能实现主节点的多个副本。
  2. 主节点⽤来写,从节点⽤来读.这样做可以降低主节点的访问压⼒.
  3. 复制⽀持多种拓扑结构,可以在适当的场景选择合适的拓扑结构。
  4. 复制⽀持多种拓扑结构,可以在适当的场景选择合适的拓扑结构。
  5. 主从节点之间通过⼼跳机制保证主从节点通信正常和数据⼀致性。

主从复制配置的过程:

  1. 主节点配置不需要改动.
  2. 从节点在配置⽂件中加⼊ 主从复制的缺点: slaveof 主节点 ip 主节点端⼝ 的形式即可.

主从复制的缺点:

  1. 从机多了,复制数据的延时⾮常明显.
  2. 主机挂了,从机不会升级成主机.只能通过⼈⼯⼲预的⽅式恢复.

http://www.ppmy.cn/ops/132167.html

相关文章

登陆验证中的cookie和session对比

1. Cookie 和 Session 简介 Cookie:Cookie 是一种存储在客户端(如浏览器)的小数据。它通常被服务器生成并发送给客户端,之后在每次请求时由客户端将其附带返回服务器,从而实现用户的身份识别和状态管理。 Session&…

计算机毕业设计Python流量检测可视化 DDos攻击流量检测与可视化分析 SDN web渗透测试系统 网络安全 信息安全 大数据毕业设计

温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…

【图论】图的C++实现代码

在这个例程中我们用类实现了节点、&#xff08;无向图&#xff09;连边、无向图&#xff0c;实现了节点度的计算、无向图聚类系数计算、度分布统计、无向图的Dijkstra算法&#xff08;已知起止点计算最短路的算法&#xff09; #include <iostream> #include<vector&g…

MySQL第六章,数据库企业级开发技术

这一章节也是非常重要的一章&#xff0c;非常常用&#xff01; 一、事务&#xff08;Transactions&#xff09; 1. 事务的概念 事务是数据库操作的基本单位&#xff0c;它保证了一组数据库操作要么全部执行成功&#xff0c;要么全部回滚&#xff0c;从而保持数据的一致性和完…

Python并发编程库:Asyncio的异步编程实战

Python并发编程库&#xff1a;Asyncio的异步编程实战 在现代应用中&#xff0c;并发和高效的I/O处理是影响系统性能的关键因素之一。Python的asyncio库是专为异步编程设计的模块&#xff0c;提供了一种更加高效、易读的并发编程方式&#xff0c;适用于处理大量的I/O密集型任务…

How to use ffmpeg to convert video format from .webm to .mp4

The .mp4 container format doesn’t support the VP8 codec, which is commonly used in .webm files. MP4 containers typically use the H.264 codec for video and AAC for audio. You’ll need to re-encode the video using the H.264 codec and re-encode the audio us…

uniapp组件样式运行至小程序失效

文章目录 一、uniapp样式穿透打包运行至微信小程序失效 一、uniapp样式穿透打包运行至微信小程序失效 组件样式隔离文章参考 解决方案 options: {styleIsolation: "shared",},这个配置项改变了小程序组件的样式隔离模式&#xff0c;使得组件的样式能够共享和继承。…

AscendC从入门到精通系列(一)初步感知AscendC

1 什么是AscendC Ascend C是CANN针对算子开发场景推出的编程语言&#xff0c;原生支持C和C标准规范&#xff0c;兼具开发效率和运行性能。基于Ascend C编写的算子程序&#xff0c;通过编译器编译和运行时调度&#xff0c;运行在昇腾AI处理器上。使用Ascend C&#xff0c;开发者…