【AICon】AI 基础设施、LLM运维、大模型训练与推理,一场会议,全方位涵盖! >>> 了解详情
写点什么

大麦库存的高性能及一致性是如何设计的?

  • 2020-03-07
  • 本文字数:2925 字

    阅读完需:约 10 分钟

大麦库存的高性能及一致性是如何设计的?

一、背景

大麦网作为现场娱乐票务平台,其业务覆盖了各大顶级演唱会和大型赛事等高流量项目。票务行业库存系统不同于普通电商库存系统,瞬压过高的秒杀抢票,多场景、多阶段的售卖,对一致性和稳定性提出更高要求。本文将为读者介绍现场娱乐行业票务库存高性能和一致性难点解决和沉淀下来的库存稳定性建设经验。

二、库存场景分类

在售卖中支持多渠道:主办方售卖、大麦网售卖、其他分销渠道售卖等。来满足不同场景下的票源管理。大麦网库存可以分为无座库存、选座库存、预售数字库存和现票库存。


1)无座库存:比如音乐节、游展类项目,观众持票入场,无需安排座位;


2)选座购买:用户可以自己通过座位图选择座位,下单购买;



(图:大麦网选座购买)


3)预售数字库存:预售阶段用户先按照票档价位购买,然后系统按购买顺序进行自动配座;



(图:大麦网预售数字库存购买)


4)现票库存:如非大麦网票务系统生产的,由大麦网从主办方提取现票在大麦网售卖。


  1. 库存核心技术点


目标:高性能、强一致性


库存的高性能和一致性主要从以下几个方面保障:


1)进行事务拆分,执行粒度最小化,优化提高性能;


2)基于正向流水防止重复扣减;


3)基于逆向流水防止重复回滚。


  1. 扣减预校验:防击穿缓存设计


如果所有的库存扣减拦截都放到最后一步扣减库存来做,无疑会对数据库造成巨大的冲击。毕竟库存有限,总有一部分请求是无法购买成功的,这一部分请求流量应该在库存实际扣减之前拦截下来。


预校验阶段即“高并发读”链路时,进行一些不影响性能的检查操作,比如请求的合法性校验、票品是否可售、可售数量是否足够、渠道是否授权等。在这个阶段,系统采用分布式缓存来抵抗高并发读。


传统意义的缓存比如 Memcached,一个比较头疼的问题是缓存击穿。为了保护 DB,我们对传统缓存做了一层封装,即在传统缓存写入时增加当前毫秒级时间戳属性,读取缓存后与当前时间戳比较其差值判定其是否逻辑过期,如果逻辑过期则在竞争分布式锁后读取 DB 数据并反哺缓存。



(图:防击穿缓存流程图)


  1. 库存扣减的一致性保障


库存扣减要同时扣减票品库存和渠道库存,所以扣减阶段势必要进行拆解执行,拆解成最小粒度执行是为了命中数据库热点补丁,达到快速执行的目的。但拆解后面临的问题是如果一个扣减动作执行失败,如何回滚已经执行的动作。基于分库分表的限制,以上两个扣减动作显然无法使用数据层的事务做保证。本库存系统选用的是“职责链模式”进行库存扣减步骤的定制化。


我们把“票品库存扣减”、“渠道库存扣减”作为职责链中的两个独立 Action,任何一个 Action 发生异常则向上抛出,在上层处理异常并回滚已经执行过的 Action。确保“票品库存”“渠道库存”的扣减共进退,理论上达到数据一致性的事务保障。


在动态组合职责时,两个 Action 的执行顺序相当关键。在扣减顺序上,首先扣减票品库存,因为票品库存的共享性,在多渠道同时扣减的情况下,票品库存一般先于渠道库存售罄。所以首先扣减票品库存相较于首先扣减渠道库存可以减少很多回滚情况的发生。



(图:库存扣减顺序)


  1. 库存回滚的一致性保障


在回滚职责链中,动态组合职责时,同样讲究执行的先后顺序,与正向扣减刚好相反,首先回滚渠道库存,然后回滚票品库存。这样在渠道库存已经回滚的情况下如果回滚票品库存发生异常,结合上述的扣减顺序,票品库存的超卖扣减几率将大大降低。



(图:库存回滚顺序)


  1. 异常场景的实时对账


