hhhh 喜欢的可以点 star
分布式不能同时满足一致性(Consisency),可用性(Available),分区容忍性(Partition Tolerance),最多只能同时满足其中两项。
一致性指的是多个数据副本是否能够保持一致的特性,在一致性的条件下,系统在执行数据更新操作之后能够从一致性状态转移到另一个一致性状态。
对系统的一个数据更新成功之后,如果所有用户都能够读取到最新的值,该系统就被认为具有强一致性。
可用性指分布式系统在面对各种异常时可以提供正常的服务能力,可以用系统可用时间占总时间的比值来衡量,4 个 9 的可用性表示系统 99.99%的时间是可用的。
在可用性的条件下,要求系统提供的服务一直处于可用的状态,对于用户的每一个操作请求总是能够在有限的时间内返回结果。
网络分区指分布式系统中的节点被划分了多个区域,每个区域内部都可以通信,但是区域之间无法通信。
在分区容忍性条件下,分布式系统在遇到任何网络分区故障的时候,仍然需要能对外提供一致性的可用服务,除非整个网络都出现了故障。
在分布式系统中,分区容忍性必不可少,因为需要总是假设网络是不可靠的,因此,CAP 理论实际上是要在一致性和可用性之间做权衡。
可用性跟一致性往往的冲突的,很难使它们同时满足,在多个节点之间进行数据同步时
BASE 是基本可用(Basically Available)、软状态(Soft Satue)和最终一致性(Eventually Consistent)三个短语的缩写。
BASE 理论是对 CAP 中的一致性和可用性权衡的结果,它的核心意思:即使无法做到强一致性,但每个应用都可以根据自身业务特点,采用适当的方式来使系统达到最终一致性。
指分布式系统在出现故障的时候,保证核心可用,允许损失部分可用性。
例如:电商在做促销的时候,为了保证购物系统的稳定性,部分消费者可用会被引导到一个降级的页面。
指允许系统中的数据存在中间状态,并认为该中间状态不会影响系统整体可用性,即允许系统不同节点的数据副本进行同步存在时延。
最终一致性强调是系统中所有的数据副本,在经过一段时间内的同步后,最终能达到一致的状态。
ACID 要求强一致性,通常运用在传统的数据库系统上。而 BASE 要求最终一致,通过牺牲一致性来达到可用性,通常运用在大型分布式系统中。
在实际的分布式场景,不同业务单元和组件对一致性的要求是不同的,因此 ACID 和 BASE 往往会结合在一起。
两阶段提交(two-phase Commit),通过引入协调者(Coordinator)来协调参与者的行为,并最终决定参与者是否真正执行事务。
协调者询问参与者事务是否执行承购,参与者回复事务执行结果。
在该过程,参与者执行了事务,但是还没提交。
如果事务在每个参与者上都执行成功,事务协调者发送通知让参与者提交事务;否则,协调者发送通知让参与者回滚事务。
获得锁的时候想表中插入一条数据,释放锁删除这条记录,通过唯一索引保证记录只插入一次,通过这条记录来判断是否处于锁定状态。
存在问题:
使用 SETNX(set if not exit) 指令插入一个键值对,如果 key 不存在,则插入,返回 true,已经存在返回 false 。
redis> EXISTS job # job 不存在
(integer) 0
redis> SETNX job "programmer" # job 设置成功
(integer) 1
redis> SETNX job "code-farmer" # 尝试覆盖 job,失败
(integer) 0
redis> GET job # 没有被覆盖
"programmer"
原理跟数据库唯一索引类似,保证只存在一个 Key 的键值对。
同时可以通过 EXPIRE 指定过期时间,从而避免锁释放失败问题。
存在问题:
使用多个 redis 实例实现分布式锁,避免发生单点故障问题。
获取锁:
释放锁:
XA 方案,即:两阶段提交,有一个事务管理器的概念,负责协调多个数据库(资源管理器)的事务,事务管理器先问问各个数据库你准备好了吗?如果每个数据库都回复 ok,那么就正式提交事务,在各个数据库上执行操作;如果任何其中一个数据库回答不 ok,那么就回滚事务。
全称为:Try 、Confirm 、Cancel
这种方案使用的人很少,因为事务回滚依赖于自己写的代码进行回滚跟补偿,会造成补偿代码巨大。
阿里的 RocketMQ 就支持消息事务: