高性能平台设计—美团旅行结算平台实践

本文根据第23期美团技术沙龙演讲内容整理而成。

美团酒旅有很多条业务线,例如酒店、门票、火车票等等,每种业务都有结算诉求,而结算处于整个交易的最后一环不可缺少,因此我们将结算平台化,来满足业务的结算诉求。结算平台通过业务需求以及我们对业务的理解,沉淀了各种能力并构建了丰富的能力地图。

我们将业务的发展归纳为几个阶段,例如业务孵化阶段,快速抢占市场扩大覆盖阶段,市场稳定后急需盈利阶段,国内业务稳定后的国际化阶段,业务发展的各个阶段都能在结算平台找到相应的能力支持。业务孵化阶段讲究的是低成本试错,我们将结算的核心流程,账单->付款->发票等模块平台化,新业务接入只需要5~10天。我们的预付款结算、分销结算、阶梯返佣结算、地推结算能力能快速的帮业务抢占市场实现盈利。

我们的汇率管理,多币种,多时区结算能力可以助力业务开展海外市场。当前结算平台支持美团酒旅4个事业部、17条业务线,涵盖境内、境外等业务的线上结算,后边我主要介绍下对账平台的实践即账单的实践。

对账是平台化的第一环,它需要算清楚商家和美团的收益明细,后续的付款,发票等,都是基于对账进行开展的。同时它需要对接酒旅的各个订单中心,不同业务的订单具体实现和业务流程不同,不同的业务对账规则和时机也不相同,同时对账每天需要处理数百万条交易明细。

如何解决订单、对账层面的差异?每天处理数百万交易明细,如何高效准确的处理这些数据?17条业务线如何做隔离、定制、个性化扩容?其中面临了很多挑战,这也是为什么要讲对账的原因。

账单的生成逻辑主要分两部分:

早期的系统架构和实现有一些问题,比如采用单线程,Pull的模式去获取数据,生成账单,虽然部署了很多台Server,但其实同一时刻只有一台Server在工作,有严重的资源浪费,同时数据处理效率较低。本应7月1日进行结账,因为业务变更,数据处理效率低,出账往往会拖到7月底,商家体验非常差。当时除了酒店业务之外,门票、火车票业务都处于孵化阶段也有结算需求,比较紧迫的任务有两个,一个是快速的解决酒店结账不及时的问题,另外一个是支持新业务的结算需求。所以当时的策略是,优化老系统让酒店业务平稳运行,搭建新的结算平台支持新业务的孵化。

优化的策略有两点:

提高数据处理能力思路是:单线程改多线程,串行改并行,单机计算改分布式计算。具体做法是:商家ID维度用取模的方式分片,通过配置将不同的分片配置到不同的Server,同时每个Server上有单独的线程池,可以在商家ID的维度并行获取数据,处理账单。这样虽然能快了起来,但是它又引入了一些新的问题。

比如单点问题,如果Server2宕机了,配置不具备自动Rebalance的能力,就需要结合报警来人工处理,运维压力会变大。如果继续提升处理能力,就需要更多的数据分片,更多的Server资源,这时需要去重新处理分片和配置的逻辑,虽然它是可扩展的,但是并不灵活。

资源利用率波动也比较大,在7月1日处理整个月的数据,资源利用率(蓝线),在月初的时候最高,平时的时候基本上接近于0。比较健康的资源利用率,应该像黄线一样,虽然会有业务的峰值,但是整体上来看是趋于平稳的。如果是蓝线这样的资源利用,就会导致订单系统、结算系统、DB,都需要按照业务的峰值来部署,会产生资源浪费,最后我们在速度和资源的使用上求一个平衡,通过这些优化做到了及时结账。

但还遗留了如下问题:

上边这些问题在对账平台化时都需要解决,尤其是逻辑耦合问题,如果不解决,后续对接的业务越多,步伐越沉重,最终会拖慢业务的发展。解决这个问题需要优化结算系统的业务架构,需要抽象一套订单模型,商家模型,计算规则模型,这些模型要足够通用,在兼容各个业务差异同时又要有一定的扩展和定制能力,模型的抽象是平台化的关键。

结算抽象了一组统一的订单状态来描述订单的整个生命周期:支付成功,使用前退、使用、取消使用、使用后退。它们所代表的含义如字面上一样,简单便于理解,每来一条业务线,将订单的原始状态和结算抽象的状态做映射,就能解决订单层面的差异。以酒店为例:预定周日晚上的酒店,周四行程变更无法入住,周五找客服退款,客服退款成功,这个对应使用前退,客服退款在一些特殊的场景也会对应到使用后退,最终解决了订单状态层面的差异。

