乐趣区

关于旅游电商:51特辑-为什么显示有票你却抢不到技术揭秘12306如何保证车票不超卖

摘要:每逢节假日,当全国几百万小伙伴同时查票、订票时,12306 是如何保障余票显示准、车票不超卖的?为你揭开背地的关键技术:数据强一致性。

本文分享自华为云社区《5.1 特辑 | 为什么显示有票你却抢不到?技术揭秘 12306 如何保障车票不超卖》,原文作者:技术火炬手。

眼瞅着五一小长假就要来了,小云还在为没有抢到高铁票心急如焚。

她再次关上 APP,一遍遍刷新,发现还有余票 2 张,连忙下单,一顿操作猛如虎,后果还是没抢到。

但认真想想也能了解:从勾选乘车人到正式下单,整个流程至多须要 10 秒,如果“见者有份”,恐怕这两个座位大家要挤挤共用了。

那么,每逢节假日,当全国几百万小伙伴同时查票、订票时,12306 是如何保障余票显示准、车票不超卖的?

于是,按捺不住好奇心的咱们,进行了一番深入研究。原来问题背地暗藏着一个分布式数据库畛域极其要害的技术——数据强一致性保障。

1. 什么是强统一?

在介绍概念之前,咱们无妨先来模仿一场球赛直播。

假如笔者做了一款 APP,后盾应用上图的主从数据库。比分写入主节点,从节点分担用户查问。较量中,Alice 惊呼较量完结,Bob 闻声刷新 APP,却显示较量仍在持续!Bob 体验到了显著的数据不统一,于是默默给 APP 打了个差评……

那么,产生不统一的起因到底是什么?

异步复制时,主节点不期待从节点写入就间接返回了。因为网络提早等起因,从节点无奈保障更新工夫。Alice 和 Bob 明明在同时同地查问同一零碎,失去正确后果却有先有后。其实这就是典型的弱一致性。

实际上,为解决单点故障、加强吞吐性能,分布式数据库外部都会对同一份数据进行复制,把冗余正本扩散保留到不同节点上。简略的异步复制只能构建出弱统一零碎,很难满足业务要求。

那么,到底什么样的一致性才靠谱?有哪些类别?上面咱们就来意识这个神秘家族!

1.1 强一致性 / 线性一致性(Linearizability)


强一致性 / 线性一致性是一致性的最高规范,实现难度最高。外围要求是:一旦写操作实现,随后任意客户端的查问都必须返回这一新值。以下图为例,一旦“写入 b”实现,必须保障读到 b。而写入过程中,认为值的跳变可能产生在某一瞬间,因而读到 a 或 b 都是可能的。

从业务角度来说,强一致性带来的体验几乎能够用丝滑来形容!因为它外部的数据“好像”只有一份,即便并发拜访不同节点,每个操作也都能原子有序。正因如此,强统一数据库在业务架构中往往被用在要害地位。

etcd 是强统一俱乐部里的元老。它基于 Raft 共识算法,真正实现了强统一,也因而在 Leader 选举、服务发现等场景起到重要作用。GaussDB(for Redis)作为一款分布式云数据库,凭借多年潜心打磨,也是强统一的代言人。

1.2 程序一致性(Sequential Consistency)


程序一致性弱于线性统一,不保障操作的全局时序,但保障每个客户端操作能按程序被执行。下图中,A 先写 x =10,后写 x =20;B 先写 x =99,后写 x =999。当 C 读取时,程序一致性保障了 10 先于 20 被读到、99 先于 999 被读到。

Zookeeper 基于 ZAB 协定,所有写操作都经由主节点协调,实现了程序一致性。

1.3 因果一致性(Causal Consistency)


进一步放宽要求,因果一致性只对并发拜访中具备因果关系的操作保序。例如:

A 写入 3,B 读到后乘以 100 再更新它。在这个场景下,因为“A 写入 3”与“B 写入 300”有着明确因果关系,因果一致性保障 300 晚于 3 被读到。

因果一致性多用于各种博客的评论零碎、社交软件等。毕竟,咱们回复某条评论的内容,不应早于评论自身被显示进去。

1.4 最终一致性(Eventual Consistency)


它指的是进行写入并期待一段时间,最终所有客户端都能读到雷同的新数据,但具体时限不作保障。许多分布式数据库都满足最终一致性,如 MySQL 主从集群等。

然而,这其实是一个十分弱的保障。因为不确定零碎外部过多久能力收敛统一,在此之前,用户随时可能体验到数据不统一。因而最终一致性有人造的局限性,常常会给业务逻辑带来凌乱。

1.5 弱一致性(Weak Consistency)


说弱一致性最为“厚脸皮”也不为过,因为它连数据写入后未来被读到都不能保障。弱一致性实现技术门槛低,利用场景也不多。严格来说,单纯的开源 Redis 主从集群就属于这一类别。

OK,一致性家族的各位成员曾经跟大家打过照面。显然,一致性越强的数据库系统,可能撑持的业务场景越多。有的业务同学小声说,强统一技术再牛,可我业务简略,不必也没关系吧。实际上恰恰相反:

强统一不仅仅是技术问题,它更是一个不可漠视的业务需要、运维需要!

接下来咱们就先来聊一聊:业务上那些只有强统一能力搞定的事儿!

2 强统一是业务刚需

2.1 计数器 / 限流器

计数服务是典型的强统一利用场景。电商在秒杀流动中,往往会搭建 Redis 主从集群给上层 MySQL 做缓存。因为要抗住超大流量,须要 Redis 的计数器性能做限流。简略讲,咱们初始化 counter=5000。随后每次业务拜访都执行 DECR 命令,当 counter 归零就阻塞后续申请。此外,每隔一个时间段重置 counter=5000,通过这样的伎俩来实现“细水长流”。

