【微服务】分布式一致性算法-Paxos、Raft、ZAB、Gossip

一致性hash

使用Hash时遇到的问题

在上述hash取模的过程中,我们虽然不需要对所有Redis服务器进行遍历而提升了性能。但是,使用Hash算法缓存时会出现一些问题,Redis服务器变动时,所有缓存的位置都会发生改变。
比如,现在我们的Redis缓存服务器增加到了8台,我们计算的公式从hash(product.png) % 6 = 5变成了hash(product.png) % 8 = ? 结果肯定不是原来的5了。
再者,6台的服务器集群中,当某个主从群出现故障时,无法进行缓存,那我们需要把故障机器移除,所以取模数又会从6变成了5。我们计算的公式也会变化。

由于上面hash算法是使用取模来进行缓存的,为了规避上述情况,Hash一致性算法就诞生了

一致性Hash算法原理

一致性Hash算法也是使用取模的方法,不过,上述的取模方法是对服务器的数量进行取模,而一致性的Hash算法是对2的32方取模。即,一致性Hash算法将整个Hash空间组织成一个虚拟的圆环,Hash函数的值空间为0 ~ 2^32 - 1(一个32位无符号整型),整个哈希环如下:

将数据Key使用相同的函数Hash计算出哈希值,并确定此数据在环上的位置,从此位置沿环顺时针查找,遇到的服务器就是其应该定位到的服务器。

总结:一致性hash通过减少影响范围的方式解决了增减服务器而导致数据散列的问题。从而解决了分布式环境下负载均衡的问题

一致性Hash算法对于节点的增减都只需重定位环空间中的一小部分数据,有很好的容错性和可扩展性。

数据倾斜问题

这时我们发现有大量数据集中在节点A上,而节点B只有少量数据。为了解决数据倾斜问题,一致性Hash算法引入了虚拟节点机制,即对每一个服务器节点计算多个哈希,每个计算结果位置都放置一个此服务节点,称为虚拟节点。

在这里插入图片描述

数据定位算法不变,只需要增加一步:虚拟节点到实际点的映射。
所以加入虚拟节点之后,即使在服务节点很少的情况下,也能做到数据的均匀分布。

Raft

Raft 的数据一致性策略

Raft 协议强依赖 Leader 节点来确保集群数据一致性。即 client 发送过来的数据均先到达 Leader 节点,Leader 接收到数据后,先将数据标记为 uncommitted 状态,随后 Leader 开始向所有 Follower 复制数据并等待响应,在获得集群中大于 N/2 个 Follower 的已成功接收数据完毕的响应后,Leader 将数据的状态标记为 committed,随后向 client 发送数据已接收确认,在向 client 发送出已数据接收后,再向所有 Follower 节点发送通知表明该数据状态为committed。

Consul如何通过Raft协议实现强一致性?

首先,库存服务注册到Leader Server的时候,会采取Raft协议,要求必须让Leader Server把这条注册数据复制给大部分的Follower Server才算成功。这就保证了,如果你认为自己注册成功了,那么必然是多台Consul Server都有这条注册数据了。如果你刚发送给Leader Server他自己就宕机了,那么这次注册会认为失败。此时,Consul Server集群会重新选举一个Leader Server出来,你需要再次重新注册。这样就可以保证你注册成功的数据绝对不会丢,然后别人发现服务的时候一定可以从Leader Server上获取到最新的强一致的注册数据。

CAP理论

CP 和 AP不可能同时满足

P

代表分区容错, 在整个分布式系统中某个节点服务挂掉了,并不影响整个系统的运作和使用,

因为他可以在稍后或者通过切换可用节点立即恢复使用

C:

写操作之后的读操作,必须返回该值。

注册中心集群中: leader的作用, 所有的写操作都依赖于leader来完成,为了保证数据的一致性, leader只有一个

假如: 没有leader,首先加入我们新加入一台数据处理服务,就会向注册中心1进行注册,注册中心1写入数据处理服务的ip

等等基本信息,并且准备同步给其他注册中心节点, 结果这个在还没发生同步的过程中,注册中心1挂掉了,

然后客户端准备调用数据中心写入,这个时候就因为注册中心1挂掉了,就直接切到了注册中心2,但是注册中心2没有

收到数据处理服务的添加请求,所以没有这个服务,这个时候就对客户端显示不可用了.

A:

没有leader,可以很容易的切换到可用的注册中心,对于客户端的调用总是及时反应, 在上述C操作的例子中,

对于向服务注册,获取服务注册的基本信息,比如ip来说,基本不会存在,因为像Eureka来说,我们的服务可以

向所有的注册中心节点发起注册请求, 这样就不会存在注册中心节点服务列表不一致的情况

AP、CP及使用场景

在分布式环境下,为了保证系统可用性,通常都采取了复制的方式,避免一个节点损坏,导致系统不可用。那么就出现了每个节点上的数据出现了很多个副本的情况,而数据从一个节点复制到另外的节点时需要时间和要求网络畅通的,所以,当P发生时,也就是无法向某个节点复制数据时,这时候你有两个选择:

  • 选择可用性 A(Availability),此时,那个失去联系的节点依然可以向系统提供服务,不过它的数据就不能保证是同步的了(失去了C属性)。
  • 选择一致性C(Consistency),为了保证数据库的一致性,我们必须等待失去联系的节点恢复过来,在这个过程中,那个节点是不允许对外提供服务的,这时候系统处于不可用状态(失去了A属性)。

最常见的例子是读写分离,某个节点负责写入数据,然后将数据同步到其它节点,其它节点提供读取的服务,当两个节点出现通信问题时,你就面临着选择A(继续提供服务,但是数据不保证准确),C(用户处于等待状态,一直等到数据同步完成)。

P不存在,就是单机环境了,单机下CA是一定存在。

为什么选择大多数节点?因为分区后,我们要尽可能多的对外提供服务,所以在网络分区时当然要选择大多数节点。
请添加图片描述

nacos

阿里的nacos : 性能最好

他同时支持AP和CP模式,他根据服务注册选择临时和永久来决定走AP模式还是CP模式,

他这里支持CP模式对于我的理解来说,应该是为了配置中心集群,因为nacos可以同时作为注册中心和配置中心,

因为他的配置中心信息是保存在nacos里面的,假如因为nacos其中一台挂掉后,还没有同步配置信息,

就可能发生配置不一致的情况. 配置中心的配置变更是服务端有监听器,配置中心发生配置变化,

然后服务端会监听到配置发生变化,从而做出改变

eureka+spring cloud config:

性能也不差,对于服务数量小于上千台来说,性能没有问题

  • eureka: 可以做注册中心,完全AP,支持注册中心之间的节点复制,同时支持服务端同时注册多个注册中心节点, 所以不存节点信息不一致的情况

  • config: 单独服务,是从git仓库拉取配置信息,然后服务端从config服务里面拉取配置信息缓存到本地仓库

    这里配置的变更比较麻烦,他需要结合bus组件,同时约束了只能用rabbitmq和kafka来进行通知服务端进行配置变更,但是保证了数据的一致性,因为他的配置信息在git仓库上,git仓库只有一个,就会数据一致

阿里nacos异常情况 leader挂了

1.不影响服务之间互相调用

2.不影响服务注册

3.不影响服务正常启动拉取配置文件

4.选举新leader差不多4,5秒钟
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值