在分布式系统的数据一致性问题(一)里面,简单的介绍了分布式数据的同步问题,上面的问题比较抽象,在目前的互联网应用中还很少见,这次在通过一个比较常见的例子,让大家更深入的了解一下分布式系统设计中关于数据一致性的问题
这次我们拿我们经常使用的功能来考虑吧,最近网购比较热门,就以京东为例的,我们来看看京东的一个简单的购物流程
用户在京东上下了一个订单,发现自己在京东的账户里面有余额,然后使用余额支付,支付成功之后,订单状态修改为支付成功,然后通知仓库发货。假设订单系统,支付系统,仓库系统是三个独立的应用,是独立部署的,系统之间通过远程服务调用。
订单的有三个状态:I:初始 P:已支付 W:已出库,订单金额100, 会员帐户余额200
如果整个流程比较顺利,正常情况下,订单的状态会变为I->P->W,会员帐户余额100,订单出库。
但是如果流程不顺利了?考虑以下几种情况
1:订单系统调用支付系统支付订单,支付成功,但是返回给订单系统数据超时,订单还是I(初始状态),但是此时会员帐户余额100,会员肯定会马上找京东骂京东,为啥不给老子发货,我都付钱了
2:订单系统调用支付系统成功,状态也已经更新成功,但是通知仓库发货失败,这个时候订单是P(已支付)状态,此时会员帐户余额是100,但是仓库不会发货。会员也要骂京东。
3:订单系统调用支付系统成功,状态也已经更新成功,然后通知仓库发货,仓库告诉订单系统,没有货了。这个时候数据状态和第二种情况一样。
对于问题一,我们来分析一下解决方案,能想到的解决方案如下
1 假设调用支付系统支付订单的时候先不扣钱,订单状态更新完成之后,在通知支付系统你扣钱
如果采用这种设计方案,那么在同一时刻,这个用户,又支付了另外一笔订单,订单价格200,顺利完成了整个订单支付流程,由于当前订单的状态已经变成了支付成功,但是实际用户已经没有钱支付了,这笔订单的状态就不一致了。即使用户在同一个时刻没有进行另外的订单支付行为,通知支付系统扣钱这个动作也有可能完不成,因为也有可能失败,反而增加了系统的复杂性。
2 订单系统自动发起重试,多重试几次,例如三次,直到扣款成功为止。
这个看起来也是不错的考虑,但是和解决方案一样,解决不了问题,还会带来新的问题,假设订单系统第一次调用支付系统成功,但是没有办法收到应答,订单系统又发起调用,完了,重复支付,一次订单支付了200。
假设支付系统正在发布,你重试多少次都一样,都会失败。这个时候用户在等待,你怎么处理?
3 在第二种方案的基础上,我们先解决订单的重复支付行为,我们需要在支付系统上对订单号进行控制,一笔订单如果已经支付成功,不能在进行支付。返回重复支付标识。那么订单系统根据返回的标识,更新订单状态。
接下来解决重试问题,我们假设应用上重试三次,如果三次都失败,先返回给用户提示支付结果未知。假设这个时候用户重新发起支付,订单系统调用支付系统,发现订单已经支付,那么继续下面的流程。如果会员没有发起支付,系统定时(一分钟一次)去核对订单状态,如果发现已经被支付,则继续后续的流程。
这种方案,用户体验非常差,告诉用户支付结果未知,用户一定会骂你,你丫咋回事情,我明明支付了,你告诉我未知。假设告诉用户支付失败,万一实际是成功的咋办。你告诉用户支付成功,万一支付失败咋办。
4 第三种方案能够解决订单和支付数据的一致性问题,但是用户体验非常差。当然这种情况比较可能是少数,可以牺牲这一部分的用户体验,我们还有没有更好的解决方案,既能照顾用户体验,又能够保证资金的安全性。
我们再回来看看第一种方案,我们先不扣钱,但是有木有办法让这一部分钱不让用户使用,对了,我们先把这一部分钱冻结起来,订单系统先调用支付系统成功的时候,支付系统先不扣钱,而是先把钱冻结起来,不让用户给其他订单支付,然后等订单系统把订单状态更新为支付成功的时候,再通知支付系统,你扣钱吧,这个时候支付系统扣钱,完成后续的操作。
看起来这个方案不错,我们仔细在分析一下流程,这个方案还存在什么问题,假设订单系统在调用支付系统冻结的时候,支付系统冻结成功,但是订单系统超时,这个时候返回给用户,告知用户支付失败,如果用户再次支付这笔订单,那么由于支付系统进行控制,告诉订单系统冻结成功,订单系统更新状态,然后通知支付系统,扣钱吧。如果这个时候通知失败,木有问题,反正钱都已经是冻结的了,用户不能用,我只要定时扫描订单和支付状态,进行扣钱而已。
那么如果变态的用户重新拍下来一笔订单,100块钱,对新的订单进行支付,这个时候由于先前那一笔订单的钱被冻结了,这个时候用户余额剩余100,冻结100,发现可用的余额足够,那就直接在对用户扣钱。这个时候余额剩余0,冻结100。先前那一笔怎么办,一个办法就是定时扫描,发现订单状态是初始的话,就对用户的支付余额进行解冻处理。这个时候用户的余额变成100,订单数据和支付数据又一致了。假设原先用户余额只有100,被冻结了,用户重新下单,支付的时候就失败了啊,的确会发生这一种情况,所以要尽可能的保证在第一次订单结果不明确的情况,尽早解冻用户余额,比如10秒之内。但是不管如何快速,总有数据不一致的时刻,这个是没有办法避免的。
第二种情况和第三种情况如何处理,下次在分析吧。
由于互联网目前越来越强调分布式架构,如果是交易类系统,面临的将会是分布式事务上的挑战。当然目前有很多开源的分布式事务产品,例如java JPA,但是这种解决方案的成本是非常高的,而且实现起来非常复杂,效率也比较低下。对于极端的情况:例如发布,故障的时候都是没有办法保证强一致性的。
相关推荐
这些研究方向可能包括但不限于:分布式系统与云计算技术的结合、跨地理区域多数据中心架构下的数据一致性问题、以及如何在保证一致性的同时提高系统性能等。理解这些方向对推动一致性领域研究的发展具有指导意义。 ...
【标题】:“基于消息队列的分布式系统数据一致性方法研究.pdf” 【摘要】:本文主要探讨了在分布式环境中如何保持数据一致性,通过分析一个实际的容灾系统,研究了数据同步和数据一致性的问题。作者提出了一种利用...
2. **分布式系统的副作用:数据一致性问题** 尽管分布式系统带来了诸多好处,但数据一致性成为业界关注的焦点。在分布式环境中,业务逻辑分散在不同的节点上执行,如果各节点间的数据同步出现问题,会导致数据不...
在分布式系统中,缓存一致性问题是系统性能的关键。由于分布式系统由多个计算节点组成,这些节点可能分布在不同的地理位置,因此系统中的数据拷贝需要保持一致,以确保系统的正常运行。缓存技术的引入可以缓解数据...
为了实现强一致性,通常会采用二阶段提交协议(Two-phase Commit Protocol),这是一种分布式事务处理协议,能够确保在多节点间的数据一致性。该协议分为两个阶段:准备阶段(准备所有参与者是否准备好提交事务)和...
为了便于讨论问题,先简单介绍下数据一致性的基础理论。当更新操作完成之后,任何多个后续进程或者线程的访问都会返回最新的更新过的值。这种是对用户最友好的,就是用户上一次写什么,下一次就保证能读到什么。根据...
针对分布式系统中数据一致性的问题,有几种不同的定义方法来描述系统在何种程度上保证数据的一致性。 - **强一致性(即时一致性)**:如果某个客户端写入了一个新的值,则所有后续对该值的读取操作都将返回这个最新...
分布式系统的设计和实施面对的首要问题之一就是如何保证数据一致性。数据一致性是分布式系统中一个核心问题,它涉及到系统中各个组件在数据更新、事务处理等方面能够保持一致的状态。那么,分布式系统在面临各种业务...
在探讨分布式系统事务一致性解决方案时,我们首先需要理解分布式系统的核心挑战之一就是如何在保证数据一致性的同时,还要维持系统的可用性和分区容错性。根据CAP定律,一个分布式系统不可能同时满足这三个特性。在...
在分布式系统中,保证数据一致性通常分为强一致性和弱一致性两种方式。强一致性要求系统中的任何数据更改都能立即反映在所有副本上,确保并发访问时数据的一致性,但这种要求可能会降低系统的可用性。弱一致性(最终...
在分布式系统中,由于数据分布在多个节点上,数据一致性成为了一个关键挑战。分布式UDDI注册中心通常由多个子注册中心组成,每个子中心存储一部分Web服务的注册信息。这种架构虽然提高了服务的可用性和容错性,但也...
2. **CAP理论**:分布式系统设计的核心原则之一是CAP定理,它指出一个分布式系统不能同时满足一致性、可用性和分区容错性这三个特性。理解和权衡这三者在实际系统设计中的重要性是至关重要的。 3. **Paxos算法**:...
在分布式系统中,由于网络延迟、节点故障和并发操作的存在,保持数据一致性是一项极具挑战性的任务。一致性模型如强一致性、弱一致性或最终一致性,提供了不同的解决方案来平衡可用性和一致性。Paxos算法就是为了...
该平台通过一系列机制确保了在异步消息传递过程中的数据一致性。 首先,系统设计中引入了幂等性原则,即无论同一操作执行多少次,结果始终相同。这样可以避免因为消息重复发送或接收导致的不一致状态。同时,平台...
**CAP 定理** 是理解分布式系统中数据一致性问题的基础。该定理指出,在分布式系统中,一致性(Consistency)、可用性(Availability)和分区容错性(Partition Tolerance)这三个属性不可能同时完全满足。具体来说...
内容概要:文章深入讨论了分布式系统中一致性协议面临的挑战及优化策略,特别是基于动态负载均衡、数据复制与分片,和高效通信的方案。实验结果显示优化策略能在降低延时、增大吞吐量以及提高可扩展性三个方面显著...
Paxos算法是解决分布式系统中数据一致性问题的一种有效协议。Paxos算法通过一系列的通信过程,确保在分布式环境中对数据的一致性达成共识。Paxos算法中的参与者分为提议者(Proposer)、接受者(Acceptor)和学习者...
传统的基于SQL的技术在集中式数据库中可以有效解决数据不一致性,但在分布式环境中,由于网络延迟、数据分区、并发更新等问题,使得数据一致性难以保证。 分布式数据不一致性检测主要依赖于函数条件依赖...