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

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介:

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

目录:

  • 问题分析
  • 概念解读
  • 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。如果消息发送失败,本地会做时间阶梯式的异步重试;优惠券系统和库存系统收到消息后,会进行判断是否需要做业务回滚,这样就准实时地保证了多个本地事务的最终一致性。

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

分布式架构

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


本文作者:大象会跳舞

来源:51CTO

相关文章
|
5天前
|
存储 缓存 算法
分布式锁服务深度解析:以Apache Flink的Checkpointing机制为例
【10月更文挑战第7天】在分布式系统中,多个进程或节点可能需要同时访问和操作共享资源。为了确保数据的一致性和系统的稳定性,我们需要一种机制来协调这些进程或节点的访问,避免并发冲突和竞态条件。分布式锁服务正是为此而生的一种解决方案。它通过在网络环境中实现锁机制,确保同一时间只有一个进程或节点能够访问和操作共享资源。
23 3
|
11天前
|
分布式计算 Kubernetes Hadoop
大数据-82 Spark 集群模式启动、集群架构、集群管理器 Spark的HelloWorld + Hadoop + HDFS
大数据-82 Spark 集群模式启动、集群架构、集群管理器 Spark的HelloWorld + Hadoop + HDFS
66 6
|
10天前
|
缓存 监控 API
探索微服务架构中的API网关模式
【10月更文挑战第5天】随着微服务架构的兴起,企业纷纷采用这一模式构建复杂应用。在这种架构下,应用被拆分成若干小型、独立的服务,每个服务围绕特定业务功能构建并通过HTTP协议协作。随着服务数量增加,统一管理这些服务间的交互变得至关重要。API网关作为微服务架构的关键组件,承担起路由请求、聚合数据、处理认证与授权等功能。本文通过一个在线零售平台的具体案例,探讨API网关的优势及其实现细节,展示其在简化客户端集成、提升安全性和性能方面的关键作用。
38 2
|
11天前
|
分布式计算 资源调度 Hadoop
大数据-80 Spark 简要概述 系统架构 部署模式 与Hadoop MapReduce对比
大数据-80 Spark 简要概述 系统架构 部署模式 与Hadoop MapReduce对比
37 2
|
2天前
|
存储 固态存储 安全
阿里云服务器X86计算架构解析与X86计算架构云服务器收费价格参考
阿里云服务器架构分为X86计算、Arm计算、高性能计算等多种架构,其中X86计算是用户选择最多的一种架构,本文将深入探讨阿里云X86计算架构的云服务器,包括其技术特性、适用场景、性能优势以及最新价格情况。
|
3天前
|
编解码 弹性计算 应用服务中间件
阿里云服务器Arm计算架构解析:Arm计算架构云服务器租用收费标准价格参考
阿里云服务器架构分为X86计算、Arm计算、高性能计算等多种架构,其中Arm计算架构以其低功耗、高效率的特点受到广泛关注。本文将深入解析阿里云Arm计算架构云服务器的技术特点、适用场景以及包年包月与按量付费的收费标准与最新活动价格情况,以供选择参考。
|
6天前
|
消息中间件 中间件 数据库
NServiceBus:打造企业级服务总线的利器——深度解析这一面向消息中间件如何革新分布式应用开发与提升系统可靠性
【10月更文挑战第9天】NServiceBus 是一个面向消息的中间件,专为构建分布式应用程序设计,特别适用于企业级服务总线(ESB)。它通过消息队列实现服务间的解耦,提高系统的可扩展性和容错性。在 .NET 生态中,NServiceBus 提供了强大的功能,支持多种传输方式如 RabbitMQ 和 Azure Service Bus。通过异步消息传递模式,各组件可以独立运作,即使某部分出现故障也不会影响整体系统。 示例代码展示了如何使用 NServiceBus 发送和接收消息,简化了系统的设计和维护。
19 3
|
7天前
|
Java Spring
Spring底层架构源码解析(三)
Spring底层架构源码解析(三)
|
7天前
|
XML Java 数据格式
Spring底层架构源码解析(二)
Spring底层架构源码解析(二)
|
4天前
|
存储 安全 API
单元化架构,分布式系统的新王!
【10月更文挑战第9天】
44 0
单元化架构,分布式系统的新王!

推荐镜像

更多