最近在做分布式事务的知识分享,在网上查阅了不少资料,也就逐渐对分布式事务有深刻的理解。写这篇文章其目的是为让自己的知识脉络更加清晰,同时也希望能够分享部分自己的见解。
事务
在讲分布式事务之前,首先得清楚事务是做什么的。 事务其实是一个连贯的状态和值的变化。细讲这些变化有什么特点。原子性、一致性、隔离性、持久性,这4个特性其实就是对事务的一个补充说明,当我们将功能的一系列操作定性为一个事务操作时,那必须遵守ACID原则。
那为什么需要遵守这些原则呢?其实事务这个概念是符合现实逻辑的。比如我们在商场下单一件商品,那现实中的逻辑就需要我们付钱才能够得这个商品,商家收到了钱,就将商品通过快递交付给我们。假定这整个流程在一个事务里,那原子性就代表买方扣钱、卖方收益、卖方减库存、买方收到货物,这几个动作必须都成功,否则都不成功即回滚;隔离性指的是当商家在同一时刻收到了两笔订单,订单数量、库存数量该怎么展示给两个事务;持久性,商品一旦卖出,在没有其他事件发生的情况下,金钱交换、商品交换都是永久性的。
那一致性又是什么呢?我上面的例子没有提到一致性。原因就是不管是原子性、隔离性、持久性其实最终都要满足一致性要求的,而一致性就是要保证一个事务在业务上的逻辑正确性,也就是说一个事务从开始到结束,任何的状态转换,都得符合我们人脑想像他应有的样子(如果你想像不出来?看需求文档,问产品经理!)。
事务的4个特性,为我们在代码开发中编写事务时提供了理论指导。用统一的定义简化了我们事务开发过程中的编程模型,是具有工程化的意义的。当然ACID也是对事务的一个细化描述,帮助我们更好的理解和使用事务。
分布式事务
分布式事务的产生不是空穴来风,当前大部分公司都已经使用了分布式系统作为应用架构,由此引发的现象是在一个事务范围内,可能会涉及到多个节点服务,而以数据库代表的本地事务只能在一个节点内生效。那要处理多节点的事务就无法用常规的事务来解决,所以为了解决涉及到多个节点的事务问题(这类问题因为分布式系统而频频发生),就把这类事务划分为分布式事务。
分布式事务的基础理论
很多学者为解决分布式事务问题,提出了很多的理论。CAP理论是现在分布式事务中最为知名的理论。CAP定理是我们在设计分布式事务时绕不开的定理。
一致性(Consistency)。CAP定理中的一致性与事务特性的一致性属于两个概念。事务里的一致性强调的是事务执行要符合业务逻辑是一种指导性质的特性。而CAP定理中的一致性说的是当系统不管因何种情况出现了节点不一致的情况,必须等待到节点信息一致才可返回,这是一种问题出现后的处理方案。
可用性(Availability)。当系统出现了部分节点宕机失联或数据不一致情况下,系统必须在可接受的时间范围内返回信息,即使这个结果是错误的或存在不合理的。
分区容错性(Partition tolerance)。当分布式系统中,某个节点因故障失联后,系统不能因为单个节点的问题导致整个系统处于不可用状态。
可以看到CAP定理实际上是对程序设计的3个原则性的要求,而定理本身要说明的是,系统无法同时满足这3个要求,最多只能同时满足2个。那根据CAP定理的理论基础,我们在程序设计时是不是就可以抛开其中一个原则进行设计呢?其实,实际的业务场景并不能严丝合缝的遵守CAP定理。CAP定理属于学术研究范畴的定理,提出时是没有分析任何外界影响因素的,是非常理想化的。而在实际工程开发过程中,我们经常会受到业务逻辑、环境因素、资源等问题的影响无法遵守CAP定理。由此讲究儒家中庸之道,充满工程设计美学的BASE定理应运而生了。
BASE定理
基本可用(Basically Available)。当系统因不可预知的问题导致出现节点故障时,在保证系统核心业务不受影响的情况下,允许系统进行服务降级,或在可接受的时间范围内进行响应。
软状态(Soft state)。允许系统存在中间状态,即认可系统在处理过程中存在时延的情况。
最终一致(Eventually consistent)。在业务可接受范围内,允许数据在一定时间内处于不一致的状态。但需要在规定期限内达到一致。
可以看到其实BASE定理其实是承认了在分布式系统运行过程,是必然存在某些不可预知的故障的或者说会因为长分布式事务链路产生对系统性能、稳定性、设计难度等的影响,因此在处理事务的过程中加入了额外的考量,进而总结了BASE定理作为处理理论依据。
BASE定理针对工程性质的系统,对CAP定理中的可用性和一致性均做出了让步,但这种让步不是不考虑业务逻辑的无脑让步,是要在业务准许的范围内进行让步,这也是该定理有别于学术性质理论的点。我们要做的不仅仅只是了解定理,更多的是需要灵活运用而不是什么都不考虑,直接套用定理,那写出来的代码依旧不满足系统要求。
总而言之,BASE定理是在CAP的基础上对软件设计的一个更为妥协性质的理论。它需要程序员对业务有更深入的理解并基于业务逻辑设计出能让分布式系统更加鲁棒的程序。
分布式事务的处理方案
分布式事务的处理最基本最常用的就是2PC模式即采用二阶段提交的方案,二阶段提交的设计固然确保了事务可以一并提交,但却延长了单个本地事务的等待时长,无法抵御高并发时刻对性能的要求,其实也是不满足BASE定理的设计理念的。像SEATA这样的分布式事务框架使用的AT、TCC、XA、SAGA事务模型都是类似于2PC的强一致分布式事务。所以我们在工程上期望使用BASE定理,实际还需要伴生使用消息中间件、redis等中间件来达到目的。
以上就是我最近关于分布式事务的一点思考。思考不深,仅做参考。