引言
上期我们聊到redis单点带来的问题和应对理论AKF拆分原则
大环境不好?前同事斩获30K的Offer就是用的这套redis谈资
其实AKF也存在着一些问题,今天我们就来探讨一下使用AKF时沿着X轴扩展问题。
X轴横向扩展隐藏问题
上期我们聊到,在X轴上扩展机器其核心是原机器和新增的机器要保持数据一致,那这里就涉及到数据同步,存在着主从或者主备的情况,定是需要区分主备,主节点向从节点同步数据,那么要保证所有机器,这些机器的组合我们叫做集群,集群这里不展开叙述,集群数据同步需要考虑的问题:
一、主从数据复制
主机与从机都会对外提供查询服务,它们的数据是一致的,所以查询的结果也是一致的,当某一个从机接收到写请求时,所有对数据的写请求都要发送到主机上,主机上收到不用转发,主机将写请求处理修改数据后,主机将修改数据的命令下发给所有的从机。
那么这里主机向从机进行数据同步也会有几种规则,就是这个过程有几种同步模式,我们来逐一看看:
1.主机从机阻塞同步修改
当客户端向redis集群发送修改数据的操作消息,不管是不是主机,最后都交由主机,主机先进行修改,随后阻塞,此时整个集群不对外提供任何服务,直到向所有从机发送完修改数据的指令,并且等待所有从机回复数据修改成功或者修改失败,汇总结果后才给客户端返回。这种方式保证了集群中所有机器的数据的强一致性,但是破坏了集群的可用性,一旦某个从节点发生故障的话,主机得不到从机的响应,会一直阻塞等待,那么客户端永远都不会得到确认消息,这样就无法使用了,这种方式显然不可取。那么在强一致性的要求下会破会可用性,我们就需要考虑取舍问题,我们是需要保证可用性,就需要降低强一致性,进而有了异步非阻塞和消息队列消费两种处理方式。
2.主机从机异步非阻塞修改
当主机执行写指令操作成功后,通过异步通信的方式向所有从机发送写指令,不管从机是否已经更新完成还是更新失败,主机发送完写指令后直接就向操作的客户端返回确认消息。
此种异步非阻塞的方式优点是能给客户端及时响应,增加吞吐量,但是对于集群内部的数据是否全部一致却得不到保障,也就是弱一致性。
3.借助消息队列进行修改
当主机收到一个写操作指令后,自己执行完写操作,不立即返回给客户端而是同步阻塞住,将指令同步到消息中间件,我们要求这个消息间件具备高可用,是一个集群,响应速度非常快等特性,比如kafka,同步给消息中间件后将确认消息返回给调用的客户端。集群中的其他从机订阅了消息队列对应的消息主题,从机就会读取消息队列中的消息,并执行写操作命令,这种方式可以快速的响应客户端,集群中的所有从机也会在未来的某一时刻达到数据的一致性,这个一致性是弱一致性,有可能出现某些客户端返回的数据不是最新的数据,我们将这种情况称之为最终一致性,强调一致性并非强一致性。
redis作者是用的哪种方式实现数据同步的呢,是用的异步非阻塞方式进行数据同步,也是舍弃掉强一致性,提高可用性,大家其实在自己设计程序的时候,就要根据具体情况进行取舍,这个功能是可用性重要还是一致性重要,比如大家所熟知的火车票和银行卡账户的余额操作都是强一致性。
二、故障发现
在机器集群中,及时发现主机出现故障是非常重要的事情,这样就会引申出一个问题:怎么才知道主机出现故障?
最简单也是最愚蠢的办法,咱们可以安排一个人一直监控,不行就2个换班,这样似乎是能解决监控的问题,不过人是不可靠的,有可能没有将职责进行到位或者擅离职守,人还有各种需求,所以可以搞一套程序监控主机,这样做才是合适的解决方法。这一套程序应该是具备高可用的,必然不是一个而是一群,那么这套程序应当是一个集群。集群中所有节点都监控着主机,我们可以用主机广播一个主题,所有监控都在这个主题下收取消息,当监控集群中某个节点发现主机挂了,就会同步给其他节点。其他节点知道后怎么确定监控的主机是否挂了呢,有没有可能其他节点没有监控到主机挂了,更有一种极端的情况比如我们监控集群是4台机器,有2台通报说主机挂了,另外两台没有监控到主机挂了,这个时候要确定主机是否挂了就需要投票,这种投票2:2分不出结果,就会出现脑裂问题。这个时候就需要引入势力范围,只要集群中达成了一致的势力范围,就可以将这个结果进行统一,那么我们要求势力范围一定是有结果的,所以搭建集群时,从机总数总和是奇数,这样不至于会有脑裂的情况发生。达成势力范围的条件是过半通过,也就是n/2+1,n代表从机总和,只有这样才能准确确定被监控主机的状态,如果确定主机挂了就要进行故障恢复。
三、故障恢复
故障恢复本节不做实操,涉及搭建集群和集群相关的知识,这里不展开叙述,只做简单的故障恢复理论讲解。集群中存在主节点和从节点,就会分为主节点挂掉和从节点挂掉,我们恢复的方式又可手动和自动。
1. 主节点挂掉
- 手动方式我们是现将存在的从节点的追随关系改到某个从节点,然后再去排查主机的问题,当主机问题修复后,之前主机在追随新的主机
- 自动方式是由redis哨兵来做的,哨兵会监控集群并且哨兵之间也有通信,主节点挂了就相当于做了和手动恢复的操作,这个操作是由哨兵来完成,原来的主能恢复就加回来,不能恢复就直接踢掉,这时候需要配置一些辅助策略比如邮件通知管理员某某机器挂了,需要检修。
2.从节点挂掉
对于从节点来说,手动的方式就是检查问题然后再重启机器,重新追随主机,自动的方式就是从节点挂了就直接踢掉,如果从节点是因为网络问题暂,可能在某个时刻又能正常通信,这个时候哨兵会将其恢复至集群。
总结
今天我们接着上期展开叙述了AKF拆分的沿着X轴拆分存在的一些问题进行了探讨,并且也引出了一些集群的知识,后面将会对集群进行一次探讨,欢迎持续关注!