用太极拳讲分布式理论,真舒服! (2)

如下图所示:节点 1 和节点 2 返回给客户端的值分别是 A = 5 和 A = 1,也就是节点 1 和 节点 2 并没有保证数据一致性,而是考虑了节点的可用性。

mark

分区容错性的含义就是节点间出现任意数量的消息丢失或高延迟的时候,系统仍然在继续工作。分布式系统告诉客户端,我的内部不论出现什么样的数据同步问题,我会一直运行。强调的是集群堆分区故障的容错能力。

1.2 CAP 三角

那么这三个指标又有什么关系呢?这个就是我们经常听到的 CAP 理论。C 代表一致性(Consistency),A 代表可用性(Availability)、P 代表分区容错性(Partition Tolerance)。

对于分布式系统,CAP 三个指标只能选择其中两个。

CA:保证一致性和可用性。当分布式系统正常运行时(大部分时候所处的状态),这个时候不需要 P,那么 C 和 A 能够同时保证。只有在发生分区故障时,才需要 P,这个时候就只能在 C 和 A 之间做出选择。典型应用:单机版部署的 MySQL。

CP:保证数据的一致性和分区容错性,比如配置信息,必须保证每个节点存的都是最新的,正确的数据。比如 Raft 的强一致性系统,会导致无法执行读操作和写操作。典型应用:Etcd、Consul、Hbase。

AP:保证分布式系统的可用性和分区容错性。用户访问系统,都能得到相应数据,不会出现响应错误,但是可能会读到旧的数据。典型应用:Cassandra 和 DynamoDB。

二、太极的刚 2.1 ACID 的刚

最开始知道 ACID 是研究 SQL 数据库的时候,原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。

这四个属性是针对事务而言的,而事务就是为单个工作单元而执行的一系列操作。如查询、修改数据、修改数据定义。

事务不仅仅只用在数据库上,还可以用在业务系统中,比如发券后扣减库存,这种业务场景可以定义为一个事务。单机场景我们可以通过加锁、时间序列等机制来保证单个节点上的 ACID 特性,但无法保证节点间操作的 ACID 特性。

那么分布式系统下该如何解决事务问题呢?这也是面试中经常遇到的题。分布式事务协议大家一定听过,比如二阶段提交协议和 TCC 协议,下面我还是用六大派围攻光明顶故事来讲解二阶段协议。

2.2 围攻光明顶

峨眉派想汇集少林派、武当派、昆仑派明天一起进攻光明顶。如果有一方不同意进攻,或者进攻时机不一致,则需要取消整个行动计划。少林派、武当派、昆仑派进攻光明顶这一组行动可以看成是一个分布式事务,要么全部执行、要么全部不执行。如下图所示:

围攻光明顶

那如何帮助灭绝师太解决这个协同问题?我们可以用二阶段提交协议来说明。

2.3 二阶段提交协议

在二阶段提交协议中,灭绝师太先给少林派发送进攻的消息,少林派作为协调者的身份,由少林派联系武当派和昆仑派是进攻还是撤退。

二阶段就是说有两个阶段,1.提交请求阶段(投票阶段),2.提交执行阶段(完成阶段)。

阶段一:提交请求阶段:

第一步:少林派作为协调者分别给武当派和昆仑派发送消息:“明天进攻光明顶,可行?”

第二步:少林派、武当派、昆仑派分别评估明天是否能进攻光明顶,如果能,就预留时间并锁定,不再安排其他的进攻事项。

第三步:少林派得到全部的回复结果,包括少林派自己的评估结果。最后三方的结果都是可行。

如下图所示:

mark

阶段二:提交执行阶段:

第一步:少林派统计自己、昆仑派和武当派的消息,都是可以进攻,所以可以执行分布式事务,进攻光明顶。

第二步:少林派通知昆仑派和武当派进攻光明顶。

第三步:少林派、昆仑派、武当派召集手下弟子,进攻光明顶(执行事务)。

第四步:昆仑派、武当派将是否已发起进攻告诉少林派。

第五步:少林派汇总自己、昆仑派、武当派的进攻结果给灭绝师太。这样灭绝师太看到的就是统一的作战计划。

mark

注意:

可以将灭绝师太当做客户端。少林派、武当派、昆仑派当做分布式系统的三个节点。少林派作为协调者。

将评估是否能进攻光明顶以及预留时间可以理解为需要操作的对象和对象状态,是否已经准备好了,能否提交新的操作。

发送消息、飞鸽传书可以理解为网络消息。

第一个阶段中,每个参与者投票表决事务是放弃还是提交,一旦投票要求提交事务,那么就不允许放弃事务。

第二个阶段中,每个参与者执行最终统一的决定,提交事务或者放弃事务。这个就是 ACID 的原子性。

第一个阶段中,需要预留资源,预留期间,其他人不能操作这个资源。

2.4 二阶段协议带来的问题

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsffwz.html