redis 主从复制

 


Redis 主从复制架构

Redis 的主从复制是一种数据复制机制,它允许从节点(slave)复制主节点(master)的数据。这样可以提高读操作的性能,并实现数据的高可用性和容错。

主从架构基本概念

主节点(Master):负责处理写操作并将数据同步到从节点。
从节点(Slave):负责从主节点读取数据,可用于承载读请求,以减轻主节点的负担。

主节点(Master)和 从节点(Slave) 在发生故障时无法自动切换角色。

Redis 主从复制特点

数据冗余
  数据在不同节点间复制,提供数据备份,确保在主节点故障时数据不会丢失。

读写分离
  主节点处理所有写操作,而从节点可以处理读操作,从而提高系统的整体性能和响应速度。

异步复制
  从节点与主节点之间的复制通常是异步的,主节点写入数据后立即返回响应,减少了写操作的延迟。

故障转移
  当主节点发生故障时,可以快速将从节点提升为新的主节点,保持系统的可用性和一致性。

可扩展性
  可以通过增加多个从节点来扩展读取能力,以应对更多的并发请求,提高系统的可扩展性。

简单配置
  配置简单,通常只需在从节点的配置文件中指明主节点的 IP 和端口。

数据一致性
  在复制过程中的某些情况下(如网络延迟),可能会出现数据不一致。不过,Redis 提供了工具和策略来确保数据最终一致。

单主、多从
  支持多个从节点复制一个主节点,形成树状结构。这使得系统可以在一个主节点下,支持多个从节点并发处理。从节点只读。
  

Redis 复制的工作原理

每个Redis主节点都有一个复制ID:这是一个大型伪随机字符串,用于标识数据集的特定历史记录。每个主节点还会维护一个偏移量,该偏移量会随着发送给从节点的每个字节的复制流而递增,以便用新的更改更新从节点的状态。即使没有从节点实际连接,复制偏移量也会递增,因此每对:Replication ID, offset都能精确标识主节点数据集的一个版本。

当从节点连接到主节点时,它们会使用PSYNC命令发送其旧主节点的复制ID和迄今为止处理的偏移量。这样,主节点就可以仅发送所需的增量部分。然而,如果主节点的缓冲区中没有足够的积压数据,或者从节点引用的history (replication ID)不再存在,则会发生全量重新同步:在这种情况下,从节点将从头获得数据集的完整副本。

无盘复制

正常情况下,完全重新同步需要在磁盘上创建一个RDB文件,然后从磁盘重新加载RDB文件以将数据提供给从节点。

对于慢速磁盘,这可能会对主节点造成很大的压力。Redis 2.8.18是首个支持无磁盘复制的版本。在这种设置中,子进程直接通过网络将RDB发送给从节点,而不使用磁盘作为中间存储。

Redis 主从同步流程

Redis主从复制分为全量同步和增量同步。

全量同步过程

1. 连接与身份验证
      从节点连接到主节点并进行身份验证(如果设置了密码)。
2. 发送 PSYNC 命令
      从节点发送 PSYNC命令给主节点,请求同步数据。
3. 主节点响应
      主节点响应 FULLRESYNC,并发送以下信息:
      master_replid(主节点的运行 ID)
      offset(复制的偏移量)
4. 保存主节点信息
      从节点接收到主节点的 master_replid 和 offset,并保存主节点的信息。
5. 主节点执行 BGSAVE
      主节点执行 BGSAVE 以异步保存当前数据库状态到 RDB 文件,同时记录新的写入操作到复制缓冲区。
6. 发送 RDB 文件
      主节点将生成的 RDB 文件传输给从节点。
7. 主节点同步缓冲区信息
      在从节点加载 RDB 文件的同时,主节点继续将在复制缓冲区中的新写入记录发送给从节点。
8. 从节点删除旧数据
      从节点在加载 RDB 文件之前,删除本地的旧数据,以确保数据的干净状态。
9. 加载 RDB 文件
      从节点加载收到的 RDB 文件数据。
