互联网行业是大势所趋,从招聘工资水平即可看出,那么如何提升自我技能,满足互联网行业技能要求?需要以目标为导向,进行技能提升。

本文主要针对分布式系统设计、架构(数据一致性)做了分析,祝各位早日走上属于自己的"成金之路"。

目录:

  • 问题分析

  • 概念解读

  • Most Simple原理解读

  • eBey、去哪儿、蘑菇街分布式事务案例分析

  • 参考资料

1.问题解析 

要想做架构,必须识别出问题,即是谁的问题,什么问题。

明显的,分布式架构解决的是高并发的问题。

高并发下服务高可用和数据一致性问题;当规模规模较小时,单库 HA 即可满足请求,当业务规模持续增加,单库已经无法满足业务需求,业界主流做法,是对业务进行分表、分库,那么原来的有些业务,现在则要在一个事务中,保证两个库同时操作成功或操作不成功(一个库成功,一个库失败,要么重新尝试失败库操作直到成功,要么回滚成功库)。

随之而来的问题既是如何保证分库时业务操作的数据一致性。理解分布式架构、分布式系统数据一致性的问题、起源是第一步。

这里多啰嗦一点,分库后,每个库可以采取不同的语言,以时下很流行的微服务向外提供服务;但是业务量不大的情况下,使用微服务到增加了复杂性及技术成本。明白技术的起源,针对不同的业务量,采取适当的架构、以最恰当的方式承载业务,是架构师必须具备的能力。

2.常见概念解读

  1. 关系型数据库通常具有 ACID 特性:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。

  2. Base (basically available, soft state, eventually consistent):一种 Acid 的替代方案,BASE 的可用性是通过支持局部故障而不是系统全局故障来实现的。化学理论中 ACID 是酸、Base 恰好是碱。

  3. CAP 定律:在分布式系统中,同时满足" CAP 定律"中的"一致性"、"可用性"和"分区容错性"三者是不可能的。

  4. 强一致:当更新操作完成之后,任何多个后续进程或者线程的访问都会返回最新的更新过的值。这种是对用户最友好的,就是用户上一次写什么,下一次就保证能读到什么。根据 CAP 理论,这种实现需要牺牲可用性,常见的 RDBMS。

  5. 弱一致性:系统并不保证续进程或者线程的访问都会返回最新的更新过的值。系统在数据写入成功之后,不承诺立即可以读到最新写入的值,也不会具体的承诺多久之后可以读到。

  6. 最终一致性:弱一致性的特定形式。系统保证在没有后续更新的前提下,系统最终返回上一次更新操作的值。在没有故障发生的前提下,不一致窗口的时间主要受通信延迟,系统负载和复制副本的个数影响。DNS 是一个典型的最终一致性系统。

为保证可用性,互联网分布式架构将强一致性需求转换成最终一致性的需求,并通过系统执行幂等性的保证,保证数据的最终一致性。

※幂等性 (Idempotence):分布式架构的基石,即同一个操作无论请求多少次,其结果都相同。

典型的是HTTP,

Methods can also have the property of "idempotence" in that

(aside from error or expiration issues) the side-effects of N > 0

identical requests is the same as for a single request.

每个概念实际所解决的是人遇到的某个特定的问题,发现其背后所代表的问题,是理解分布式架构、分布式系统数据一致性第二步。

3.Most Simple原理解读

假设有一个从账户取钱的远程 API(可以是 HTTP 的,也可以不是),我们暂时用类函数的方式记为:

bool withdraw(account_id, amount)

withdraw 的语义是从 account_id 对应的账户中扣除 amount 数额的钱;如果扣除成功则返回 true,账户余额减少 amount;如果扣除失败则返回 false,账户余额不变。

值得注意的是:和本地环境相比,我们不能轻易假设环境的可靠性。

一种典型的场景是 withdraw 请求已经被服务器端正确处理,但服务器端的返回结果由于网络等原因被掉丢了,导致客户端无法得知处理结果。

如果是在网页上,一些不恰当的设计可能会使用户认为上一次操作失败了,然后刷新页面,这就导致了 withdraw 被调用两次,账户也被多扣了一次钱。如图1所示:

一种更轻量级的解决方案是幂等设计。我们可以通过一些技巧把 withdraw 变成幂等的,比如:

int create_ticket() 
bool idempotent_withdraw(ticket_id, account_id, amount)

create_ticket 的语义是获取一个服务器端生成的唯一的处理号 ticket_id,它将用于标识后续的操作。idempotent_withdraw和withdraw 的区别在于关联了一个 ticket_id,一个 ticket_id 表示的操作至多只会被处理一次,每次调用都将返回第一次调用时的处理结果。这样,idempotent_withdraw 就符合幂等性了,客户端就可以放心地多次调用。

