互联网行业是大势所趋,从招聘工资水平即可看出,那么如何提升自我技能,满足互联网行业技能要求?需要以目标为导向,进行技能提升,本文主要针对高并发分布式系统设计、架构(数据一致性)做了分析,祝各位早日走上属于自己的"成金之路"。
 
目录:
问题分析
概念解读
Most Simple原理解读
eBey、去哪儿、蘑菇街分布式事务案例分析
参考资料

1.问题解析    
要想做架构,必须识别出问题,即是谁的问题,什么问题。
明显的,分布式架构解决的是高并发的问题,高并发下服务高可用和数据一致性问题问题;当规模规模较小时,单库HA即可满足请求,当业务规模持续增加,单库已经无法满足业务需求,业界主流做法,是对业务进行分表、分库,那么原来的有些业务,现在则要在一个事务中,保证两个库同时操作成功或操作不成功(一个库成功,一个库失败,要么重新尝试失败库操作直到成功,要么回滚成功库)。随之而来的问题既是如何保证分库时业务操作的数据一致性。理解高并发分布式架构、分布式系统数据一致性的问题、起源是第一步。

这里多啰嗦一点,分库后,每个库可以采取不同的语言,以时下很流行的微服务向外提供服务;但是业务量不大的情况下,使用微服务到增加了复杂性及技术成本。明白技术的起源,针对不同的业务量,采取适当的架构、以最恰当的方式承载业务,是架构师必须具备的能力。
 
2.常见概念解读:
a.关系型数据库通常具有ACID特性:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。
b.Base(basically available, soft state, eventually consistent):一种 Acid 的替代方案,BASE 的可用性是通过支持局部故障而不是系统全局故障来实现的。化学理论中ACID是酸、Base恰好是碱。
c.CAP定律:在分布式系统中,同时满足"CAP定律"中的"一致性"、"可用性"和"分区容错性"三者是不可能的。
d.强一致:当更新操作完成之后,任何多个后续进程或者线程的访问都会返回最新的更新过的值。这种是对用户最友好的,就是用户上一次写什么,下一次就保证能读到什么。根据 CAP 理论,这种实现需要牺牲可用性,常见的RDBMS。
e.弱一致性:系统并不保证续进程或者线程的访问都会返回最新的更新过的值。系统在数据写入成功之后,不承诺立即可以读到最新写入的值,也不会具体的承诺多久之后可以读到。
f.最终一致性:弱一致性的特定形式。系统保证在没有后续更新的前提下,系统最终返回上一次更新操作的值。在没有故障发生的前提下,不一致窗口的时间主要受通信延迟,系统负载和复制副本的个数影响。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.案例分析
a.eBay经典的BASE模式
一个最常见的场景,如果产生了一笔交易,需要在交易表增加记录,同时还要修改用户表的金额。这两个表属于不同的库及远程服务,所以就涉及到分布式事务一致性的问题。
 
核心思想是用两个事务来保证一致性,同时用异步保证了可用性:一个事务处理主要操作"增加交易表记录"与异步消息构建,另外一个事务用来处理构建的异步消息;第一个事务即处理主要业务又记录次要业务,同时还能快速返回,保证了高可用性,第二个事务则用来保证数据的一致性。(即将buyer和seller表更新的处理转为"线下"处理,消息日志可以存储到本地文本、数据库或消息队列,再通过业务规则自动或人工发起重试。人工重试更多的是应用于支付场景,通过对账系统对事后问题的处理,类似与淘宝双11重复支付后续退款)
 
一个经典的解决方法,将主要修改操作以及更新用户表的"异步消息"放在一个本地事务来完成。同时为了达到多次重试的幂等性,避免重复消费用户表消息带来的问题,增加一个更新记录表 updates_applied 来记录已经处理过的消息。
在第一事务中,通过本地的数据库的事务保障,保证"增加交易表记录"、"增加两条异步消息队列记录(一条处理buyer表、一条处理seller表)",同时成功或同时失败。
在第二事务中,分别读出消息队列(但不删除),通过判断更新记录表 updates_applied 来检测相关消息是否被执行,如没执行,则执行相关业务逻辑(保证幂等性,保证即使执行过程中异常,重复执行没有任何问题),执行完所有消息后然后增加一条操作记录到updates_applied,事务到此结束。用事务保证两个异步消息执行及updates_applied的一致性操作(又称为分布式事务框架)。最后删除队列。
 
b.去哪儿网分布式事务方案
i.优先使用异步方案,原理和"a.eBay经典的BASE模式"类似,对业务逻辑处理不能保证"幂等性"的,增加去重表(即a中的updates_applied) 来处理
ii.对于不适合异步消息处理的业务,如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框架层进行维护,对业务是透明的。
 
c.蘑菇街交易创建过程
场景:将下单功能拆分为12个子业务(见参考资料b),对于非实时、非强一致性的关联业务,使用"eBay经典的BASE模式"思想,第一个本地事务执行成功后,以发消息通知、关联事务异步化执行方案,来避免a中第二个事务的"分布式事务框架"对业务带来的侵入和复杂性,具体方案是基于DB事件变化通知给MQ,而MQ消费者通过ACK,保证消息一定消费成功,完成强一致性(消息可能会被重发,所以消息消费方要保证幂等性)。
 