10. 同步缓冲区信息
      从节点同步从主节点接收到的缓冲区写入操作,以确保最终的数据一致性。

全量复制的触发条件:
  首次连接:从节点第一次连接到主节点(无 master_replid 或 run_id)。
  偏移量丢失:从节点的复制偏移量不在主节点的复制积压缓冲区内。
  超时:从节点无法在设定的时间内连接到主节点。

增量同步过程

在 Redis 主从复制建立初次全量同步之后,后续的数据同步主要通过增量复制实现。
1. 全量同步完成后状态
      首次全量同步完成后,从节点会保存主节点的 master_replid 和当前的 offset 信息。
2. 增量复制的触发
      当从节点再次需要同步时,它会向主节点发送其当前的 offset 位置,这个位置代表了从节点最后接收的数据点。
3. 主节点处理请求
      主节点根据从节点提供的 offset,检查其复制缓冲区,确定自该位置以来的所有数据更改。
      主节点会将这些更改(包括缓冲区中的未传送的写操作)发送给从节点。
4. 数据传输
      主节点将新增加的写操作以命令的形式发送给从节点。
      这些命令会被直接执行,更新从节点内存中的数据。
5. 数据一致性维护
      增量复制确保从节点的状态与主节点一致,从而减少全量复制的开销,提高性能。
      如果从节点的复制偏移量不在主节点的复制积压缓冲区内,则会触发全量复制。

主从同步的完整过程

1. Slave 发起连接 Master:
       Slave 向 Master 发起连接请求。
2. 验证通过:
       Master 验证 Slave 的连接请求,确认其访问权限。
3. Slave 发送 PSYNC 命令:
       Slave 发送 PSYNC 命令给 Master,表示它希望进行一次同步。此时 Slave 会告诉 Master 自己的复制偏移量(replication offset)。
4. Master 接收 PSYNC 命令:
       Master 接收 PSYNC 命令后,执行 BGSAVE 命令开始生成 RDB (Redis DataBase) 快照文件。这是将当前内存中的数据集保存到一个二进制文件中。
       同时,Master 会将其后续发生的写操作记录到一个名为 replication buffer 的地方。这个 buffer 用于保存从生成 RDB 快照之后的写操作,确保 Slave 能够接收到这些操作。
5. Master 向所有 Slave 发送 RDB 文件:
       Master 完成 RDB 快照生成后,向所有 Slave 发送这个 RDB 文件。
6. Slave 收到快照文件:
       Slave 接收到 RDB 文件后,丢弃所有旧数据。
7. Slave 加载 RDB 到内存:
       Slave 加载收到的 RDB 文件到内存中,构建数据集。
8. Master 向所有 Slave 发送后续的写操作:
       在 Slave 加载 RDB 文件的同时或之后,Master 会向 Slave 发送从生成 RDB 快照之后的写操作,这些操作保存在之前提到的 replication buffer 中。
9. Slave 执行来自 Master 的写操作:
       Slave 接收到这些写操作并执行它们,确保与 Master 的数据保持一致。这一步可能是增量的,取决于 Slave 上一次复制的偏移量和当前 Master 上的偏移量之间的差异。
10. 比较并增量复制:
       当 Slave 完成全量复制后,Master 和 Slave 会维护各自的复制偏移量。后续的增量复制是基于这些偏移量进行的。当 Slave 启动或重新连接时,它会告诉 Master 自己上次复制的偏移量。Master 会发送从那时起发生的所有写操作给 Slave,这样 Slave 只需要接收并应用这些增量数据即可,无需再次进行全量复制。

节点规划

redis-m01 192.168.174.108 master
redis-s01 192.168.174.109 slave
redis-s02 192.168.174.110 slave

配置主从复制

Redis Server 默认为 master节点,如果要配置为从节点,需要指定master服务器的IP,端口及连接密码。

主节点 m-108

