【Redis系列9】手把手带你搭建单机版高可用分布式Redis集群(Cluster)

复制积压缓冲区

上面的部分重同步貌似看起来能解决问题,但是这又会带来另一个问题,那就是当主服务器将命令发送出去之后,为了实现部分重同步还需要将命令保存起来,否则当从服务器的偏移量低于主服务器时,主服务器也无法将命令重传播。

那么问题就来了,这个命令要保存多久呢?如果一直保存下去就会占据大量的空间,为了解决这个问题,master服务器维护了一个固定长度的FIFO队列,即复制积压缓冲区

当进行命令传播的过程中,master服务器不仅会将命令传播给所有的slave服务器,同时还会将命令写入复制积压缓冲区。复制积压缓冲区默认大小为1MB。

下面就是一个完整的部分重同步流程图:

在这里插入图片描述

也就是说,当master服务器记录的偏移量+1已经不存在与复制积压缓冲区了,就会执行一次全量同步,即发送RDB文件给从服务器。

主从服务的不足之处

主从服务器通过读写分离实现了数据的可靠性,但是其并未实现系统的高可用性。其主要存在以下两个问题:

  • 1、首次同步或者部分重同步时需要执行全量同步时发送的RDB文件如果过大,则会非常耗时。

  • 2、假如master服务器挂了,那么系统并不能手动切换master服务器,仍然需要人为进行切换。

哨兵Sentinel机制


Redis的Sentinel机制主要是为了实现Redis服务器的高可用性而设计的一种解决方案。这种方案也是为了弥补主从复制模式的不足,Sentinel机制实现了主从服务的自动切换。

Sentinel原理分析

Sentinel其本身也是一个特殊的Redis服务,在Redis的安装包内,除了redis.conf文件,还有一个sentinel.conf文件,这个就是启动sentinel服务的配置文件,启动命令则通过redis-sentinel来执行(如:./redis-sentinel ../sentinel.conf)或者也可以通过redis-server命令指定参数sentinel来启动(如:./redis-server ../sentinel.conf --sentinel)。

Sentinel主要用来监控Redis集群中的所有节点,当Sentinel服务发现master不可用时,可以实现master服务的自动切换。但是如果Sentinel服务自己挂了怎么办?所以为了实现高可用,Sentinel服务本身也是一个集群,和Redis的master-slave模式不同的是,Sentinel集群之间在正常情况下没有主从关系,相互之间是平等的,只有在需要执行故障转移时才需要进行Leader选举。

下图就是一个3个Sentinel服务集群和1主2从的Redis集群示意图:

在这里插入图片描述

Sentinel集群之间的服务会互相监控,然后每个Sentinel服务都会监控所有的master-slave节点,一旦发现master节点不可用,则Sentinel中通过选举产生的Leader节点会执行故障转移,切换master节点。

主观下线和客观下线

Sentinel服务默认以每秒1次的频率向Redis服务节点发送ping命令(Sentinel服务之间也会发送ping命令进行检测)。如果在指定时间内(可以由参数down-after-milliseconds进行控制,默认30s)没有收到有效回复,Sentinel会将该服务器标记为下线,即主观下线

down-after-milliseconds master-name milliseconds

当某一个Sentinel把master服务标记为主观下线之后,会去询问其他Sentinel节点,确认这个master是否真的下线,当达到指定数量的Sentinel服务都认为master服务器已经主观下线,这时候Sentinel就会将master服务标记为客观下线,并执行故障转移操作。

多少个Sentinel服务认定master节点主观下线才会正式将master服务标记为客观下线,由以下参数控制:

sentinel monitor

其中的quorum选项就是决定了这个数量。

需要注意的是,每个Sentinel服务的判断主观下线和客观下线的配置可能不一样,所以当Sentinel1判定master已经主观下线或者客观下线时,其他Sentinel服务并不一定会这么认为,但是只要有一个Sentinel判定master已经客观下线,其就会执行故障转移,但是故障转移并不一定是由判断为客观下线的Sentinel服务来执行,在执行故障转移的之前,Sentinel服务之间必须进行Leader选举。

