目录
- 1.原理
-
- [1.建立复制 && 复制过程](#1.建立复制 && 复制过程)
- [2.数据同步 psync](#2.数据同步 psync)
- 3.复制偏移量维护
- [4.psync 运行流程](#4.psync 运行流程)
1.原理
1.建立复制 && 复制过程
-
保存主节点(master)的信息
-
开始配置主从同步关系之后,从节点只保存主节点的地址信息,此时建⽴复制流程还没有开始
-
在从节点6380执⾏
info replication
可以看到如下信息ip
和port
被保存下来,但是主节点的连接状态是下线状态
plaintextmaster_host: 127.0.0.1 master_port: 6379 master_link_status: down
-
-
主从建立连接 :
- 从节点(
slave
)内部通过每秒运⾏的定时任务维护复制相关逻辑,当定时任务发现存在新的主节点后,会尝试与主节点建⽴基于TCP的⽹络连接 - 如果从节点⽆法建⽴连接,定时任务会⽆限重试直到连接成功或者⽤⼾停⽌主从复制
- 从节点(
-
发送
ping
命令 :- 发送
ping
命令。连接建⽴成功之后,从节点通过ping
命令确认主节点在应⽤层上是⼯作良好的 - 如果
ping
命令的结果pong
回复超时,从节点会断开TCP连接,等待定时任务下次重新建⽴连接
- 发送
-
权限验证 :
- 如果主节点设置了
requirepass
参数,则需要密码验证,从节点通过配置masterauth
参数来设置密码 - 如果验证失败,则从节点复制将会停⽌
- 如果主节点设置了
-
同步数据集 :
- 对于⾸次建⽴复制的场景,主节点会把当前持有的所有数据全部发送给从节点,这步操作基本是耗时最⻓的
- 所以⼜划分称两种情况:全量同步和部分同步
-
命令持续复制 :
- 当从节点复制了主节点的所有数据之后,针对之后的修改命令,主节点会持续的把命令发送给从节点,从节点执⾏修改命令,保证主从数据的⼀致性
- 当从节点复制了主节点的所有数据之后,针对之后的修改命令,主节点会持续的把命令发送给从节点,从节点执⾏修改命令,保证主从数据的⼀致性
2.数据同步 psync
- Redis使用
psync
命令完成主从数据同步,同步过程分为:全量复制和部分复制- 全量复制 :
- ⼀般⽤于初次复制场景,Redis早期⽀持的复制功能只有全量复制,它会把主节点全部数据⼀次性发送给从节点
- 当数据量较⼤时,会对主从节点和⽹络造成很⼤的开销
- 部分复制 :
- ⽤于处理在主从复制中因⽹络闪断等原因造成的数据丢失场景
- 当从节点再次连上主节点后,如果条件允许,主节点会补发数据给从节点
- 因为补发的数据远⼩于全量数据,可以有效避免全量复制的过⾼开销
- 全量复制 :
PSYNC
语法 :PSYNC replication offset
- 如果
replicationid
设为?
并且offset
设为-1
,此时就是在尝试进⾏全量复制 - 如果
replicationid offset
设为了具体的数值,则是尝试进⾏部分复制
- 如果
replicationid/replid
(复制id) :-
主节点的复制id,主节点 重新启动,或者从节点晋级成主节点,都会生成一个
replicationid
- 同一个节点,每次重启,生成的
replicationid
也会变化
- 同一个节点,每次重启,生成的
-
从节点和主节点建立连接之后,就会获取到主节点的
replicationid
-
通过
info replication
即可看到replicationid
plaintext127.0.0.1:6379> info replication # Replication role:master connected_slaves:0 master_replid:1da596acecf5a34b4b2aae45bd35be785691ae69 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
-
关于
master_replid
和master_replid2
,每个节点需要记录两组master_replid
,这个设定解决的问题场景是这样的:- 比如当前有两个节点A和B,A为
master
,B为slave
- 此时B就会记录A的
master_replid
- 此时B就会记录A的
- 如果网络出现抖动,B以为A挂了,B自己就会成为主节点,于是B给自己分配了新的
master_replid
,此时就会使用master_replid2
来保存之前A的master_replid
- 后续如果网络恢复了,B就可以根据
master_replid2
找回之前的主节点 - 后续如果网络没有恢复,B就按照新的
master_replid
自成一派,继续处理后续的数据
- 后续如果网络恢复了,B就可以根据
- 比如当前有两个节点A和B,A为
-
明辨
replid
和runid
?runid
:主要用在支撑实现Redis哨兵这个功能,和主从复制没关系replid
:主要在主从复制中起到作用
-
offset
(偏移量) :-
参与复制的主从节点都会维护⾃⾝复制偏移量
- 主节点(
master
)在处理完写⼊命令后,会把命令的字节⻓度做累加记录,统计信息在info replication
中的master_repl_offset
指标中
plaintext127.0.0.1:6379> info replication # Replication role:master ... master_repl_offset:1055130
- 主节点(
-
从节点(
slave
)每秒钟上报⾃⾝的复制偏移量给主节点,因此主节点也会保存从节点的复制偏移量plaintext127.0.0.1:6379> info replication connected_slaves:1 slave0:ip=127.0.0.1,port=6380,state=online,offset=1055214,lag=1 ...
-
从节点在接受到主节点发送的命令后,也会累加记录⾃⾝的偏移量,统计信息在
info replication
中的slave_repl_offset
指标中plaintext127.0.0.1:6380> info replication # Replication role:slave ... slave_repl_offset:1055214
-
3.复制偏移量维护
-
通过对⽐主从节点的复制偏移量,可以判断主从节点数据是否⼀致
-
replid
+offset
共同标识了⼀个"数据集"- 如果两个节点,他们的
replid
和offset
都相同,则这两个节点上持有的数据,就⼀定相同
- 如果两个节点,他们的
4.psync 运行流程
-
从节点发送
psync
命令给主节点,replid
和offset
的默认值分别是?
和-1
-
主节点根据
psync
参数和自身数据情况决定响应结果- 如果回复
+FULLRESYNC replid offset
,则从节点需要进⾏全量复制流程 - 如果回复
+CONTINEU
,则从节点进⾏部分复制流程 - 如果回复
-ERR
,说明Redis主节点版本过低,不⽀持psync
命令- 从节点可以使⽤
sync
命令进⾏全量复制
- 从节点可以使⽤
- 如果回复
-
说明:
psync
⼀般不需要⼿动执⾏,Redis
会在主从复制模式下⾃动调⽤执⾏- 从节点负责执行
psync
,从节点从主节点这边拉取数据
- 从节点负责执行
sync
会阻塞redisserver
处理其他请求,psync
则不会