redis-cli
127.0.0.1:6379> auth 123456
OK
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:0108740a3548acedfec8655321470d82516bd556
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
set node m-108
OK
127.0.0.1:6379> get node
"m-108"
127.0.0.1:6379> 

从节点 s-109

127.0.0.1:6379> auth 123456
OK
127.0.0.1:6379> set node s-109
OK
127.0.0.1:6379> get node
"s-109"
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:db6d5969a80a819818ed645f08a00fe8dc26972d
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:6379> replicaof 192.168.174.108 6379     # 配置 master 节点信息
OK
127.0.0.1:6379> config set masterauth 123456       # 设置 master 节点认证信息
OK
127.0.0.1:6379> info replication
# Replication
role:slave                                        # 角色转变
master_host:192.168.174.108
master_port:6379
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_read_repl_offset:0
slave_repl_offset:0
master_link_down_since_seconds:-1
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:db6d5969a80a819818ed645f08a00fe8dc26972d
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:6379> get node         # 同步成功
"m-108"
127.0.0.1:6379> 

or

直接修改配置文件
replicaof 192.168.174.108 6379

masterauth 123456

requirepass 123456 

从节点 s-110

127.0.0.1:6379> auth 123456
OK
127.0.0.1:6379> set node s-110
OK
127.0.0.1:6379> get node
"s-110"
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:f9fc8a2506253b2996fd6b572503fec4525e4d9b
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:6379> replicaof 192.168.174.108 6379          # 配置 master 节点信息
OK
127.0.0.1:6379> config set masterauth 123456            # 配置 master 节点认证信息
OK
127.0.0.1:6379> info replication
# Replication
role:slave                                              # 角色转变
master_host:192.168.174.108
master_port:6379
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_read_repl_offset:0
slave_repl_offset:0
master_link_down_since_seconds:-1
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:f9fc8a2506253b2996fd6b572503fec4525e4d9b
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:6379> get node      # 同步成功
"m-108"
127.0.0.1:6379> 

or

直接修改配置文件
replicaof 192.168.174.108 6379

masterauth 123456

requirepass 123456 

主节点查看信息

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.174.109,port=6379,state=online,offset=448,lag=1   # slave 信息
slave1:ip=192.168.174.110,port=6379,state=online,offset=448,lag=0
master_failover_state:no-failover
master_replid:e509943e8e8dc5247fd3c1df974d776dfe593365
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:448
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:448
127.0.0.1:6379> 

日志验证

master 节点

2186:M 12 Dec 2024 08:09:45.199 * Replica 192.168.174.109:6379 asks for synchronization
2186:M 12 Dec 2024 08:09:45.199 * Partial resynchronization not accepted: Replication ID mismatch (Replica asked for 'db6d5969a80a819818ed645f08a00fe8dc26972d', my replication IDs are '0108740a3548acedfec8655321470d82516bd556' and '0000000000000000000000000000000000000000')
2186:M 12 Dec 2024 08:09:45.200 * Replication backlog created, my new replication IDs are 'e509943e8e8dc5247fd3c1df974d776dfe593365' and '0000000000000000000000000000000000000000'
2186:M 12 Dec 2024 08:09:45.200 * Delay next BGSAVE for diskless SYNC
2186:M 12 Dec 2024 08:09:50.635 * Starting BGSAVE for SYNC with target: replicas sockets
2186:M 12 Dec 2024 08:09:50.635 * Background RDB transfer started by pid 2205
2205:C 12 Dec 2024 08:09:50.637 * Fork CoW for RDB: current 0 MB, peak 0 MB, average 0 MB
2186:M 12 Dec 2024 08:09:50.637 * Diskless rdb transfer, done reading from pipe, 1 replicas still up.
2186:M 12 Dec 2024 08:09:50.640 * Background RDB transfer terminated with success
2186:M 12 Dec 2024 08:09:50.640 * Streamed RDB transfer with replica 192.168.174.109:6379 succeeded (socket). Waiting for REPLCONF ACK from replica to enable streaming
2186:M 12 Dec 2024 08:09:50.640 * Synchronization with replica 192.168.174.109:6379 succeeded
2186:M 12 Dec 2024 08:10:11.763 * Replica 192.168.174.110:6379 asks for synchronization
2186:M 12 Dec 2024 08:10:11.764 * Partial resynchronization not accepted: Replication ID mismatch (Replica asked for 'f9fc8a2506253b2996fd6b572503fec4525e4d9b', my replication IDs are 'e509943e8e8dc5247fd3c1df974d776dfe593365' and '0000000000000000000000000000000000000000')
2186:M 12 Dec 2024 08:10:11.764 * Delay next BGSAVE for diskless SYNC
2186:M 12 Dec 2024 08:10:16.835 * Starting BGSAVE for SYNC with target: replicas sockets
2186:M 12 Dec 2024 08:10:16.836 * Background RDB transfer started by pid 2206
2206:C 12 Dec 2024 08:10:16.837 * Fork CoW for RDB: current 0 MB, peak 0 MB, average 0 MB
2186:M 12 Dec 2024 08:10:16.837 * Diskless rdb transfer, done reading from pipe, 1 replicas still up.
2186:M 12 Dec 2024 08:10:16.842 * Background RDB transfer terminated with success
2186:M 12 Dec 2024 08:10:16.843 * Streamed RDB transfer with replica 192.168.174.110:6379 succeeded (socket). Waiting for REPLCONF ACK from replica to enable streaming
2186:M 12 Dec 2024 08:10:16.843 * Synchronization with replica 192.168.174.110:6379 succeeded