Leader选举

当某一个或者多个Sentinel服务判定master服务已经下线,其会发起Leader选举,选举出Leader之后,由Leader节点执行故障转移。

Raft选举算法

Sentinel服务的Leader选举是通过Raft算法来实现的。Raft是一个共识算法(consensus algorithm),其核心思想主要有两点:

  • 1、先到先得

  • 2、少数服从多数

在Raft算法中,每个节点都维护了一个属性election timeout,这是一个随机的时间,范围在150ms~300ms之间,哪个节点先到达这个时间,哪个节点就可以发起选举投票。

选举步骤总要可以总结为以下步骤:

  • 1、发起选举的服务首先会给自己投上一票。

  • 2、然后会向其他节点发送投票请求到其他节点,其他节点在收到请求后如果在election timeout范围内还没有投过票,那么就会给发起选举的节点投上一票,然后将election timeout重置。

  • 3、如果发起选举的节点获得的票数超过一半,那么当前服务就会成为Leader节点,成为Leader节点之后就会维护一个heartbeat timeout时间属性,在每一次到达heartbeat timeout时间时,Leader节点就会向其他Follow节点发起一个心跳检测。

  • 4、Follow节点收到Leader节点的心跳包之后就会将election timeout清空,这样可以防止Follow节点因为到达election timeout而发起选举。

  • 5、假如Leader节点挂了,那么Follow节点的election timeout将不会被清空,谁先到达,谁就会再次发起选举。

PS:因为election timeout是一个随机值,虽然概率小,但也可能出现两个节点同时发起投票选举,这种情况就可能出现一次选举并不能选出Leader(比如总共4个节点,每个节点都得了2票),此时就会等待下一次首先到达election timeout的节点再次发起投票选举。

如果对Raft算法感兴趣的,可以点击这里观看演示。

Sentinel选举Leader

Sentinel中的选举虽然是源于Raft算法,但是也做了以下改进:

  • 1、触发选举并不是由election timeout时间决定,而是由谁先判定master下线来决定的。

  • 2、Sentinel节点并没有维护election timeout属性,而是维护了一个配置纪元configuration epoch属性,配置纪元是一个计数器(默认0),每一个Sentinel节点的同一个配置纪元只能投票1次(先到先得),每次投票前会将配置纪元自增+1。

  • 3、选举出Leader之后,Leader并不会向Follow节点发送心跳包告诉其他Follow节点自己成为了Leader。

故障转移

当Sentinel选举出Leader之后,Leader就会开始执行故障转移,执行故障转移主要分为一下三步:

  • 1、在已判定客观下线的master服务器的slave服务器中找到一个合格的slave服务器,向其发送replicaof no one命令,使其转换为master服务。

  • 2、向其他从服务器发送replicaof ip port命令,使其成为新master服务的slave节点。

  • 3、将已下线的master服务也设置为新的master服务的slave节点。

如何选举新的master节点

新的master选举条件主要需要参考4个因素:

  • 1、断开连接时长:首先将所有于已下线master节点断开连接时间超过down-after-milliseconds * 10的slave节点删除掉,确保salve节点的数据都是比较新的。

  • 2、slave节点的优先级排序:将所有的salve节点按照优先级进行排序,选出优先级最高的slave节点作为新的master节点(优先级由配置文件参数replica-priority决定,默认100)。

  • 3、复制偏移量:如果有多个优先级相同的slave节点,则选出复制偏移量最大的的slave节点作为新的master节点。

  • 4、进程id:如果还是没选出新的master节点,那么会再次选择进程id最小的slave节点作为新的master节点。

配置Sentinel集群

配置sentinel需要修改sentinel.conf配置文件

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值