关于旅游电商: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)。咱们来看一下它的部署形式: ...