slave 节点 

2493:S 12 Dec 2024 08:10:11.317 * MASTER <-> REPLICA sync started
2493:S 12 Dec 2024 08:10:11.319 * Non blocking connect for SYNC fired the event.
2493:S 12 Dec 2024 08:10:11.320 * Master replied to PING, replication can continue...
2493:S 12 Dec 2024 08:10:11.323 # Unable to AUTH to MASTER: -NOAUTH Authentication required.
2493:S 12 Dec 2024 08:10:11.762 * Connecting to MASTER 192.168.174.108:6379
2493:S 12 Dec 2024 08:10:11.762 * MASTER <-> REPLICA sync started
2493:S 12 Dec 2024 08:10:11.762 * Non blocking connect for SYNC fired the event.
2493:S 12 Dec 2024 08:10:11.763 * Master replied to PING, replication can continue...
2493:S 12 Dec 2024 08:10:11.764 * Trying a partial resynchronization (request f9fc8a2506253b2996fd6b572503fec4525e4d9b:1).
2493:S 12 Dec 2024 08:10:16.836 * Full resync from master: e509943e8e8dc5247fd3c1df974d776dfe593365:42
2493:S 12 Dec 2024 08:10:16.838 * MASTER <-> REPLICA sync: receiving streamed RDB from master with EOF to disk
2493:S 12 Dec 2024 08:10:16.838 * Discarding previously cached master state.
2493:S 12 Dec 2024 08:10:16.838 * MASTER <-> REPLICA sync: Flushing old data
2493:S 12 Dec 2024 08:10:16.840 * MASTER <-> REPLICA sync: Loading DB in memory
2493:S 12 Dec 2024 08:10:16.843 * Loading RDB produced by version 7.4.1
2493:S 12 Dec 2024 08:10:16.843 * RDB age 0 seconds
2493:S 12 Dec 2024 08:10:16.843 * RDB memory usage when created 1.11 Mb
2493:S 12 Dec 2024 08:10:16.843 * Done loading RDB, keys loaded: 1, keys expired: 0.
2493:S 12 Dec 2024 08:10:16.843 * MASTER <-> REPLICA sync: Finished with success

删除主从同步 

在从节点执行 REPLICAOF NO ONE  指令可以取消主从复制

从节点 s-110

127.0.0.1:6379> replicaof no one
OK