状态过滤出来后要计算这笔交易商家和美团分别的收入和支出是多少。如上图所示酒店要计算收入和支出需要订单的基础信息、间夜信息等因子,这些因子可能散落在各个数据表中,收集和计算非常复杂,业务变更会导致计算因子和计算逻辑变更,不同业务计算因子不相同,所以它很难复用。

资金语言是结算和订单的标准协议,不管什么样的业务,数据结构和业务流程怎么设计,都按照标准协议来,只要协议不变,不管是订单变化还是结算变化都不会相互影响,订单和结算也就具备了独立演进的可能。

如上图所示。

老架构

数据获取采用PULL模式,如果上游故障会导致无法获取数据,从而影响账单计算,重度外部依赖。不管是数据获取还是计算账单都需要穿透两层业务逻辑,业务逻辑严重耦合难以复用。

新架构

抽象了资金语言,商家信息,结算规则,标准化了接入规范,数据接入采用PUSH的模式,业务产生了交易,新签约了商家只要能将数据按时的PUSH过来就能按时结账,结算被动接收数据,轻度外部依赖。新架构设计了适配层,用来做业务数据和标准协议的适配,适配层逻辑结算和业务都可以做,但是考虑到业务侧的同学更了解业务,业务变更自己修改适配层不需要找结算排期更灵活,我们将适配层交给业务团队来做,每来一个新业务只需要一个小的适配块,就能快速接入。通过抽象的模型和标准协议,对账平台做到了数据聚合统一,计算规则统一,数据模型统一,从而达到了高度复用,结算和业务解耦。历史上酒店和旅游订单发生过多次重构,对结算基本无影响。人员也得到了高度复用,当前对账模块只有4名RD对接了17条业务线。

数据接入

订单产生交易,将交易转为资金语言,通过消息中间件(Mafka)实时的推送给结算,结算只做必要的校验,完成后数据落到MySQL中,此时数据的状态是未处理,这一步设计了ACK机制保证数据不丢。落库后会给账单引擎发一个消息,说有一条数据要处理了。数据的接入和账单引擎的计算做了分离,数据的接入非常快,基本延迟在毫秒级别。

账单引擎

账单引擎会在6月1日生成6月1日到6月30日的空账单,数据经过聚合规则,进入到相应的账单,同时触发账单计算规则,完成账单的实时计算。一些特殊的情况例如数据产生在6月1日,结算日期是6月2日,会将这个消息转发到Mafka的延迟队列,在6月2日重新消费这条消息,数据处理成功后,数据的状态变更为已处理。

账单引擎的补偿和监控机制是通过对数据的状态控制来实现的,例如6月1日到30日,商家A一共产生了1万条交易明细,已处理的数据只有8千条,那剩下的2千条要么就是在途,要么就是消息丢了,或者系统Bug,会有一定的监控和补偿策略来保证数据的完整性,账单引擎处理具体的交易明细延迟在秒级。

提高账单的处理效率需要从两个维度出发:

提高高并发设计

我们通过消息中间件Mafka来提高并发度,在Topic的维度拆分多个Partition,不同的ConsumerGroup配置不同的消费线程数,Mafka基于滑动窗口机制实现了多线程消费同一个Partition的数据,所以可以做到并发度=Partition数量*消费线程数,在数据处理上做了幂等性保障,能确保数据的正确处理。从架构上来看除了DB之外全链路无单点,比如某个Server挂了以后,通过Mafka的Rebalance机制,将Partition自动分配给别的Server,消除了Server层面的单点问题。

提高并行度设计

单个对账单包含了多条交易明细,账单的总金额是多条交易明细金额的累加,并发度上来以后,会产生线程安全性问题,怎么保证账单总金额的数据准确性?常规实现:

//事务保证原子性try{Locklock=distributedLockManager.getReentrantLock(statementId);//账单维度锁lock.lock();//获取锁,存在阻塞insert(detail);//写入明细compute(statementId);//计算账单}finally{lock.unlock();//释放锁}如上边的伪代码所示,要有一个事务保证明细写入和账单金额计算的原子性,其次是获取分布式锁,写入明细,计算账单,因为锁的缘故单账单的并发度是N,并行度是1,并行度低的结果会导致消息出列变慢,单个账单的处理效率变低,有了事务也会有一定的性能开销。怎么提高并行度,怎么减少事务的粒度成为单账单维度高性能计算的关键问题。

每个账单的写入时机不同,每个账单的计算时机也不同,所以可以将多个账单的计算时机随机相对均匀的分散开,减轻DB的压力,每个账单在最终结账时都会有一次终极的兜底计算,防止计算异常。最终做到了无事务、无锁,单账单并行度也从1变成了N,提高了单账单的处理效率。

提高读性能

场景一

