抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

摘要:本文介绍了Redis的主从复制。

环境

Windows 10 企业版 LTSC 21H2
Redis 7.4.8

1 概述

主从复制是Redis的一种高可用方案,它允许将一个主节点的数据复制到多个从节点。主节点负责处理写操作,从节点负责处理读操作,从而实现读写分离,提高系统的性能和可用性。

2 作用

主从复制的作用:

  1. 数据备份:从节点是主节点的备份,可以防止数据丢失。
  2. 读写分离:主节点处理写操作,从节点处理读操作,提高系统的并发处理能力。
  3. 负载均衡:多个从节点可以分担读操作的压力,提高系统的整体性能。
  4. 高可用:当主节点发生故障时,可以将从节点升级为主节点,保证系统的可用性。

3 原理

3.1 同步过程

建立连接,在同步前需要建立主从关系:

  1. 从节点通过REPLICAOF命令连接到主节点。
  2. 主节点进行连接验证,确认从节点的权限。

全量复制,首次同步全量命令:

  1. 从节点向主节点发送PSYNC ? -1命令,表示没有主节点运行ID和从节点偏移量,请求进行全量复制。
  2. 主节点收到连接请求后,返回+FULLRESYNC告知从节点进行全量复制,并且返回主节点运行ID和主节点偏移量,用于后续的同步操作。
  3. 主节点执行BGSAVE命令生成RDB文件,然后将RDB文件发送给从节点。
  4. 从节点接收RDB文件,清空数据,执行命令,记录主节点运行ID,覆盖从节点偏移量。
  5. 主节点将处理RDB文件的过程中执行的命令写入积压缓冲区,将要发送的命令写入复制缓冲区并发送给从节点。
  6. 从节点接收复制缓冲区中的命令,执行命令。

命令传播,持续同步新增命令:

  1. 主节点将后续执行的命令写入积压缓冲区,将要发送的命令写入复制缓冲区并发送给从节点。
  2. 从节点接收复制缓冲区中的命令,执行命令。

增量复制,网络重连后同步增量命令:

  1. 从节点向主节点发送PSYNC 主节点运行ID 从节点偏移量命令,表示已有主节点运行ID和从节点偏移量,请求进行增量复制。
  2. 主节点收到连接请求后,返回+CONTINUE告知从节点进行增量复制。
  3. 主节点根据主节点偏移量和从节点偏移量,在积压缓冲区找到对应的命令,将要发送的命令写入复制缓冲区并发送给从节点。
  4. 从节点接收复制缓冲区中的命令,执行命令。

3.2 同步方式

3.2.1 首次同步

从节点首次同步时,没有主节点运行ID和从节点偏移量,发送PSYNC ? -1命令,主节点进行全量复制。

3.2.2 断开重连

从节点与主节点断开连接后重新连接时,已有主节点运行ID和从节点偏移量,发送PSYNC 主节点运行ID 从节点偏移量命令,主节点根据参数判断进行增量复制还是全量复制。

判断逻辑:

  • 如果主节点运行ID和当前主节点运行ID相同,说明主节点未被更换,需要进行增量复制,否则进行全量复制。
  • 如果从节点偏移量在积压缓冲区范围内,说明从节点存在记录,需要进行增量复制,否则进行全量复制。

3.3 缓冲处理

3.3.1 积压缓冲区

积压缓冲区属于环形缓冲区,是主节点上的唯一缓冲区,用于存储主节点最近执行的命令。

积压缓冲区溢出时会覆盖旧的命令。

3.3.2 复制缓冲区

复制缓冲区属于链式缓冲区,是主节点上的从节点专属缓冲区,用于存储从节点需要执行的命令。

复制缓冲区溢出时会自动断开从节点的连接,释放缓冲区空间。

3.3.3 共享缓冲区

由于主节点需要对每个从节点创建各自的复制缓冲区,会造成内存浪费。

为了解决这个问题,从7.0版本开始引入共享缓冲区的概念。

共享缓冲区属于链式缓冲区,用于存储主节点最近执行的命令。

共享缓冲区在内存中分成了多个数据块,每个数据块都有一个引用计数,用于记录有多少个从节点正在使用该数据块,系统会定期释放未被使用的数据块。