基于幂等性的解决方案中一个完整的取钱流程被分解成了两个步骤:

  1. 调用create_ticket()获取ticket_id;

  2. 调用idempotent_withdraw(ticket_id, account_id, amount)。

虽然 create_ticket 不是幂等的,但在这种设计下,它对系统状态的影响可以忽略,加上 idempotent_withdraw 是幂等的,所以任何一步由于网络等原因失败或超时,客户端都可以重试,直到获得结果。如图所示:

和分布式事务相比,幂等设计的优势在于它的轻量级,容易适应异构环境,以及性能和可用性方面。在某些性能要求比较高的应用,幂等设计往往是唯一的选择。

幂等性是分布式架构、分布式系统数据一致性的底层基本原理,理解这一步,是走上"成金之路"的关键。

4.案例分析

  1. eBay 经典的 BASE 模式

    一个最常见的场景,如果产生了一笔交易,需要在交易表增加记录,同时还要修改用户表的金额。这两个表属于不同的库及远程服务,所以就涉及到分布式事务一致性的问题。

    核心思想是用两个事务来保证一致性,同时用异步保证了可用性:一个事务处理主要操作"增加交易表记录"与异步消息构建,另外一个事务用来处理构建的异步消息;第一个事务即处理主要业务又记录次要业务,同时还能快速返回,保证了高可用性,第二个事务则用来保证数据的一致性。(即将 buyer 和 seller 表更新的处理转为"线下"处理,消息日志可以存储到本地文本、数据库或消息队列,再通过业务规则自动或人工发起重试。人工重试更多的是应用于支付场景,通过对账系统对事后问题的处理,类似与淘宝双11重复支付后续退款)。

    一个经典的解决方法,将主要修改操作以及更新用户表的"异步消息"放在一个本地事务来完成。同时为了达到多次重试的幂等性,避免重复消费用户表消息带来的问题,增加一个更新记录表 updates_applied 来记录已经处理过的消息。

    在第一事务中,通过本地的数据库的事务保障,保证"增加交易表记录"、"增加两条异步消息队列记录(一条处理 buyer 表、一条处理 seller 表)",同时成功或同时失败。

    在第二事务中,分别读出消息队列(但不删除),通过判断更新记录表 updates_applied 来检测相关消息是否被执行,如没执行,则执行相关业务逻辑(保证幂等性,保证即使执行过程中异常,重复执行没有任何问题),执行完所有消息后然后增加一条操作记录到 updates_applied,事务到此结束。用事务保证两个异步消息执行及 updates_applied 的一致性操作(又称为分布式事务框架)。最后删除队列。

  2. 去哪儿网分布式事务方案

    优先使用异步方案,原理和"a.eBay 经典的 BASE 模式"类似,对业务逻辑处理不能保证"幂等性"的,增加去重表(即 a 中的 updates_applied) 来处理

    对于不适合异步消息处理的业务,如 A、B、C 三方需要同步处理才能返回:在 A、B、C 三个库中分别维护一个事务记录表 recorda/recordb/recordc,当 A、B、C 业务事务处理完,将结果存到对应的 recordx 中,由一个中心服务对比查询三方的事物记录表,有如下两种处理方式:

    第一种:A、B成功,C失败了,重试C,知道C成功;

    第二种:C不可能成功时,回滚A、B,如C为扣库存,当库存为0时,则不能成功(不考虑补库存)。

    另,这种 recordx 表由 RPC 框架层进行维护,对业务是透明的。

  3. 蘑菇街交易创建过程

    场景:将下单功能拆分为12个子业务(见参考资料b),对于非实时、非强一致性的关联业务,使用" eBay 经典的 BASE 模式"思想,第一个本地事务执行成功后,以发消息通知、关联事务异步化执行方案,来避免 a 中第二个事务的"分布式事务框架"对业务带来的侵入和复杂性,具体方案是基于DB事件变化通知给 MQ,而 MQ 消费者通过 ACK,保证消息一定消费成功,完成强一致性(消息可能会被重发,所以消息消费方要保证幂等性)。

    而对要求同步做、强一致性要求的场景(和 b 的 ii 相同场景),如优惠券和优惠券减库存:可以引入"a.eBay经典的 BASE 模式"的第二个事务(分布式事务框架)来处理,但是复杂性会急剧上升;

    另一种方式是创建一个不可见订单,然后在同步调用锁券和扣减库存时,针对调用异常(失败或者超时),发出废单消息到 MQ。如果消息发送失败,本地会做时间阶梯式的异步重试;优惠券系统和库存系统收到消息后,会进行判断是否需要做业务回滚,这样就准实时地保证了多个本地事务的最终一致性。

    根据业务进行不同的方案处理,解决了分布式架构、分布式系统的数据一致性问题。

整体来说,蘑菇街的案例可迁移性强,可移植性好,可以尝试模拟下实际场景,驾驭分布式架构、分布式系统数据一致性方案,祝大家早日走上"成金之路"。

