一、主从模式的概念
在Redis中,只有主节点拥有写操作的权限,从节点只能进行读操作,而且还要不停从主节点进行复制来保证自己的数据始终处于最新状态。这样的做的原因一方面是因为一般的业务主要是以读操作为主,另一方面是为了避免从节点修改数据导致主从数据不一致的问题。
修改主从结构的三种方式:
1.在配置文件中添加salveof{masterHost}{masterPort},这个操作在Redis重启后生效,而且由于修改的是配置文件,所以是长久生效的。
2.在Redis-service启动时加上--salveof{masterHost}{masterPort},但是这个只在这一次启动生效,不能长久生效。
3.直接使用命令salveof{masterHost}{masterPort},也是不持久的。
主从模式的结构:
主要分为两类:
1.树状结构:
这种结构中,A是主节点,虽然B对于D来说也是主节点,但是B本质仍然是从节点,只有读操作,没有写操作能力。
这种结构优势是主节点A的网络带宽压力会小很多,因为它无需同时向所有从节点传输信息(通过TCP连接传输),但是缺点就是无法同时让所有的从节点更新数据,会存在无法避免的延时。
2.扁平化结构
这样优势就是主节点A可以同时向所有从节点发送信息,让它们同时同步主节点,但是A节点网络带宽压力就会比较大。
在主从结构柱一般默认是读操作更多,但是如果出现写操作过多的情况,我们可以通过关闭主节点上的AOF(一种持久化策略)来减轻主节点压力,但是要注意在主节点重启时,要使用从节点的AOF文件来加载数据。
二、主从模式建立连接的详细过程
1.从节点保存主节点的信息:IP地址,端口号等
2.从节点和主节点通过TCP的三次握手来建立连接。
3.发送Ping命令,这主要是验证主节点是否能正常工作。
4.权限验证,这主要是对安全方面的考虑.
5.同步数据集。
6.持续进行命令复制。
其中较为重要的是5和6
同步数据集
分为全量复制和增量复制
如果是初次建立连接,主从之间肯定要进行全量复制,同步数据集过程为
1.从节点发送Psync命令给主节点,其中包含一个表示偏移量的信息offset,若为第一次则是-1,同时主节点也在维护一个环形的命令挤压缓冲区,它会检查从节点的offset是否在环形挤压缓冲区的范围内,如果在,就进行增量复制即可此时只需要主节点将之后的命令发送给从节点即可,如果不在,就进行全量复制。在全量复制的情况下,主节点回复+FULL_RESYNC命令。
2.在全量复制的情况下,从节点会先保存主节点的运行信息。
3.主节点进行bgsave命令,生成RDB文件,采用RDB文件的原因则是RDB为二进制文件,相较于AOF的文本文件更省空间。
4.从节点在接收到RDB文件后,会先将其保存到硬盘上,然后进行数据加载。
5.主节点将从节点保存和加载RDB文件过程中的命令写到一个缓冲区中,待从节点加载完成后,再将其发送给从节点,保证主从一致。
其中redis从节点中还有一个重要的属性:replicationId,这个Id一般有两个。第一个是主节点在启动时产生的,同时还有一个Id从节点会在自己变为主节点后用来存储原本的主节点的Id。
三、主从模式中的故障转移
主流的故障转移技术包含Redis Cluster和Redis哨兵模式(Redis Sentinel)这两种自动故障转移模式,除此还有手动模式,一般用于突发的特殊情况。而Redis Cluster则用于大型数据库情况下,这种情况下单一节点的内存已经不能满足需要,需要进行“分片”操作,一般用于Redis集群模式中,这个之后会将,这里主要讨论的是Redis的哨兵模式。
首先,哨兵节点是独立于Redis-service的节点,不负责数据存储,而且一般是多个哨兵节点,而且是奇数(为了满足后面要说的leader选举和下线判断,一般也就是3/5个)。
哨兵模式工作的流程:
1.当一个哨兵节点发现主节点不能连接(通过ping命令发现,而且超时时间可以设置),它会标记其为“主观下线”状态,而且会共享这个信息给其他哨兵节点,当有超过半数的哨兵都发现主节点下线后,才会将其标记为“客观下线”状态,这样主要是为了避免网络波动导致的误判。
2.一般是首个发现主节点为“客观下线”的哨兵节点发起“Leader”的选举,而且会率先投自己一票,这是其他哨兵节点接收到消息后,如果没有投票,就会投第一个发现的节点,因为理论上它的网络最好,超过半数后,leader就会产生,进行故障转移操作,也就是确立一个新的主节点。
3.leader会在满足要求的从节点中进行挑选(不能是下线,正在进行故障转移过程),首先是看优先级,一般从节点的优先级都是一样的,但是如果手动设置了更高的优先级,那么这个节点会优先被设置为主节点;其次如果优先级都一样,那就看从节点中谁的offset更大,更大的表示数据最新,会优先被设置为主节点;最后,如果offset都一样,那就进行随机操作了,因为它们本质上都一样,这时会比较runId(启动时生成),这个runId是随机的,有的版本是先启动的最小,一般选最小的为主节点。
4.然后leader会向选举出的从节点发送 salveof no one 命令让其解除与主节点的联系,然后向其他节点发送salveof {masterHost}{masterPort}命令,让它们与新的主节点建立联系。然后再将新的主从结构广播给其他的哨兵节点。
关于主节点的问题,默认情况先原主节点是不会重新成为主节点的(故障转移正常选举除外),但是由于主节点的硬件资源可能更优,程序员一般会设置它的优先级更高,在下一轮故障转移中会优先被选举为主节点。