为什么80%的码农都做不了架构师?>>>   

在分布式系统的数据一致性问题(一)里面,简单的介绍了分布式数据的同步问题,上面的问题比较抽象,在目前的互联网应用中还很少见,这次在通过一个比较常见的例子,让大家更深入的了解一下分布式系统设计中关于数据一致性的问题

这次我们拿我们经常使用的功能来考虑吧,最近网购比较热门,就以京东为例的,我们来看看京东的一个简单的购物流程

用户在京东上下了一个订单,发现自己在京东的账户里面有余额,然后使用余额支付,支付成功之后,订单状态修改为支付成功,然后通知仓库发货。假设订单系统,支付系统,仓库系统是三个独立的应用,是独立部署的,系统之间通过远程服务调用。

订单的有三个状态: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,但是这种解决方案的成本是非常高的,而且实现起来非常复杂,效率也比较低下。对于极端的情况:例如发布,故障的时候都是没有办法保证强一致性的。

转载自:http://www.cnblogs.com/aigongsi/archive/2012/09/22/2698055.html

转载于:https://my.oschina.net/004/blog/92823

关于分布式系统的数据一致性问题(二)相关推荐

  1. 关于分布式系统的数据一致性问题(三)

    在我的博文里面 关于分布式系统的数据一致性问题(二) 里面主要介绍了数据分布的情况下保证一致性的情况,在第二篇文章里面,我这里提出了三个问题 订单系统调用支付系统支付订单,支付成功,但是返回给订单系统 ...

  2. 关于分布式系统的数据一致性问题(一)

    最近写了一个关于 铁道部购票系统的若干文章 铁道部新客票系统的设计(一) 铁道部新客票系统的设计(二) 铁道部新客票系统的设计(三) 正好遇到一个博友,咨询了一个问题,这个问题正好可以作为分布式系统的 ...

  3. 不懂这些高并发分布式架构、分布式系统的数据一致性解决方案,你如何能找到高新互联网工作呢?强势解析eBay BASE模式、去哪儿及蘑菇街分布式架构...

    互联网行业是大势所趋,从招聘工资水平即可看出,那么如何提升自我技能,满足互联网行业技能要求?需要以目标为导向,进行技能提升,本文主要针对高并发分布式系统设计.架构(数据一致性)做了分析,祝各位早日走上 ...

  4. 结合现有分布式系统的数据一致性思考

    背景 我们项目本身分成了多套系统,但数据上有要求一致性的地方(比如订单状态,通俗点讲就是系统A更新了订单状态为状态一,那么系统B也需要把相同订单的订单状态更新成状态一,这样可以让我们不管是读系统A还是 ...

  5. Google分布式系统三大论文(二)Bigtable: A Distributed Storage System for Structured Data

    原文地址:https://blog.csdn.net/u010359965/article/details/49795133 摘要 Bigtable是一个管理结构化数据的分布式存储系统,它被设计用来处 ...

  6. 分布式系统的容错性(二)——检错和纠错

    本系列内容是我学习分布式系统容错性的一些笔记,欢迎就相关内容进行讨论. 我的联系方式:DLite@163.com 2007-11-26 ================================ ...

  7. 分布式系统知识学习(二)共识算法

    分布式系统知识体系庞大而精妙,不花费大量的时间无法掌握.本文根据一些前人经验和自己摸索总结,由浅入深.由基础概念到实际运用,给出了一条学习曲线相对平滑的分布式学习攻略,希望和大家多多交流,共同进步.本 ...

  8. 车神(车江毅)的分布式事务资料链接汇总

    <!DOCTYPE NETSCAPE-Bookmark-file-1> <META HTTP-EQUIV="Content-Type" CONTENT=" ...

  9. 分布式系统数据一致性解决方案

    2019独角兽企业重金招聘Python工程师标准>>> 1.微服务架构的数据一致性问题 以电商平台为例,当用户下单并支付后,系统需要修改订单的状态并且增加用户积分.由于系统采用的是微 ...

  10. 美团二面:如果每天有百亿流量,你如何保证数据一致性?

    V-xin:ruyuanhadeng获得600+页原创精品文章汇总PDF 目录 前情提示 什么是数据一致性? 一个数据计算链路的梳理 数据计算链路的bug 电商库存数据的不一致问题 大型系统的数据不一 ...

最新文章

  1. python编程入门指南磁力下载-使用python 将bt转磁力链接
  2. 转载: Tortoise SVN使用方法,简易图解
  3. shell脚本编程for循环求阶乘_shell脚本编程(完结版).pdf
  4. CSS设置背景透明字体不透明
  5. 每个做DBA的孩纸都是上辈子被drop的db
  6. java面向对象特性_java面向对象编程三大特性
  7. arcgis python 教程-ArcGIS Python 入门到精通,视频教程下载
  8. 如何在 Mac 上安排电子邮件?
  9. Atitit Spring事务配置不起作用可能出现的问题: .是否是数据库引擎设置不对造成的【笔者就遇到了这个问题,由于笔者使用的是mysql数据,但是在创建表的时候引擎默认(mysql中引擎默认为
  10. 你所不知道的 AI 进展
  11. 高等数学下册——引力
  12. 【hashcat help中文注释】
  13. 参考文献的序号怎么对齐_word参考文献怎么对齐
  14. 吉林大学邮箱smtp服务器,吉林大学邮件系统成功案例-彩讯Richmail邮件系统,致力于互联网行业软件的开发和应用12年....
  15. bh1750采集流程图_基于BH1750的光照度检测)教程.doc
  16. [Unity]摘录笔记UnityShader(重写SurfaceShader)
  17. advisor 2002在matlab2014a上的安装
  18. 在PPT上使用开发工具的不同控件实现单选操作
  19. 微信公众平台在高校教育工作中的使用
  20. “链上政务”三管齐下,效率、监管、企业服务成关键词

热门文章

  1. js点击事件onclick_关于JavaScript的事件绑定问题
  2. centos7如何安装samba-client_Docker: 教程07 - ( 如何对 Docker 进行降级和升级)
  3. 力扣-1736 替换隐藏数字得到的最晚时间
  4. HarmonyOS 编译系统源码
  5. Eclipse 中侧边栏、控制台、Server打不开怎么办?
  6. CF#213DIV2:B The Fibonacci Segment
  7. System Center Operations Manager 简介 [SCOM中文系列之一]
  8. 关于事业发展,雷林鹏教你如何找到方向?
  9. 安装redis3.0.5
  10. 使用HTML Help Workshop将HTML转为CHM