改变说明:

  • 共享缓冲区:存储真实数据,头部用于保留历史数据块,中部用于释放未被使用的数据块,尾部的用于追加新的数据块。
  • 积压缓冲区:不再存储真实数据,而是存储共享缓冲区的指针,用于在从节点断开重连时判断是否执行增量同步。
  • 复制缓冲区:不再存储真实数据,而是存储共享缓冲区的指针,用于在从节点读取命令时判断是否执行命令。

3.4 触发逻辑

触发全量复制的情况:

  • 从节点首次同步时,发送PSYNC命令,主节点运行ID和从节点偏移量不存在。
  • 从节点断开重连时,发送PSYNC命令,主节点运行ID和当前主节点运行ID不相同。
  • 从节点断开重连时,发送PSYNC命令,从节点偏移量不在积压缓冲区范围内。

触发增量复制的情况:

  • 从节点断开重连时,发送PSYNC命令,主节点运行ID和当前主节点运行ID相同,并且从节点偏移量在积压缓冲区范围内。

4 配置

4.1 动态配置

在从节点上配置主节点:

cmd
1
REPLICAOF 主节点IP地址 主节点端口号

从节点取消主从关系:

cmd
1
REPLICAOF NO ONE

4.2 配置文件

修改从节点的redis.conf配置文件。

配置主节点:

redis.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# 配置主节点
# replicaof 主节点IP地址 主节点端口号

# 如果主节点设置了密码,需要配置主节点的密码
# masterauth 主节点密码

# 如果主节点设置了ACL,需要配置主节点的用户名
# masteruser 主节点用户名

# 设置是否允许从节点在断开重连或者复制过程中提供服务,默认为yes表示允许但数据可能不是最新的,设置为no表示不允许并返回错误
replica-serve-stale-data yes

# 设置从节点是否只读,默认为yes表示只读,设置为no表示可读可写
replica-read-only yes

# 设置同步策略,默认为yes表示无盘策略,设置为no表示磁盘策略:
# 磁盘策略:主节点创建子进程,子进程将RDB文件写入磁盘文件,主节点将磁盘文件发送给从节点,后续添加的从节点可以使用磁盘文件直接发送
# 无盘策略:主节点创建子进程,子进程将RDB文件通过字节流发送给从节点,一个批次可以发送给多个已经添加的从节点,但是发送过程中添加的从节点需要等待下一批次发送
repl-diskless-sync yes

# 设置无盘策略的延迟时间,默认为5秒,设置为0表示不等待,用于限制等待添加从节点的时间
repl-diskless-sync-delay 5

# 设置无盘策略的最大从节点数量,默认为0,设置为0表示不限制,用于限制等待添加从节点的数量
repl-diskless-sync-max-replicas 0

# 设置无盘策略发送到从节点,从节点如何处理,默认为disabled
# disabled:从节点使用磁盘加载,先将RDB文件写入从节点的磁盘文件,在将磁盘文件读取到内存,在此期间从节点不能提供服务
# swapdb:从节点使用无盘加载,将RDB文件加载到从节点的内存中,在此期间从节点仍然可以提供服务,但内存不足可能引发OOM错误
# on-empty-db:只有在从节点数据集为空时才使用无盘加载,否则使用磁盘加载
repl-diskless-load disabled

# 设置交互周期,即从节点与主节点的PING命令执行间隔,默认为10秒,主节点用PING命令检查从节点是否正常
# repl-ping-replica-period 10

# 设置复制超时时间,默认为60秒,要求必须大于PING命令执行间隔
# repl-timeout 60

# 设置在执行SYNC命令的后续通信中是否禁用TCP_NODELAY配置,默认为no表示启用,设置为yes表示禁用
# 禁用TCP_NODELAY配置可以减少发送的TCP包,从而减少发送的带宽,但是会增加延迟
repl-disable-tcp-nodelay no

# 设置积压缓冲区大小,默认为1MB,积压缓冲区越大,能够容忍从节点断开重连的时间越长
# repl-backlog-size 1mb

# 设置积压缓冲区过期时间,默认为3600秒,设置为0表示永不过期,过期后会释放积压缓冲区
# 这个设置只对主节点生效,从节点需要保留积压缓冲区以便应对未来可能变成主节点的情况
# repl-backlog-ttl 3600