主节点 m-108

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.174.109,port=6379,state=online,offset=1499,lag=0
master_failover_state:no-failover
master_replid:e509943e8e8dc5247fd3c1df974d776dfe593365
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1499
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1499

Redis 主从故障

slave 节点故障

slave节点故障,从新指向其它的slave节点。

master 节点故障

master 节点故障,需要手动将slave节点提升为master节点。
1. 先停止 slave 节点
     执行:replicaof no one, 角色变为master节点

2. 其它slave节点指向新的master节点
     执行: slaveof MASTER_IP PORT

Redis 主从复制优化

避免全量复制

第一次全量复制不可避免,后续的全量复制可以利用小主节点(内存小),业务低峰时进行全量节点复制
RUN_ID不匹配:主节点重启会导致RUN ID变化,可能会触发全量复制,可以利用config命令动态修改配置,故障转移例如哨兵或集群选举新的主节点也不会全量复制,而从节点重启动,不会导致全量复制,只会增量复制
复制积压缓冲区不足: 当主节点生成的新数据大于缓冲区大小,从节点恢复和主节点连接后,会导致全量复制.解决方法将repl-backlog-size 调大

避免复制风暴

·单主节点复制风暴
    当主节点重启,多从节点复制   
    解决方法:更换复制拓扑
    
·单机器多实例复制风暴
     机器宕机后,大量全量复制
     解决方法:主节点分散多机器

主从同步优化配置

repl-diskless-sync no # 是否使用无盘方式进行同步RDB文件,默认为no(编译安装默认为yes),no表示不使用无盘,需要将RDB文件保存到磁盘后再发送给s1ave,yes表示使用无盘,即RDB文件不需要保存至本地磁盘,而且直接通过网络发送给s1ave

repl-diskless-sync-delay 5 #无盘时复制的服务器等待的延迟时间

rep1-ping-slave-period 10  #slave向master发送ping指令的时间间隔,默认为10s

rep1-timeout 60            #指定ping连接超时时间,超过此值无法连接,master_link_status显示为down状态并记录错误日志

repl-disable-tcp-nodelay no #是否启用TCP_NODELAY#设置成yes,则redis会合并多个小的TCP包成一个大包再发送,此方式可以节省带宽,但会造成同步延迟时长的增加,导致master与slave数据短期内不一致#设置成no,则master会立即同步数据

repl-backlog-size 1mb    #master的写入数据缓冲区,用于记录自上一次同步后到下一次同步前期间的写入命令,计算公式:repl-backlog-size= 允许slave最大中断时长*master节点offset每秒写入量,如:master每秒最大写入量为32MB,最长允许中断60秒,就要至少设置为32*60=1920MB,建议此值是设置的足够大,如果此值太小,会造成全量复制

repl-backlog-ttl 3600     #指定多长时间后如果没有s1ave连接到master,则back1og的内存数据将会过期。如果值为0表示永远不过期。

slave-priority 100        #s1ave参与选举新的master的优先级,此整数值越小则优先级越高。当master故障时将会按照优先级来选择s1ave端进行选举新的master,如果值设置为0,则表示该s1ave节点永远不会被选为master节点。

min-replicas-to-write 1   #指定master的可用s1ave不能少于个数,如果少于此值,master将无法执行写操作,默认为0,生产建议设为1,

min-slaves-max-1ag 20    #指定至少有min-replicas-to-write数量的slave延迟时间都大于此秒数时,master将不能执行写操作,默认为10s

参考文档

https://redis.io/docs/latest/operate/oss_and_stack/management/replication/

posted @   小吉猫  阅读(36)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
历史上的今天:
2023-12-13 Argo Rollouts 基础
2023-12-13 ArgoCD ApplicationSet CRD
2023-12-13 ArgoCD AppProject CRD
2023-12-13 ArgoCD Application CRD
2021-12-13 kubernetes基于NFS实现nginx+tomcat动静分离
2021-12-13 ubuntu20.04部署nfs
2021-12-13 kubernetes运行nginx+tomcat
点击右上角即可分享
微信分享提示

目录导航