以前边所提账单的计算为例,核心语句如下:selectsum(金额)from账单明细表where账单ID=X,当数据规模在亿级怎么保证效率?我们除了在账单ID维度增加索引以外,还通过分表,数据备份的方式尽可能保证单表里数据量不至于太大,来提高处理效率。

通过中间件atlas,账单明细按照账单ID取模的方式进行分表,保证同一个账单明细在一张表中,虽然会有一定的数据分布不均匀的问题,但是在很大程度上也能避免同一个表过于庞大,从而提高的SUM操作的性能。

账单明细有一个特性是不可变更,我们的业务场景是写多\读少,HBase也支持水平扩展,很适合做数据备份,所以我们通过Databus将数据同步到HBase中一份,还设计了一个程序定期的去对比MySQL和Hase的中的数据,账单结账后就不需要SUM操作了,经过一定的周期以后可以将MySQL中的明细做清除,释放MySQL的存储空间,只要一开始账单明细容量预留的足够大,通过这样的策略基本上能避免后续业务规模化后扩容产生的数据迁移问题,但是会有另外一个问题是需要定期处理数据库因为删除操作而产生的表空间空洞问题。

场景二

我们将交易明细做了冷热隔离,将已结算的数据备份到备库中,未处理的数据整体量级在10万条以内,主要是不到结算时机或者在途的一些数据,在配合一些索引,整体的处理效率是非常高的。

DB读写未来的规划

结算平台对接了17条业务线,不同业务体量不同,所需要的系统容量也不同,怎么定制化扩容?业务也会有一些特殊流程和逻辑怎么做逻辑定制?怎么做到A业务线故障不影响B业务线?

如上图,我们根据一定的路由规则,将数据灌到不同的Topic中,酒店体量比较大可以针对酒店Topic配置较多的Partition,火车票体量没有酒店大可以配置相对少的Partition,针对不同的消费组配置不同的消费线程数,从而做到给不同业务分配不同的系统容量。账单引擎由通用逻辑+定制逻辑实现,定制逻辑以消费组维度做隔离,每个消费组配置单独的开关,当业务产生异常需要暂停结算时,关掉开关,对其他业务无影响。Server集群公用,通过Mafka的机制根据Topic和Partition自动划分资源,最终做到个性化扩容,多业务隔离相互不影响。

主要分三层:

整体的扩展是需要多层进行配合的,比如Mafka的并发度特别高,Server数也特别多,但是只有一个DB,DB可能就是一个瓶颈,那就需要在DB的层面做一些扩展和优化。

最后呈现出的效果是,数据接入基本上延迟是在毫秒级别,对账单是实时对账单,产生交易后商家立刻就能在账单上看到收入明细,对商家来说体验非常好,对接了17条业务线,从不交叉影响。