# 设置从节点优先级,默认为100,数字越小优先级越高,越容易被选为主节点,设置为0表示不参与主从选举
replica-priority 100

# 设置复制错误处理行为,默认为ignore
# ignore:表示忽略复制错误,继续复制,优先保证可用性
# panic:表示在复制错误时,主节点和从节点都会崩溃,优先保证数据一致性
# panic-on-replicas:表示在复制错误时,从节点会崩溃,主节点继续复制,保证写入操作的可用性
# propagation-error-behavior ignore

# 设置从节点是否忽略写入磁盘时发生的错误,默认为no
# no:在从节点写入磁盘发生错误时崩溃
# yes:在从节点写入磁盘发生错误时忽略,只记录警告并执行命令
# replica-ignore-disk-write-errors no

# 设置从节点是否在从节点列表中显示,默认为yes表示显示,设置为no表示隐藏
# replica-announced yes

# 设置主节点写入操作需要的条件,如果延迟小于等于10秒的从节点的数量小于3个,就停止执行写入操作
# 将任何一个设置为0都表示不限制,一般设置数量,表示即使没有从节点,主节点也会执行写入操作
# min-replicas-to-write 3
# min-replicas-max-lag 10

# 设置从节点的IP地址和端口号,方便主节点显示从节点信息
# replica-announce-ip 5.5.5.5
# replica-announce-port 1234

5 状态监控

使用命令查看节点状态:

cmd
1
INFO replication

主节点显示结果:

  • # Replication:复制状态
  • role:master:节点角色,master表示主节点
  • connected_slaves:1:已连接的从节点数量
  • slave0:ip=127.0.0.1,port=6381,state=online,offset=728,lag=1:从节点:IP地址、端口号、状态、复制偏移量、复制延迟,单位是秒
  • master_failover_state:no-failover:故障转移状态,no-failover表示未发生故障转移
  • master_replid:805f3a2e734fooc7bf4e5103a5867189c695d2c2:主节点的复制ID,建立主从关系后生成新的ID
  • master_replid2:0000000000000000000000000000000000000000:发生故障转移时,原主节点的复制ID
  • master_repl_offset:728:主节点的复制偏移量
  • second_repl_offset:-1:发生故障转移时,原主节点的复制偏移量
  • repl_backlog_active:1:是否激活积压缓冲区,1表示已激活
  • repl_backlog_size:1048576:积压缓冲区大小
  • repl_backlog_first_byte_offset:1:积压缓冲区中第一个字节对应的复制偏移量
  • repl_backlog_histlen:728:积压缓冲区中实际存储的有效数据量,单位是字节

从节点显示结果:

  • # Replication:复制状态
  • role:slave:节点角色,slave表示从节点
  • master_host:127.0.0.1:主节点的IP地址
  • master_port:6379:主节点的端口号
  • master_link_status:up:主从连接状态,up表示正常
  • master_last_io_seconds_ago:1:上次与主节点通信的时间,单位是秒
  • master_sync_in_progress:0:是否正在同步数据,0表示空闲
  • slave_read_repl_offset:728:从节点已接收的复制偏移量
  • slave_repl_offset:728:从节点已执行的复制偏移量
  • slave_priority:100:从节点的优先级
  • slave_read_only:1:从节点是否只读,1表示只读
  • replica_announced:1:从节点是否显示,1表示显示
  • connected_slaves:0:已连接的从节点数量
  • master_failover_state:no-failover:故障转移状态,no-failover表示未发生故障转移
  • master_replid:805f3a2e734fooc7bf4e5103a5867189c695d2c2:主节点的复制ID,建立主从关系后生成新的ID
  • master_replid2:0000000000000000000000000000000000000000:发生故障转移时,原主节点的复制ID
  • master_repl_offset:728:主节点的复制偏移量
  • second_repl_offset:-1:发生故障转移时,原主节点的复制偏移量
  • repl_backlog_active:1:是否激活积压缓冲区,1表示已激活
  • repl_backlog_size:1048576:积压缓冲区大小
  • repl_backlog_first_byte_offset:15:积压缓冲区中第一个字节对应的复制偏移量
  • repl_backlog_histlen:714:积压缓冲区中实际存储的有效数据量,单位是字节

6 最佳实践

对于生产环境,建议使用哨兵模式,实现主节点的自动故障转移。

评论