然而,完满的假如还不够!

开源 Redis 采纳异步复制,如遇网络不畅,常常产生主节点复制 buffer 沉积。这将导致从节点 counter 偏大很多。此时,一旦主节点宕机,切换到从节点继续执行 DECR 命令,压力很容易超出阈值,全副落到上层软弱的 MySQL,随时可能引起零碎雪崩!

因而,在限流场景下,只有真正的强统一能力提供牢靠的计数器。

2.2 Leader 选举

当业务部署的节点较多、可用性要求高时,往往要用到 Leader 选举。etcd 作为强统一 KV 存储,能完满 cover 这一场景。etcd 依赖两大性能实现 Leader 选举:

(1)TTL:给 key 设置有效期,到期后 key 主动删除。

(2)CAS:对 key 的原子操作(这一性能只有强统一数据库能力实现),应用 etcd 搭建 Leader 选举服务的设计如下:

1)约定 key,用于选举时抢占。其 value 用于保留 Leader 节点名称。

2)约定 TTL,用于给 key 设定有效期。

3)启动时:每个参加节点尝试 cas create key& 设置 TTL。在 etcd 集群强统一 CAS 机制保障下,只有一个节点能执行胜利。该节点成为 Leader 并将名称写入 value;其余节点成为 Follower。

4)运行中:每个节点定期 TTL/ 2 尝试 get key,将 value 与本身名称比照:

如雷同,阐明已是 Leader,尔后只需每隔 TTL/ 2 刷新 key 的 TTL 即可。

如不同,阐明是 Follower,接下来要每隔 TTL/ 2 执行 cas create key& 设置 TTL。

5)当 Leader 节点异样退出,无奈刷新 TTL,key 会很快过期。此时,其余 Follow 之中便会有新的 Leader 产生。

从原理上能看出,强统一能力是 Leader 选举的根基。相似的“刚需”业务场景还有很多,强统一不可或缺。

好了,业务上的事儿就聊到这里,接下来让咱们听听运维怎么说。

3. 强统一为运维减负

3.1 辅助组件架构简单、问题难定位

后盾架构中,MySQL 主从热备也是常见的部署形式。因为数据保留在本地磁盘中,当主库产生重大故障,仅仅依附 MySQL 本身同步机制,主从切换后无奈保障所提供数据与之前状态完全一致。于是呈现了“重量级”的辅助组件——MHA(Master High Availability)。咱们来看一下它的部署形式:

MHA 负责在故障转移过程中,帮忙从库尽量追平主库最新状态,提供近似统一的数据。但这一能力须要额定的 Manager 节点,同时还要在每一个 MySQL 节点上部署 Node 服务。故障切换时,Manager 先为从库补充落后的数据,再通过切换 VIP 复原用户拜访,过程可能长达数十秒。

这样的 HA 零碎部署和前期保护都很简单。如未能顺利执行故障切换或产生数据失落,运维面临的局面都将很辣手。其实运维同学何尝不心愿手中的零碎稳固运行呢?要是数据库本身能提供强统一保障,何苦再依赖简单的辅助组件!

读到这里,对强统一的认识,置信各位读者心里曾经有了本人的一杆秤。让咱们再一次划重点:

强统一不仅仅是技术问题,它更是一个不可漠视的业务需要、运维需要!

从产品选型角度登程,开源 Redis 提供的一致性保障很弱。而 etcd 虽有强统一能力,但它单点写入性能有余,也未能提供 hash、sorted set、stream 等迷人的数据结构……

此时,有人会陷入纠结,到底抉择哪一种,GaussDB(for Redis)应声而起——我,都能够。

4. GaussDB(for Redis)与强统一

自设计之初,GaussDB(for Redis)(后文简称高斯 Redis)给本人的定位就是“强统一 KV 数据库”,因而彻底摒弃了开源 Redis 的异步复制机制。借助华为云 GaussDB 系列先进的“存算拆散”架构,将全量数据下沉到强统一存储层(DFV Pool),从核心技术上超过了传统开源产品的极限。

让咱们来一起认识一下 高斯 Redis的强悍:

用户购买的实例作为一个整体,提供强统一 KV 存储。

用户业务对立通过 Proxy 集群接入高斯 Redis,不必思考外部简单逻辑。多点并发拜访实例,读写操作满足强一致性,再也不用放心开源 Redis 异步复制的不统一隐患。

计算层智能解决数据分片、动静故障转移,将数据全量下沉到共享存储池。

cfgsvr 集群对立治理 ShardServer 节点,主动对海量数据进行分片。并可能在故障场景实现秒级接管,严格避免任何两头态下的数据不统一。

存储层通过 RDMA 高速网络实现高性能分布式数据长久化,三正本冗余保障强统一、零失落。

DFV Pool 是强统一、高性能的分布式存储系统。这是华为外部自研的公司级 Data Lake,它可能稳固撑持各类全栈数据服务。高斯 Redis 冲破了开源 Redis“小格局”的内存架构,将数据全量下沉,基于 DFV Pool 弱小的一致性保障能力,给用户业务带来更广大的拓展空间。

5. 结语

试想,当处在要害地位的数据库“不给力”,业务层就要忙于为零碎增加简单、易出错的一致性保障逻辑。与此同时,运维还要时刻放心故障引发的数据落后问题…这样的零碎真的“香”吗?

试想如果 12306 显示你抢到票了,上车的时候却发现有四五个人和你是同一个座位,太诡异了。

所以,业余的事件交给业余的团队来做。GaussDB(for Redis)自研发初期就继续关注数据强一致性设计,借助强统一存储池 DFV Pool,它能够提供真正强统一的海量 KV 存储解决方案。

点击关注,第一工夫理解华为云陈腐技术~

退出移动版