5.参考资料


a.幂等性

http://www.cnblogs.com/weidagang2046/archive/2011/06/04/idempotence.html

b.架构案例详细

http://weibo.com/ttarticle/p/show?id=2309403965965003062676

c.http://www.infoq.com/cn/articles/solution-of-distributed-system-transaction-consistenc

作者:成金之路

链接:http://www.cnblogs.com/uttu/p/6553307.html

本文已获得作者成金之路独家授权,转载请标明作者及出处。

内容转载自公众号

51CTO博客
了解更多

赞赏

强势解析 eBay BASE 模式、去哪儿及蘑菇街分布式架构相关推荐

  1. 强势解析eBay BASE模式、去哪儿及蘑菇街分布式架构

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

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

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

  3. 解析eBay BASE模式、去哪儿及蘑菇街分布式架构

    目录: 问题分析 概念解读 Most Simple原理解读 eBey.去哪儿.蘑菇街分布式事务案例分析 参考资料 1.问题解析     要想做架构,必须识别出问题,即是谁的问题,什么问题. 明显的,分 ...

  4. eBay电子商务模式

    eBay (electron bay 电子港湾)背景: eBay 于 1995 年创立于美国,是迄今为止全球最大的网络交易 / 拍卖网站.面对日趋红火的eBay业务,美国媒体叫出 了"让电子 ...

  5. RavenDB建模--ACID模式和BASE模式

    本专题最后一节,我们将学习 RavenDB 中常用的两种模式:ACID和BASE模式.首先我先来简述一下什么是 ACID和BASE. ACID 是数据库事务正确执行的四个基本要素的缩写.指 DBMS ...

  6. 分布式架构原理解析常见问题解决

    大家觉得写还可以,可以点赞.收藏.关注一下吧! 也可以到我的个人博客参观一下,估计近几年都会一直更新!和我做个朋友吧!https://motongxue.cn 分布式架构原理解析常见问题解决 1. 分 ...

  7. IPFS DHT专题:去中心化搜索的架构演进

    前言 去中心化搜索随着P2P分享软件的兴起而来到了聚光灯下. 说起P2P分享软件的发展史,是单个节点能力不断发展的历史,也是探索如何集合节点们的能力成为有机整体的历史,其强大的单个节点能力和相对落后脆 ...

  8. 去哪儿旅行微服务架构实践

    今天我带来的主题是去哪儿旅行微服务架构实践.我将从以下几个方面进行介绍: 背景介绍 微服务架构模式的最佳实践 微服务开发效率的提升实践 微服务治理的实践 ServiceMesh 尝试 一.背景介绍 首 ...

  9. 万字长文解析:分布式架构、SOA、微服务架构、API网关、ESB服务总线架构之间的关联及演进

    1架构演进 架构十五年:改变的是形态,不变的是目的 业务驱动架构形态变化 过去十几年,随着互联网发展以及业务的多样化,系统的架构也在不断发生变化,总体上来说大体经历了从单体应用架构-垂直应用架构-分布 ...

最新文章

  1. Java多线程(九)—— interrupt()和线程终止方式
  2. 面经(一)——5G和物联网的关系
  3. C++ 文件和文件流
  4. VS2012找不到EF框架实体模型的解决方法
  5. C/C++ OpenCV图像的尺寸变化
  6. 7月最新发布10.2.0.4.5 Patch Set Update
  7. 互联网介入对安防行业的影响
  8. shell :将标准输出及标准错误输出写到指定文件
  9. 使用ps 制作gif 动图
  10. WPS中的EXCEL冻结首行问题
  11. en结尾的单词_形容词加en前后缀变动词的英语单词
  12. 为什么好多人说win8不好用?
  13. 基于C++和OpenCV的中心线提取算法
  14. obd协议 混动车_OBD协议
  15. Mac下安装keras
  16. 安卓结构能转换成苹果借口吗_在外面开着手机WiFi有多危险你知道吗?
  17. 追加审批人样式html,更新 | 你的审批打印模板真丑!看别人用html模板怎么玩
  18. android obb在哪,在Android中使用加密的OBB文件
  19. 【计算机毕业设计】70.毕业设计管理系统源码
  20. Shopify和其他电子商务平台上的微数据

热门文章

  1. MySQL-5.5.33主从复制
  2. 关于异或的一些东西和应用
  3. Haproxy 让后端RS记录真实IP
  4. 获取iOS 设备上崩溃日志 (Crash Log)的方法
  5. VS2010 C++下编译调试MongoDB“.NET研究”源码
  6. ASP.NET Core使用编译时依赖关系注入(DI)
  7. 限流中间件IpRateLimitMiddleware的使用
  8. 为什么 Dapper 的批量插入比我预期的要慢很多?
  9. C#基础知识之base、this、new、override、abstract梳理
  10. Csharp实例:武汉智能安检闸机数据接收和解析