分布式一致性问题
1. 什么是共识算法,为什么需要?
在分布式系统中,不同节点之间可能存在网络延迟、故障等原因导致彼此之间存在数据不一致的情况,为了保证分布式系统中的数据一致性,因此需要引入共识算法。
共识算法是指在分布式系统中,多个节点通过一系列协议达成一致的过程。这个过程确保不同节点之间的数据状态达成一致,从而保证系统的正确性和可靠性。
在共识算法中,节点通过相互通信来传递数据,并根据一定的规则进行数据处理和验证。一旦多个节点达成一致,系统就会根据达成的共识状态来执行相应的操作。
著名的共识算法包括Paxos算法、Raft算法、拜占庭容错算法等。这些算法都在分布式系统中得到了广泛的应用,是保证分布式系统正确性和可靠性的重要手段之一。
2. 为什么一个分布式系统要引入raft算法?
raft算法是代替Paxos算法,提高一种更加易用高效的共识机制,其中也有诸多类似的开源实现,其实底层原理也是类似于raft算法。比如zk采用的zab算法。
3. raft算法是强一致性吗?
raft算法是数据强一致性算法,但是raft是有主节点和从节点,并且节点数量需要保持一个奇数,因为它采用了半数服从机制,也就是,写操作只能在主节点执行,主节点执行了写操作,会生成一条未提交的日志,会通过心跳机制将日志发送给对应的从节点,如果获得了半数同意,则将该日志进行提交。
这样就会存在一些节点数据暂时不是最新的。
4. raft写数据的时候不是多数同意即可吗?那也是强一致性吗?
写数据情况
raft算法会存在leader和follower ,写数据如果首先请求到的是follower则会将请求同步给到leader,leader进行写数据
,写好数据之后,会在log enters进行存储,该log的状态为uncommitted,这个时候会进行log replication,会将对应log推送给
每一个follower,只有收到半数则表示该数据已存储,从而返回结果true给到客户端。
读数据情况
一般实现的话:那么客户端进行读数据的时候,follower也会将数据请求给到leader节点,leader节点进行返回数据。
有些cp集群实现的话,是可以任意机器处理读请求的,也就是说写数据的时候只是同步了一半的节点,那么有些节点暂时还没有被同步,
那么刚刚好就是读取了旧数据。比如zookeeper就是这样实现的。zookeeper在处理读请求的话,是follower也可以参与读请求,尽管当时follower的数据可能不是最新的,其他节点的数据都是更新了。
5. 如上说的zooKeeper读数据会存在旧数据情况会有问题吗?
其实问题不大,如果我们更新配置时,可能会有一段时间等待配置全部生效的啊,即使当时读的数据是旧的,可能我们刷新下下次就是新的数据了。那我们会不会一直读那个节点一直都是旧数据?这个不存在的,因为follower节点会和leader节点进行通信的,如果仅仅是因为网络波动,那么leader在下一次心跳中也会将最新的配置给到follower节点,那么follower节点肯定也会立马同步,如果follower节点一直没有被同步,说明leader节点访问不到follower,那么客户端也访问不到
该follower节点啊,那么就会换一个节点进行访问啊,如果客户端能访问到该follower节点,那么就说明leader节点也能访问到follower节点啊。
6. zookeeper是cp还是ap
cp,因为采用zab协议,保证数据的强一致性,可能读的时候会存在读取旧数据的情况(很小的概论,即使出现了也无伤大雅,如果不行的话,则可以使用sync方法,要求读数据把请求给到leader节点)
7. 什么时候分布式系统不需要强一致性算法
没有数据共享
如果数据存储的是在同一个数据源上,那么就不需要分布式系统,早期的nacos在改造的时候,配置模块就只有mysql数据存储,那么要想去除mysql存储,那么数据就会存在多个机器的内存或者文件上,那么就会涉及到数据同步的问题,就需要一致性算法来保证。
数据需要高可用
注册中心中的配置强调数据要强一致性,而注册与发现的话需要强调高可用性。
因此针对高可用的不能采取强一致性算法,可以通过gossip算法进行数据同步,保证数据最终一致性。