交易系统与库存系统之间的对账可以让双方系统互通有无。如果交易系统在扣减库存时发生读取超时,库存系统实际已经完成库存扣减,但交易系统并未成功落单。则库存系统在实际扣减成功后会发起对账消息,此时交易系统对账结果显示交易系统并未落单,立即主动发起库存回滚请求,撤销刚才的事实扣减。



(图:系统对账交互图)


  1. 数据库层面的极限优化


库存扣减会在同一条票品库存或者渠道库存记录上“高并发写”。此阶段会直接面对数据库的一条记录进行高频次的写操作,业界普遍采用的方案是应用层排队或者行级乐观锁保障对同一条记录进行操作的并发。考虑到应用层排队有损性能,库存系统采用了较为理想的数据层排队,主要基于阿里的数据库团队开发的针对 InnoDB 层上的补丁程序(patch),可以基于 DB 层对单行记录做并发排队,从而实现秒杀场景下的定制优化。


  1. 高并发场景下日志优化


业务日志对于发现业务问题极为有效,也有助于测试阶段的问题定位。上线后有详细的全链路日志协助问题排查。为了避免引入的外部 jar 输出不必要的日志,所以上线后的系统业务日志级别调整为 ERROR 级别。另外,为了防止大抢期间日志落地造成 IO 竞争导致性能下降,库存系统裁剪了大量的无效日志输出,并且采用 Logback 的 LoggingEventAsyncDisruptorAppender 异步写日志,防止写日志阻塞(极端情况下有抛弃日志的可能)引起的系统性能下降。

三、库存稳定性

稳定性目标:2 分钟内发现(业务监控 100%覆盖),5 分钟内定位,15 分钟内止血。



(图:库存稳定性建设包含内容)


  1. 链路梳理及优化


库存红线:是库存系统的生命线,其规则如下图:



(图:库存核心红线规则)


强弱依赖:对库存的核心链路进行强弱依赖梳理,保证核心链路只依赖 DB,其他依赖均可降级。


  1. 全链路压测


完备的常态化全链路压测体系,保证库存的一致性和性能符合大抢预期。



(图:全链路压测流程)


  1. 大抢预案自动化


预案自动化的核心在于两点:哪些项目是热门项目?哪些预案需要执行?


1)发现热门项目,预案根据 PV 和参与人数,自动发现热门项目,加入预案执行队列。


2)自动执行预案项,根据预先编排好的执行时间自动对抢票场次执行缓存预热、开关降级和接口限流等操作。



(图:大抢预案自动化配置示例图)


  1. 库存异常熔断


在抢票场景下,库存异常的诊断是非常困难的,基于库存扣减流水可以准确计算出库存在某一时间段内变化的情况,和当前生成的票单对比后即可以判断库存是否不一致,进而触发渠道熔断,防止情况恶化。



(图:基于时间轴的异常熔断检测)


  1. 监控及报警


在监控方面主要有:核心指标及异常监控、业务实时审计和周期巡检。


1)核心指标及异常监控


核心指标及异常监控可以有效监控下单成功率和 RT 抖动,如果有异常错误码或者抖动可以及时发现,快速介入;


2)业务实时审计


业务实时审计是数据一致性检测的重要手段,由于链路超时或异常下状态不一致的时进行报警;


3)周期巡检


周期巡检是对上述监控的重要补充,业务实时审计其实是数据状态变化触发的,当没有触发事件或者没有覆盖到其他规则时,周期巡检可以避免监控遗漏,虽然是非实时的,但是也在实践中起到不错的效果。



(图:票品健康监测示例图)


  1. 排查工具建设:快速定位,快速止血恢复



(图:排查工具包含内容)



(图:库存燃尽图示例)

四、总结

以上是票务行业库存系统建设及项目中的一些探索经验,基于正逆向流水的防重,预校验拦截,防缓存击穿,职责链模式的步骤拆分,系统间对账,数据库热点补丁的使用,日志裁剪优化等一些列技术手段,达成库存高性能、强一致性目标。


通过梳理库存红线,常态化全链路压测,异常熔断机制,监控报警以及排查工具,大抢预案自动化建设,持续提高库存系统稳定性。


作者简介


阿里文娱技术专家 古行


