目录
1.psync 数据同步
通过psync命令来实现主从同步数据,是从节点给主节点发的命令,这个命令不需要手动执行,当建立好主从连接关系后,redis会自动执行这个命令.
psync语法格式: psync replication offset
replication 复制:
缩写:replid :是主节点的id.
从节点的master-replid 记录是从哪个主节点同步的.即主节点的id.
可以看到,这里有两个replid,第二个是全为0,当主节点和从节点的数据传输过程中出现网络抖动,或主节点挂了,与从节点连接的主节点目前不存在,当从节点就晋升为新的主节点时,会生成新的id,保存在replid中;这时replid2就会保存原来的主节点的id,之后当主节点又恢复了,可以再通过replid2再与主节点连接起来.
offset偏移量:
主节点和从节点都会维护一个偏移量,用来记录当前从节点同步主节点数据的进度.
主节点上每收到一个操作数据的命令(读数据除外),每个命令都会占据几个字节的空间,主节点会把这些命令的字节数累加(一个整型数字);当从节点同步时,也会记录类加偏移量.
当从节点的偏移量和主节点相同时,就表示这个从节点中的数据和主节点的数据完全一致了.
当两个从节点的replication和offset完全一致是,说明这两个从节点中的内容是完全相同的.(从同一个主节点复制,同步进度相同).
2.psync运行流程:
psync命令是从节点向主节点发送的命令,用来让主节点同步数据到从节点。
同步数据的方式有全量复制,部分复制和实时复制;主节点要根据psync命令的参数判断是哪种复制。
psync语法格式: psync replication offse
当replication为? ,且 offset = -1时,则尝试进行全量复制;
offset为一个确定的正整数时,是从指定的偏移量进行复制,即部分复制.但实际是哪种复制,还要看主节点是否方便部分复制,若无法部分复制,即使offset指定了具体的值,还是会进行全量复制.
运行流程:
1>.从节点给主节点发送psync命令,
2>.主节点根据psync参数和自身数据情况决定响应结果,主节点返回的命令有一下几种:
-FULLRESYNC:从节点进行全量复制流程
-CONTINUE:从节点进行部分复制流程
-ERR:说明redis版本过低,不支持psync命令。可以使用sync命令进行全量复制。(sync命令会阻塞redis server处理其他请求,psync不会 )
3.全量复制
全量复制在redis主从节点第一次进行数据同步的时候进行,即从节点刚和主节点建立连接的时候。
流程如下:
1.从 主动发送psync命令给 主 进行数据同步,由于是第一次复制,从 没有 主 的replid和复制偏移量,所以发送psync ? -1.
2.主根据命令,解析出要进行全量复制,回复 -FULLRESYNC响应。
3.从 收到主 的运行id等信息,并进行保存·。
4.主 开始执行bgsave,进行RDB文件的持久化。
5.主 发送RDB文件给 从,从 先保存RDB文件到本地硬盘中。
6.主节点在生成rdb文件和将rdb文件传输给从节点的过程中,可能又会有对数据的操作命令:
于是: 主 将 从开始执行bgsave命令到发送给从节点之间又产生的 写命令,写入一个缓冲区中,等 从保存完rdb文件,主 再将缓冲区中的数据补发给 从节点,补发的数据仍以rdb的二进制格式追加到写入的rdb文件中,补发是为了保持 主从一致性。
7.从节点清空自身原有的旧数据,
8.从节点加载rdb文件和主节点保持数据一致。
9.若从节点开启了aof持久化功能,在加载完rdb文件后会执行bgrewrite操作(由于目前得到的是所有的数据,数据存在一定的冗余,此操作会进行数据的整理,瘦身),得到最新的aof文件。
在第四部,主节点生成rdb文件,有两个可讨论的小问题:
1>.为啥用rdb文件存储,而不是aof文件?
使用rbd文件,而不是aof文件,是因为rdb文件是以二进制的形式存储的,aof是以文本格式存储的,主节点通过网络传输向从节点传输大量数据时,rdb文件节省空间.
2>.若主节点的持久化方式就是以rdb文件形式存储,能否将已有的rdb文件直接传输给从节点,不再重新进行rdb文件持久化?
不能, 因为主从同步,要求的不是尽量保持一致,而是要求100%的一致,此时可能主节点已经有新的数据操作,但还未被rdb持久化,若直接将已有的rdb文件传输过去,更不能保证主从节点数据的一致性了,因此主节点必须要重新生成rdb文件.
全量复制是一件成本较高的操作,应尽可能避免对大量数据集的redis执行全量复制。
无磁盘复制 diskless:
但在一些情况下,不得不执行全量复制,可以通过采用“无磁盘复制”的方法来降低开销:
默认情况下,进行全量复制主节点要将生成的rdb文件存储到磁盘上,然后再将磁盘上的rdb文件发送给从节点。
redis的2.8.18版本支持无磁盘复制,即主节点在执行bgsave命令,生成rdb文件后,不会将生成的rdb文件存储到磁盘,而是直接通过网络传输将rdb文件发送给从节点。从节点接收到的rdb也可以不写入磁盘,直接加载.也会节省文件存储到磁盘带来的开销. 这样就节省了一系列的写硬盘和都硬盘的操作开销。
注意: 尽管引入了“无盘复制”,但全量复制的成本还是很高了,仅是得到了较小的优化,对网络传输等操作是无法缓解的,还是要尽量避免全量复制。
4.部分复制:
部分复制也是在主从节点建立连接后,进行第一次复制的操作。
部分复制是全量复制的一种优化机制,复制流程和全量复制流程一样,只是发生部分复制和全量复制的情况不同。
进行行全量复制的情况:
1.主从节点第一次建立连接,第一次同步数据。
2.主节点不方便进行部分复制。
进行部分复制的情况:
1.从节点已经复制过主节点的数据,因为网络抖动,或从节点重启了;
2.当主从节点因为一些情况断开来连接,后又连接上,从节点只需要同步部分主节点的数据(主从节点的大部分数据已经是一致的)。
部分复制过程:
1>.当主从节点出现网络问题中断时,如果超过 repl-timeout 时间,主节点会认为 从节点故障并 中断 复制连接。
2>.主从节点断开连接后,主节点还会接收响应命令. 由于主从节点断开了,从节点无法再同步主节点的数据了; 主节点在和从节点断开后,将收到的响应暂时 存放在一个积压缓冲区中.
3>.当主节点网络恢复后,从节点会再次连接上主节点.
4>.从节点将之前保存的replicationId和offset信息,通过发送psync命令给主节点,进行部分数据同步.
5>.主节点收到psync命令后,通过验证后,根据offset去复制积压缓冲区中的合适数据,并响应-CONTINUE给从节点
6>.主节点将从节点需要的数据同步给从节点,完成主从一致性.
细节:
1. 积压缓冲区:
就是一个内存中一个简单的队列,会记录最近一段时间数据的修改,但由于空间有限,随着时间的推移,会把之前旧的数据删除.
2.当主节点网咯恢复后,收到从节点的psync命令后,要进行验证,验证的内容:
1>.判断从节点传过来的replicationId是否是自己的.若不是自己的Id,说明该从节点未和主节点有过连接,需要进行全量复制. 若是,说明是网络中断之前连接过的从节点;
2.确认是之前断开的从节点后,再判断offset,看数据复制的进度是否在积压缓冲区的范围内,若太多数据需要同步,已经超出积压缓冲区的范围,就需要进行全量复制; 若在积压缓冲区的范围内,就再积压缓冲区中找到确定的位置,进行部分复制即可.
5.实时复制
在主节点和从节点已经建立连接并同步过全量数据后,主节点就会把后续的数据的修改,通过tcp长连接,实时复制给从节点,从而保证主从节点的一致性.
这里的长连接需要通过"心跳包"来进行维护:
1>.主从节点都有心跳检测,各⾃模拟成对⽅的客⼾端进⾏通信,
2>.主节点默认每隔 10 秒对从节点发送 ping 命令,判断从节点的存活性和连接状态。
3>.从节点默认每隔 1 秒向主节点发送 replconf ack {offset} 命令,给主节点上报⾃⾝当前的复制偏移量.
如果主节点发现从节点通信延迟超过 repl-timeout 配置的值(默认 60 秒),则判定从节点下线,断开复制客⼾端连接。从节点恢复连接后,⼼跳机制继续进⾏
注意: 这里的时间都是可以进行自己设定的.(无需记忆)
6.replicationId和runid的区别:
replicationId和runId在一个redis服务器上都存在,来观察一下这两个的区别:
主节点的replicationId:
主节点的runId:通过info server命令获取:
查看从节点6380的replicationId:
6380的runId:
6381的replicationId:
6381的runId:
可以看到三个节点的replicationId都是相同的,而runId都是不同的.
总结:
replicationId是用来确认连接的主节点的标识符.在主从复制中起作用;
runId是标识一次redis的运行,redis每重启一次,都会生成一个新的runId.是用来实现redis哨兵功能的.runId和主从复制没有关系.
这两个符号的长度相同,格式相似,但他俩没啥关系.
7.主从复制的缺陷:
1.若主从节点采用的树形结构,数据同步会存在延迟性,
2.一旦主节点挂了.从节点就不知道要怎么办了,这时就需要通过人工干预的方式恢复.但人工处理往往是具有非常的大的延迟性和存在出错的可能,即需要再采取措施来处理这样的问题,就是通过哨兵机制来解决.
下一篇文章讲的就是redis的哨兵机制.