而对要求同步做、强一致性要求的场景(和b的ii相同场景),如优惠券和优惠券减库存:可以引入"a.eBay经典的BASE模式"的第二个事务(分布式事务框架)来处理,但是复杂性会急剧上升;
另一种方式是创建一个不可见订单,然后在同步调用锁券和扣减库存时,针对调用异常(失败或者超时),发出废单消息到MQ。如果消息发送失败,本地会做时间阶梯式的异步重试;优惠券系统和库存系统收到消息后,会进行判断是否需要做业务回滚,这样就准实时地保证了多个本地事务的最终一致性。
根据业务进行不同的方案处理,解决了高并发分布式架构、分布式系统的数据一致性问题。
 

整体来说,蘑菇街的案例可迁移性强,可移植性好,可以尝试模拟下实际场景,驾驭分布式架构、分布式系统数据一致性方案,祝大家早日走上"成金之路",看到这里,烦请不吝"推荐",谢谢!
 
5.参考资料:

posted @ 2017-03-15 11:30

强势解析eBay BASE模式、去哪儿及蘑菇街分布式架构的更多相关文章

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

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

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

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

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

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

  4. Flink 源码解析 —— Standalone session 模式启动流程

    Standalone session 模式启动流程 https://t.zsxq.com/EemAEIi 博客 1.Flink 从0到1学习 -- Apache Flink 介绍 2.Flink 从0 ...

  5. 137-基于TMS320C6678、FPGA XC5VSX95T的四路Base模式全景影像处理平台

    基于TMS320C6678.FPGA XC5VSX95T的四路Base模式全景影像处理平台 一.板卡概述 本板卡由我公司自主研发,基于CPCI架构,符合CPCI2.0标准,采用两片TI DSP TMS ...

  6. IM 去中心化概念模型与架构设计

    今天打算写写关于 IM 去中心化涉及的架构模型变化和设计思路,去中心化的概念就是说用户的访问不是集中在一个数据中心,这里的去中心是针对数据中心而言的. 站在这个角度而言,实际上并非所有的业务都能做去中 ...

  7. 模型-视图-控制器模式(MVC模式,10种常见体系架构模式之一)

    一.简介: 架构模式是一个通用的.可重用的解决方案,用于在给定上下文中的软件体系结构中经常出现的问题.架构模式与软件设计模式类似,但具有更广泛的范围. 模型-视图-控制器模式,也称为MVC模式.是软件 ...

  8. [HBase Manual]CH5 HBase运行模式:单实例和分布式

    HBase运行模式:单实例和分布式 HBase运行模式:单实例和分布式 1.单实例模式 1.1 单实例在HDFS下 2.分布式 2.1 伪分布式 3完全分布式 HBase有2种运行模式,单实例和分布式 ...

  9. 为啥要去IOE——分布式架构的由来

    1946年2.14日,那是一个浪漫的情人节 , 世界上第一台电子数字计算机在美国宾夕法尼亚大学诞生了,她的名字叫ENIAC.这台计算机占地170平米.重达 30 吨,每秒可以进行 5000 次加法运算 ...

随机推荐

  1. android 增量更新原理

    原理如下:服务器端设计增量表,记录数据操作顺序id,和增删改查信息.在进行数据库表操作的时候同时进行将信息保存在增量表. android客户端在请求的时候上传最后保存的id.服务端判断最后的id,返回 ...

  2. spring boot学习笔记2

    开场知识: spring 容器注入bean,时容器初始化的一些接口以及接口调用的时间先后顺序: 1)BeanFactoryPostProcessor 容器初始化的回调方法 * BeanFactoryP ...

  3. Screen、IP

    主要内容 Screen 安装screen [root@TS-DEV ~]# yum install screen [root@TS-DEV ~]# rpm -qa|grep screen screen ...

  4. .net图表之ECharts随笔01-最简单的使用步骤

    找了几种绘制图表的办法,后面选定了ECharts.下载链接如下,好像不同的ECharts有不同的用法,要下对. https://gitee.com/Tuky/SomeWebFrame/tree/mas ...

  5. UWP FillRowViewPanel

    最近有童鞋有这种需求,说实话我不知道这个Panel怎么起名字. 效果连接https://tuchong.com/tags/风光/ 下面是我做成的效果,可以规定每个Row的Items个数 2个 3个 4 ...

  6. 2019年微服务实践第一课,网易&谐云&蘑菇街&奥思技术大咖深度分享

    微服务的概念最早由Martin Fowler与James Lewis于2014年共同提出,核心思想是围绕业务能力组织服务,各个微服务可被独立部署,服务间是松耦合的关系,以及数据和治理的去中心化管理.微 ...

  7. Android Dagger 2

    Dagger 2 依赖注入 1. 基本概念 最重要有四个概念,也是四个注解(annotation),Provide,Inject,Module,Component. Provide 是提供者,创建实例 ...

  8. Python文件读写及网站显示

    一.关于文件读写的笔记 (一) 文件概述 文件是一个存储在辅助存储器上的数据序列,可以包含任何数据内容 文件都是按照2进制进行存储的,但在表现形式上有2种:文本文件和二进制文件. 1. 文本文件 文本 ...

  9. WINDOWS平台下的栈溢出攻击从0到1(篇幅略长但非常值得一看)

    到1的这个过程.笔者也希望能够通过这些技术分享帮助更多的朋友走入到二进制安全的领域中.2.文章拓扑由于本篇文章的篇幅略长,所以笔者在这里放一个文章的拓扑,让大家能够在开始阅读文章之前对整个文章的体系架 ...

  10. java 路径的问题

    在项目开发中会碰到各种各样的获取项目路径的一些问题: 1:java项目: 以获取  类路径下的mess.properties 为例来说明: 文件在项目中的位置: src/bz/beppe/demo/r ...