redis集群

主从:

同步场景

1、在Redis2.8之前只能使用sync命令来主从同步数据就是全量复制,sync命令会在不管slave是第一次启动还是断线重连都会全量的去复制数据,在Redis2.8之后使用psync命令来完成主从数据同步,psync弥补对sync只能全量同步数据的问题,psync的同步过程分为全量复制跟增量复制

2、redis2.8之前的版本中断线情况下SYNC进行全量同步的低效问题,在Redis 2.8之后使用psync命令代替sync命令执行同步操作,psync具备了数据全量重同步 和 部分重同步模式

Redis的同步数据在主从初次启动psync跟sync命令都是全量复制。当服务器断线重连时,sync采用的是全量复制而psync采用的是增量复制

PSYNC执行过程中比较重要的概念有3个:runid、offset(复制偏移量)以及复制积压缓冲区

1.runid

每个Redis服务器都会有一个表明自己身份的ID。在PSYNC中发送的这个ID是指之前连接的Master的ID,如果没保存这个ID,PSYNC的命令会使用”PSYNC ? -1” 这种形式发送给Master,表示需要全量复制。

2.offset(复制偏移量)

在主从复制的Master和Slave双方都会各自维持一个offset。Master成功发送N个字节的命令后会将Master里的offset加上N,Slave在接收到N个字节命令后同样会将Slave里的offset增加N。

Master和Slave如果状态是一致的那么它的的offset也应该是一致的。

3.复制积压缓冲区

复制积压缓冲区是由Master维护的一个固定长度环形积压队列(FIFO队列),它的作用是缓存已经传播出去的命令。当Master进行命令传播时,不仅将命令发送给所有Slave,还会将命令写入到复制积压缓冲区里面。

Master接收到PSYNC 命令后,首先判断runid是否和本机的id一致,如果一致则会再次判断offset偏移量和本机的偏移量相差有没有超过复制积压缓冲区大小,如果没有那么就给Slave发送CONTINUE,此时Slave只需要等待Master传回失去连接期间丢失的命令

乐观复制

 #代表至少N台从服务器完成复制,才允许主服务器可写入,否则会返回错误。

 min-slaves-to-write 3

 #允许从服务器断开连接的时间(单位s)

 min-slaves-max-lag 10

  Redis的主从同步支持两种机制,一种为master同步给所有slave,另外一种slave级联同步,即master同步给一个slave,这个slave再充当伪“master”同步给下一个slave,这种机制的好处是减少master的数据传输量,节省master的带宽,同时在新slave加入时或者多个slave重连时,避免全部需要master来接收,造成master资源紧张

sentinel哨兵模式介绍:

Sentinel(哨兵)是用于监控redis集群中Master状态的工具,是Redis 的高可用性解决方案,sentinel哨兵模式已经被集成在redis2.4之后的版本中。sentinel是redis高可用的解决方案,sentinel系统可以监视一个或者多个redis master服务,以及这些master服务的所有从服务;当某个master服务下线时,自动将该master下的某个从服务升级为master服务替代已下线的master服务继续处理请求。

sentinel可以让redis实现主从复制,当一个集群中的master失效之后,sentinel可以选举出一个新的master用于自动接替master的工作,集群中的其他redis服务器自动指向新的master同步数据。一般建议sentinel采取奇数台,防止某一台sentinel无法连接到master导致误切换

Sentinel状态持久化

snetinel的状态会被持久化地写入sentinel的配置文件中。每次当收到一个新的配置时,或者新创建一个配置时,配置会被持久化到硬盘中,并带上配置的版本戳。这意味着,可以安全的停止和重启sentinel进程。

Sentinel作用: 

1)Master状态检测 

2)如果Master异常,则会进行Master-Slave切换,将其中一个Slave作为Master,将之前的Master作为Slave。 

3)Master-Slave切换后,master_redis.conf、slave_redis.conf和sentinel.conf的内容都会发生改变,即master_redis.conf中会多一行slaveof的配置,sentinel.conf的监控目标会随之调换。

Sentinel工作方式(每个Sentinel实例都执行的定时任务)

1)每个Sentinel以每秒钟一次的频率向它所知的Master,Slave以及其他 Sentinel 实例发送一个PING命令。

2)如果一个实例(instance)距离最后一次有效回复PING命令的时间超过 own-after-milliseconds 选项所指定的值,则这个实例会被Sentinel标记为主观下线。 

3)如果一个Master被标记为主观下线,则正在监视这个Master的所有 Sentinel 要以每秒一次的频率确认Master的确进入了主观下线状态。 

4)当有足够数量的Sentinel(大于等于配置文件指定的值)在指定的时间范围内确认Master的确进入了主观下线状态,则Master会被标记为客观下线。

5)在一般情况下,每个Sentinel 会以每10秒一次的频率向它已知的所有Master,Slave发送 INFO 命令。

6)当Master被Sentinel标记为客观下线时,Sentinel 向下线的 Master 的所有Slave发送 INFO命令的频率会从10秒一次改为每秒一次。 