相关链接


10W 座位的大场馆究竟是怎么画出来的?


10 倍高清不花!大麦端选座SVG 渲染


首次揭秘!看大麦如何掌控超大规模高性能选座抢票


3D/VR 选座技术探索


2020-03-07 11:004438

评论 1 条评论

发布
用户头像
棒棒棒👍👍👍,反复看了几遍

验阶段即“高并发读”链路时,进行一些不影响性能的检查操作,比如请求的合法性校验、票品是否可售、可售数量是否足够、渠道是否授权等。在这个阶段,系统采用分布式缓存来抵抗高并发读。

2021-03-11 22:20
回复
没有更多了
发现更多内容

阿里“云钉一体”加速整合 低代码开发平台“钉钉宜搭”发布

人称T客

圣诞狂欢,保险师APP赋能精细、个性化的运营服务

DT极客

ARTS打卡 第28周

引花眠

微服务 ARTS 打卡计划 springboot

这份阿里P8级别内部疯传的“Linux私房菜”让你一次吃个饱

Java架构之路

Java 程序员 架构 面试 编程语言

Java程序员晋升之路:“Java高级核心知识全面解析”

Java架构之路

Java 程序员 架构 面试 编程语言

ZooX首发双向电动无人车,会成为自动驾驶出行的主流吗?

脑极体

利用文字技术帮助选购商品,慧眼“识”物的人都这样做……

华为云开发者联盟

文字识别 智能 识别

窝家恶补三月,字节跳动三面,终于喜提offer!分享面试感受

Java架构之路

Java 程序员 架构 面试 编程语言

Alibaba面试官:“这该死的程序员,知识竟如此渊博!”

Java架构之路

Java 程序员 架构 面试 编程语言

业务架构设计迭代演进思路

程序员架构进阶

架构 中台 业务架构

大佬带你看源码!阿里内部Android笔记火爆IT圈,3面直接拿到offer

欢喜学安卓

android 程序员 面试 移动开发

为新基建按下加速键:从openEuler看中国操作系统的产业生态未来

脑极体

(经验分享)作为一名普通本科计算机专业学生,我大学四年到底走了多少弯路

Java鱼仔

Java 程序员 面试 大学生

区块链食品溯源系统开发,农产品溯源小程序搭建

13530558032

CEG挖矿系统APP开发|CEG挖矿软件开发

系统开发

智慧平安小区整体解决方案,智慧社区管控系统开发

13530558032

第八课性能优化作业-判断合并链表

Geek_michael

极客大学架构师训练营

浅谈如何做客户端性能测试

行者AI

性能测试

LeetCode题解:剑指 Offer 40. 最小的k个数,sort,JavaScript,详细注释

Lee Chen

算法 大前端 LeetCode

腾讯大牛亲自带你学:Java安全weblogic T3协议漏洞!

比伯

Java 编程 架构 面试 计算机

工具词典:精力管理

lidaobing

精力管理 张遇升 28天写作

软件测试所需要掌握的技能

测试人生路

软件测试

ModelArts黑科技揭秘|弹性训练,让训练资源张弛有度

华为云开发者联盟

学习 华为云

如何通过一个SDK轻松搞定人脸识别,拯救初入职场的程序猿

华为云开发者联盟

人脸识别 智能 识别

3D 可视化突发公共卫生事件 ,防护效率高达90%

一只数据鲸鱼

疫情 物联网 数据可视化 数据监测 3D可视化

阿里P8大牛手把手教你!高级Android晋升之View渲染机制,先收藏了

欢喜学安卓

android 程序员 面试 移动开发

道高一丈,且看CWE4.2的新特性

华为云开发者联盟

技术 安全 漏洞

字节面试坎坷之路,第一次二面凉了!捞起来之后一面就凉了;我太难了呀!

Java架构之路

Java 程序员 架构 面试 编程语言

程序员开发指南!1-3年的Android开发工程师看过来,经典好文

欢喜学安卓

android 程序员 面试 移动开发

甲方日常 75

句子

工作 随笔杂谈 日常

SpringBoot系列(7)- 自动装配

引花眠

springboot

大麦库存的高性能及一致性是如何设计的?_文化 & 方法_阿里巴巴文娱技术_InfoQ精选文章