THE END
1.当我是一个新人北京协和医院其实我们已经站在一个很好的平台了。好的平台意味着拥有更多的资源和机会,在这一平台工作的人也都是优秀的人。因此,在好的平台上永远不缺学习的内容,关键是你学习的意愿有多大。 团队合作的重要性 所有新人进入一个团队后都要学会如何与他人合作。我们要学会适应环境,而不是要求环境适应自己。同时记得,合作是从学...https://ims.pumch.cn/detail/16730.html
1.合作之知识,协同力量的智慧探索货架耗材4、适应性与灵活性:团队应具备适应性和灵活性,根据环境变化调整合作策略。 合作是现代社会发展不可或缺的动力,通过探讨合作方面的知识,我们可以更好地理解合作在现代社会中的重要性以及合作中的关键因素,在实际应用中,我们应充分利用合作中的知识,培养和提高合作能力,推动跨界融合,发挥集体智慧,培养适应性和灵活性,以...https://www.lzdchj.com/post/9059.html
2.企业团队协作激发潜能的无形力量一、团队合作的重要性 在现代商业环境中,一个强大且高效的团队是公司成功不可或缺的组成部分。有效的团队合作能够提高工作效率,增强创新能力,并促进员工之间的情感纽带。 二、拓展活动与个人发展 通过组织各种拓展训练和户外活动,不仅可以加深同事间的了解,还能为员工提供一个锻炼领导能力和提升沟通技巧的大舞台。这些活...https://www.tepyo.com/lv-you-zi-xun/408558.html
3.团队发展与个人价值的共生开放协作的价值观一、团队属性 团队的本质属性,在很大程度上表现为一种选择性和甄别性,即排外与排异。这意味着团队需要筛选出具有相同目标、价值观以及能力互补的成员,以达成高效的协作与共同进步。在团队运作的过程中,首要任务是明确并深入理解我们所从事工作的核心目的,这不仅关乎到每一项具体任务的成功与否,更直接影响着团队整体和...https://blog.csdn.net/sinat_19383265/article/details/137240094
4.团队合作小组协作推动项目成功的关键因素在现代企业管理中,小组协作已经成为推动项目成功的关键因素。一个有效的小组能够集思广益,快速响应市场变化,提高工作效率和质量。这一概念通过实践得到了充分的验证。在很多公司里,不同的小组名称如研发小组、销售小组、市场调研小组等,每个团队都在不同的领域内发挥着重要作用。 https://www.t60iylsx.com/jing-dian-fen-zu/431615.html
5.平台推动力量,探究其在现代社会的角色与影响技术咨询随着技术的不断进步,我们期待平台推送能更加智能化、个性化,同时更加尊重用户隐私,提供更有价值的内容,平台和政府应携手制定法规和标准,规范平台推送行为,促进信息传播的公正性和真实性。 平台推送作为数字化时代的重要特征,对我们的生活产生了深远的影响,在享受其带来的便利的同时,我们也应认识到其潜在的问题,并寻求合...https://saishenxs.cn/post/11482.html
6.团队的意义和重要性总结(精选17篇)团队的意义和重要性总结 一、团队的构成 团队是由基层和管理层人员组成的一个共同体,它合理利用每一个成员的知识和技能协同工作,解决问题,达到共同的目标。 团队的构成要素总结为5P,分别为目标、人、定位、权限、计划。团队和群体有着根本性的一些区别,群体可以向团队过渡。一般根据团队存在的目的和拥有自主权的大小...https://www.ruiwen.com/word/tuanduideyiyihezhongyaoxingzongjie.html
7.《超级飞侠》通过剧集内容说明团队合作与分工的重要性体现团队合作重要性的动画还有很多,比如《喜羊羊与灰太狼》《萌鸡小队》,假如没有团队合作,只是逞个人英雄主义,群羊如何击败灰太狼?萌鸡们又如何能够合力帮助森林里的动物?所以,对于三观尚未成型的孩童,不宜过多灌输个人英雄主义,而是要学会超级飞侠中的“各司其职”“取长补短”式的团队协作。https://m.thepaper.cn/wap/v3/jsp/newsDetail_forward_23266811
8.超强接口协作平台如何打造:细数Apifox的六把武器软件界发展至今,API(接口)的重要性日益凸显——不同的端,不同的模块都在通过API交互,不同角色的成员也都在围绕着接口展开工作。在这个前提下,一款集文档、接口调试、Mock、接口自动化测试一体的接口协作平台变得尤为必须。市面上优秀的接口调试工具如Postman、JMeter如雨后春笋般涌现,各大厂也在自研接口协作平台。 https://cloud.tencent.com/developer/article/2134792
9.融合与创新:上市公司的多元品牌设计策略4、易于扩展:品牌标识的设计应该易于扩展,可以应用于不同的媒体和平台上,如网站、广告、产品包装等。标志的设计应该考虑到这些不同的应用场景,以便能够在不同的媒体上保持一致性。 5、色彩应用:品牌标识的设计中色彩的应用非常重要,因为色彩可以传达情感和文化特色。选择合适的颜色可以帮助企业传达出其品牌形象和价值观...https://www.rhtimes.com/brand/logo-design-news7975.html
10.团队合作的重要性和意义团队合作是指多个人共同协作、互相支持、共同努力来完成共同目标的一种工作方式。在现代社会中,团队合作已经成为各行各业中不可或缺的一部分。团队合作的重要性和意义不仅体现在个人和组织层面上,而且对整个社会的发展也具有深远影响。 1. 提高工作效率 https://www.jiangshitai.com/article/6138.html
11.打造魅力团队团队协作的重要性(精选6篇)打造魅力团队——团队协作的重要性 进入单位已经两年了,在单位也不算新人了,在这段时间中,我参与了单位的多项工作,在工作中,我获得最深的感触就是:众人拾柴火焰高。工作中我们身在团队,互相团结、积极向前发展,而对于我们来讲各个部门也是一样,一个部门犹如一个团队,如果没有更好的氛围,没有团结的力量,企业的...https://www.360wenmi.com/f/filewen9r96k.html
12.简述团队协作有哪些重要性团队协作能激发出团队成员不可思议的潜力,让每个人都能发挥出最强的力量。但是,一加一的结果却是大于一,也就是说,团队工作成果往往能超过成员个人业绩的总和。团队精神的核心就是协同合作。接下来就让我们一起来了解一下关于团队协作有哪些重要性的相关内容吧。 简述https://www.jy135.com/guanli/16035.html
13.团队协作的重要性协作空间如何收费钉钉帮助中心为您提供团队协作的重要性相关问题的回答,更多团队协作的重要性问题相关解答可以注册咨询钉钉人工客服。https://www.dingtalk.com/qidian/help-keyword-1857.html