7)若没有足够数量的Sentinel同意Master已经下线,Master的客观下线状态就会被移除。 若 Master重新向Sentinel 的PING命令返回有效回复,Master的主观下线状态就会被移除。

三个定时任务

sentinel在内部有3个定时任务

1)每10秒每个sentinel会对master和slave执行info命令,这个任务达到两个目的:

a)发现slave节点

b)确认主从关系

2)每2秒每个sentinel通过master节点的channel交换信息(pub/sub)。master节点上有一个发布订阅的频道(__sentinel__:hello)。sentinel节点通过__sentinel__:hello频道进行信息交换(对节点的"看法"和自身的信息),达成共识。

3)每1秒每个sentinel对其他sentinel和redis节点执行ping操作(相互监控),这个其实是一个心跳检测,是失败判定的依据。

主观下线,单个sentinel的状态,客观下线,多个sentinel的状态

Redis Sentinel的主从切换方案

Redis 2.8版开始正式提供名为Sentinel的主从切换方案,通俗的来讲,Sentinel可以用来管理多个Redis服务器实例,可以实现一个功能上实现HA的集群,Sentinel主要负责三个方面的任务:

1)监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。

2)提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。

3)自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。

Redis的哨兵是怎么通信的?

通过Redis的订阅发布来实现集群间的通信

为什么不搭建俩台哨兵的集群呢?

如最少 quorum =1,majority要比quorum大 所以他得是 2 而执行故障切换的时候需要经过majority同意就是这个范围的哨兵投票同意,所以就得全部的哨兵同意才能执行故障转移,所以可用性就不高,三台挂了一台哨兵还是可以执行故障转移,可用性就高点,这里我为什么引出了这个问题呢?

心跳检测

怎么知道master还存活呢?我们的哨兵会发送一个info指令获取到master的信息跟master之间保持心跳检测

在故障发生时,需要立即启动故障恢复机制,那么如何保证及时性呢?

每个哨兵节点每隔1秒向master、slave、其他哨兵节点发送ping命令,如果对方能在指定时间内响应,说明节点健康存活。如果未在规定时间内(可配置)响应,那么该哨兵节点认为此节点主观下线。

选举哨兵领导者

确认master节点真正故障后,就需要进入到故障恢复阶段。如何进行故障恢复,也需要经历一系列流程。

首先需要选举出一个哨兵领导者,由这个专门的哨兵领导者来进行故障恢复操作,不用多个哨兵都参与故障恢复。选举哨兵领导者的过程,需要多个哨兵节点共同协商来选出。

这个选举协商的过程,在分布式领域中叫做达成共识,协商的算法叫做共识算法。

共识算法主要为了解决在分布式场景下,多个节点如何针对某一个场景达成一致的结果。

共识算法包括很多种,例如Paxos、Raft、Gossip算法等,(可以说下Raft算法,其他俩个复杂)。

哨兵选举领导者的过程类似于Raft算法,它的算法足够简单易理解。

简单来讲流程如下:

每个哨兵都设置一个随机超时时间,超时后向其他哨兵发送申请成为领导者的请求

其他哨兵只能对收到的第一个请求进行回复确认

首先达到多数确认选票的哨兵节点,成为领导者

如果在确认回复后,所有哨兵都无法达到多数选票的结果,那么进行重新选举,直到选出领导者为止

选择出哨兵领导者后,之后的故障恢复操作都由这个哨兵领导者进行操作。

选择新的master

哨兵领导者针对发生故障的master节点,需要在它的slave节点中,选择一个节点来代替其工作。

这个选择新master过程也是有优先级的,在多个slave的场景下,优先级按照:slave-priority配置 > 数据完整性 > runid较小者进行选择。

也就是说优先选择slave-priority最小值的slave节点,如果所有slave此配置相同,那么选择数据最完整的slave节点,如果数据也一样,最后选择runid较小的slave节点。

提升新的master

经过优先级选择,选出了备选的master节点后,下一步就是要进行真正的主从切换了。

哨兵领导者给备选的master节点发送slaveof no one命令,让该节点成为master。

之后,哨兵领导者会给故障节点的所有slave发送slaveof $newmaster命令,让这些slave成为新master的从节点,开始从新的master上同步数据。

最后哨兵领导者把故障节点降级为slave,并写入到自己的配置文件中,待这个故障节点恢复后,则自动成为新master节点的slave。

至此,整个故障切换完成。

客户端感知新master

最后,客户端如何拿到最新的master地址呢?

哨兵在故障切换完成之后,会向自身节点的指定pubsub中写入一条信息,客户端可以订阅这个pubsub来感知master的变化通知。我们的客户端也可以通过在哨兵节点主动查询当前最新的master,来拿到最新的master地址。

另外,哨兵还提供了“钩子”机制,我们也可以在哨兵配置文件中配置一些脚本逻辑,在故障切换完成时,触发“钩子”逻辑,通知客户端发生了切换,让客户端重新在哨兵上获取最新的master地址。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值