一.分布式理论基础
1.CAP理论
CAP定理是分布式系统中的重要理论,在一个分布式系统中最多只能同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance)这三项中的两项,不能同时满足这三项。
- 数据一致性(consistency): 对于客户端的每次读操作,要么读到的是最新的数据,要么读取失败。换句话说,一致性是站在分布式系统的角度,对访问本系统的客户端的一种承诺:要么我给您返回一个错误,要么我给你返回绝对一致的最新数据,不难看出,其强调的是数据正确。
- 服务可用性(availability): 任何客户端的请求在一定时间内都能得到响应数据,不会出现响应错误。换句话说,可用性是站在分布式系统的角度,对访问本系统的客户的另一种承诺:我一定会给您返回数据,不会给你返回错误,但不保证数据最新,强调的是不出错。
- 分区容错性(partition-tolerance): 在网络分区的情况下,当任意数量的消息丢失或延迟到达时,系统仍会继续提供服务,不会挂掉。换句话说,分区容忍性是站在分布式系统的角度,对访问本系统的客户端的再一种承诺:我会一直运行,不管我的内部出现何种数据同步问题,强调的是不挂掉。
概念补充:
- Partition (分区):因为网络故障或其它原因导致分布式系统中的部分节点与其它节点失去连接,形成独立分区
- Tolerance(容错):在集群出现分区时,整个系统也要持续对外提供服务
在网络分区的情况下,由于不同子网络之间的通信需要经过路由器或其他网络设备进行转发,因此可能会出现网络拥塞、延迟、丢包等问题
如果是单体应用则可以同时保证CA,P在单体应用是不存在的。对于分布式架构来说则必须保证P,因为分布式系统节点通过网络连接,一定会出现分区问题,分布式系统必须面对网络分区的可能性,即网络延迟、故障、丢包等问题。在这种情况下,一个分布式系统必须能够在网络分区发生时继续运行,即保证系统的分区容错性。因此,P是分布式系统中必须满足的特性。
如果选择了 CA 而放弃了 P,那么当发生分区现象时,为了保证 C,系统需要禁止写入,当有写入请求时,系统返回error (例如,当前系统不允许写入),这又和A冲突了,因为A要求返回no error和no timeout。因此,分布式系统理论上不可能选择 CA 架构,只能选择 CP 或者 AP 架构
反证:
如果 CAP 三者可同时满足,由于允许 P 的存在,则一定存在节点之间的丢包,如此则不能保证 C
因为允许分区容错,写操作可能在节点1上成功,在节点2 上失败,这时候对于 Client 1(读取节点1)和 Client2(读取节点2),就会读取到不一致的值,出现不一致的情况。如果要保持一致性,写操作必须同时失败,也就是降低系统的可用性。
2.Base理论
cap理论的一种妥协,由于cap只能二取其一,base理论降低了发生分区容错时对可用性和一致性的要求
- 基本可用: 允许可用性降低 ,可能响应延长、可能服务降级(服务降级指的是当某个服务繁忙,不能让客户端的请求一直等待,应该立刻返回给客户端一个备选方案)
- 软状态: 指允许系统中的数据存在中间状态,并认为该中间状态不会影响系统整体可用性。比如说下单后加个支付中的中间状态,可以给支付业务提供一个缓冲的时间,一定时间后再变成支付完成的最终状态
- 最终一致性:节点数据同步可以存在时延,但在一定的期限后必须达成数据的一致,状态变为最终状态
3.数据一致性模型
- 强一致性:当更新操作完成之后,任何多个后续进程的访问都会返回最新的更新过的值,这种是对用户最友好的,就是用户上一次写什么,下一次就保证能读到什么。根据 CAP 理论,这种实现需要牺牲可用性。
- 弱一致性:系统在数据写入成功之后,不承诺立即可以读到最新写入的值,也不会具体的承诺多久之后可以读到。用户读到某一操作对系统数据的更新需要一段时间,我们称这段时间为“不一致性窗口”。
- 最终一致性:最终一致性是弱一致性的特例,强调的是所有的数据副本,在经过一段时间的同步之后,最终都能够达到一个一致的状态。因此,最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的强一致性。到达最终一致性的时间,就是不一致窗口时间,在没有故障发生的前提下,不一致窗口的时间主要受通信延迟,系统负载和复制副本的个数影响。
最终一致性模型根据其提供的不同保证可以划分为更多的模型,包括因果一致性和会话一致性等
1.因果一致性:要求有因果关系的操作顺序得到保证,非因果关系的操作顺序则无所谓
进程A在更新完某个数据项后通知了进程 B,那么进程B之后对该数据项的访问都应该能够获取到进程 A更新后的最新值,并且如果进程 B 要对该数据项进行更新操作的话,务必基于进程A更新后的最新值。
在微博或者微信进行评论的时候,比如你在朋友圈发了一张照片,朋友给你评论了,而你对朋友的评论进行了回复,这条朋友圈的显示中,你的回复必须在朋友之后,这是一个因果关系,而其他没有因果关系的数据,可以允许不一致。
2.会话一致性:将对系统数据的访问过程框定在了一个会话当中,约定了系统能保证在同一个有效的会话中实现“读己之所写"的一致性,就是在你的一次访问中,执行更新操作之后,客户端能够在同一个会话中始终读取到该数据项的最新值。实际开发中有分布式的 Session 一致性问题,可以认为是会话一致性的一个应用。