当前位置: 首页 > Web前端 > HTML

VOP消息仓库的演进之路-如何设计亿级企业消息平台

时间:2023-03-28 16:25:17 HTML

作者:京东零售李梦东VOP作为京东旗下企业业务对外API对接采购供应链解决方案平台,一直致力于从企??业采购数字化领域出发,充分发挥借助京东数科的智能供应链能力,通过产业链上下游的耦合联动,有效帮助企业客户优化成本,提升资产效率。本文将介绍VOP如何通过亿级消息仓库体系,保障上千家企业KA客户与京东的数据交互。本文共有5088字。如果你觉得页面很长,那是因为有很多代码截图和注释。哈哈介绍留言(仓库)是电商业务场景必不可少的核心功能。VOP自上线以来,就开始迭代构建和演进。.截至目前,VOP消息仓已接入200+个内部消息终端,对外提供80+条消息,服务3000+企业客户,涵盖商品、地址、发票、订单、售后、等VOP所有业务场景。后勤。在消息系统中,一般有两种消费模式:服务端推送和客户端拉取。本文除了描述消息仓的技术架构演进,重点介绍了构建当前客户端拉取的消息仓的实践经验。客户来电场景以产品消息为例。京东的业务目前拥有约5600万+种产品。这些产品涉及基本信息、价格和库存的变化。获取相应信息,同步本地商品库,业务处理完毕后删除该批商品消息,定时循环。其他类型的消息同理,不再赘述。消息仓库V1.0和我们所知道的系统是一样的。随着业务的发展和企业客户规模的增大,消息仓库的整体架构和底层存储系统逐渐成为瓶颈。特别是在数据库方面。毕竟在高并发读写的场景下,很大一部分工作都是围绕着数据库进行的。因此,前两次升级迭代要解决的主要问题是如何增加数据库容量。虽然一开始我们通过读写分离的方式有效降低了数据库的负载,提高了系统容量和稳定性,但是缺点也非常明显:主从延迟、从库数据量受限等问题,高TPS无法妥善解决。而且,随着618、1111等各项活动的开展,VOP端客户的不断增加,留言的激增也成为我们不得不尽快面对的问题。限流、缓存等措施可以保证系统的高可用和并发能力。.但是,消息积压量大、消费水平受限、消息同步不及时等问题越来越严重,会对业务造成损害。因此,在对系统进行评估后,我们对系统进行升级。通过分析,最阻碍我们的核心原因还是数据库。(此时消息表有上亿行,容量超过10G。)因此,当读写分离不能满足我们的业务需求时(已经做好数据归档),分库的模式分表也需要注册。在舞台上。如何分库分表,注意事项等我就不赘述了,有兴趣的推荐阅读菜鸟积分系统分库分表的实践https://mp.weixin。qq.com/s/uF...分库数据库新旧进程对比新旧进程对比切换依据(供参考)根据ducc和clientId决定是否写入新库,以及switch、whitelist、blacklist和shuntrange在ducc(bizMsgTransDbJson)中配置使用新库写入,根据clientId.hashCode%dbSource.size,获取使用哪个dbSource。客户端读取时,先从旧数据库中查找。如果没有数据,则重新读取新数据库。dbSource的选择方法同上。ID是否大于万亿(1000000000000),大于新数据库,小于旧数据库?由于多主架构,分库分表不仅包含了读写分离模式的所有优点,还解决了读写分离架构无法解决的问题。解决了TPS过高的问题。同时分库分表理论上可以无限水平扩展,也解决了读写分离架构下分库数量有限的问题。当然,在实际工程实践中,一般需要提前预估容量,因为数据库是有状态的。如果发现容量不够再扩容,很麻烦,应该尽量避免。在分库分表模式下,可以通过不开启从库查询来避免主从延迟问题,也就是说读写都在主库,因为分库之后库,每个master上的流量只占总流量的1/N,大部分情况下可以承载业务的流量,从库只是作为master的备份。当主库宕机时,进行主从切换,代替master提供服务。优化前的情况是好的。无论从客户角度,还是从内部消费角度,消费水平都有了很大的提升。解决消息高峰下跳点和高TPS影响CPU的问题。整个消息仓库的性能和稳定性都是趋势性的。更稳定。为什么前期形势好?相信大家都有所期待。分库虽然大大提高了系统的整体吞吐量和稳定性,但由于之前的容量评估问题(业务增长增加)和自身现有架构的限制(单体应用),在分库中已经稳定运行了大约一年,出现了一些明显的痛点:痛点问题海量数据:19年客户数量和商品类别(商品等级)大幅增加,仓库数量初期增加消息数据的存储时间由2-3天增加到7天(原因:考虑政府、银行等客户在重保期间不消费消息的空档期,但后期验证的空档期只要月维度),消息仓库的流量出现了频繁的翻倍增长,数据不均衡现象逐渐显现;领域扩展:随着业务的不断演进,消息的内容也逐渐变得复杂(例如售后消息会附带各种链接的信息,整个JSON消息体更大),入库或有a字段长度限制,很难调整字段;高可用&扩展性:在原有单体结构的情况下,会存在热点数据的影响,以及热点商品消息数据对订单和对账消息数据的写入和同步带来严重的延迟问题和服务性能跳变问题。运维成本高:由于系统面向的是大量的开发者,系统必须考虑到各种网络环境问题和开发者能力问题。企业对接客户经常上门查询新闻量和新闻消费情况,没有相应的内审数据可供参考。目标未破但未立。为了避免消息问题和其他系统类似消息需求的长期频繁影响,我们迫切需要构建一个可重用和可扩展的企业消息中心。在满足业务需求的同时,还要综合考虑易用性、低成本、高吞吐量和强扩展性,保证消息在迁移过程中不丢失,客户无察觉。方案分析经过多方调研考察,初步选择了两种存储方案:Mysql+es和MongoDB。我们从存储成本、开发维护成本、性能对比三个方面对Mysql+es和MongoDB方案进行评估。(仅供参考,具体还是要根据自己的业务评估)存储成本:MongoDB存储优势明显——数据压缩,无冗余存储,与Mysql+es相比,数据总容量会减少更多超过50%。开发和维护成本:MongoDB不需要数据同步,降低了开发和维护的难度;字段调整方面,Mysql+es架构对业务存在抖动风险,DDL相关问题风险高,容易出错;MongoDB开发维护成本低,存储结构简单,无数据一致性压力;在扩容方面,MongoDB支持随时动态无脑扩容,基本没有上限问题,但是Mysql的扩容需要保证hash一致,迁移数据灰度等,周期长,存在高业务影响的可能性。性能对比:经过压力测试,在相同的4C8G机器配置下,MySQL和MongoDB在大数据量下的写入性能基本一致。MySQL单个分片的可读性在6000QPS左右,而ES的性能只有800QPS左右。MongoDB单分片读性能在30000QPS左右,远高于MySQL和ES。MessageWarehouseV3.0没有完美的架构,只有合适的架构,没有满足一切的架构,只有满足目标的架构综上所述,MongoDB不仅完全满足业务需求,而且在其他方??面优于其他解决方案方面,所以最终选择MongoDB分片集群作为最底层的数据存储方式,将系统架构重组为四个阶段:消息接收阶段、消息传递阶段、消息写入阶段、消息可视化阶段。主要职责如下:消息接收阶段(vop-worker):系统只关注不同消息源的接入。目前已接入中台近百个新闻源,依托BTE任务平台、订单&商品池&主数据&消息中心等服务。、清洗、封装等手段将需要入库的业务消息数据进行封装并转发出去。消息中转阶段(JMQ集群):中转消息,分级管控,目前分为四个层次,为解决核心消息在某些时间段消耗不及时,CPU内存飙升的问题。按级别设置消费线程数,低级别消息不会影响高级别消息的消费。低级消息具有降级能力。消息写入阶段(vop-msg-store):消息写入阶段,批量双写,MongoDB+ES(支持多维运维审计查询和数据导出)。MongoDB解决了tps10000+、日均数据量5亿+、查询条件多、数据分布不均等问题,解决了数据库无法支持租户数据统一性和消息内容扩展性的问题;创建mongo表,设置租户id和事件id索引,设置租户id的分片规则,设置唯一索引,设置超时时间为45天。ES解决消息运维过程中的审计、校验等问题。消息可视化阶段(vop-support-platform):解决客户生产/消费能力无知、全局消息不可控、消息可视化等问题。而数据可视化的不断完善,将反哺架构易用性的提升,为我们后续设立的优化课题打下坚实的数据基础。补充:MongoDB分片集群不存在单点故障的原因——当MongoDB部署为分片集群时,应用程序通过驱动访问路由节点,即Mongos节点。Mongos节点会根据分片键值进行读写操作,执行读写操作分配的具体分片,然后将分片的执行结果组合起来返回给应用程序。集群中的数据是如何分布的?这些元数据记录在ConfigServer中,ConfigServer也是一个高可用的副本集。每个分片管理着集群整体数据的一部分,同时也是一个高可用的副本集。另外,路由节点,即Mongos节点,在生产环境中通常会成倍部署。这样整个shardedcluster就不会出现单点故障。MessageWarehouseV3.0给我们带来的效果也非常显着,高标准达到了预期目标:支持5亿条日均消息写入,现在支持6wTPS和100ms到40ms的1wQPSTP99,在高标准的情况下吞吐量性能稳定,新架构边界清晰,新需求不涉及核心系统改造。数据的有效期已从7天增加到45天。IT成本增加到45天。信息可视化大大提升了运维效率,技术客服全面开放使用消息仓库V3.0+(回首往事),我们之前一直在奋起直追,并且现在系统稳定了。为了达到不影响消息仓库未来增加客户和产品并稳定运行3年以上的目标,我们决定对有限的资源进行限制。接下来,换个角度思考问题,优化目标。随即,我们对消息数据进行了多次专项治理,重点从流量治理、系统稳定性建设、降低成本三个方面进行。锁定目标后,接下来就是慢慢走向目标。流量管理(高峰时削减亿级消息量)1)优化业务场景,从源头减少调用量,梳理系统流程,优化无效数据源接入,历史dryrun逻辑等。2)a.无效的客户控件(LoadingCache)。由于其他终端的外部客户访问VOP,需要主动屏蔽一些不消费消息的无效客户,解决无效客户消息传递和存储的问题。b.缓存,减少耗时操作等。3)消息过滤器(jimdb),通过防重控+时间窗,对没有消费和重复sku的客户进行去重,解决客户消息消费延迟,量大客户消息量大,重复消息多,客户系统重启后消息量巨大的问题,大大减少了我这边MongoDB存储的数据量。这里要补充一个小插曲。在流量管理的过程中,我们也发现了数据中的一些问题,并将其作为数据支撑,指导我们的产品优化,通过技术手段进行优化处理。**如:通过数据分析,我们发现部分客户(如中国联通)在整个消费过程中存在消费缓慢或无效消费等情况,导致信息同步不及时。重新推送功能用于提高客户与京东之间的同步率。即通过自助重推功能,在同步异常时协助客户进行二次同步。以价格变动为例,通过客户订单价格不一致,自助重新推送价格变动,恢复因客户同步异常导致的异常订单,提高客户订单完成率,以及整体GMV产出可进一步提升。这也带给我思考,无论是引进还是自研,无论是架构还是工具,都是为了真正解决业务问题,在降本增效上带来价值。无论大小,都是创新。系统稳定性(解决cpu毛刺和碎片热点)1)提高资源利用率:优化部分代码结构,如:将list.contains()转换为set.contains(),使其时间复杂度从O(n)降低到O(1),不需要在主进程中执行的任务的耗时或异步处理,单写转换为批量写,传统重量级锁使用操作系统互斥锁带来的性能损失等。这解决了大流量下机器CPU飙升影响整体性能的情况。2)一个。主动降级队列:前面提到MongoDB对租户id设置了分片规则,所以当单个客户频繁进行大量商品池操作时,会发送消息说该客户大量商品进出水池。由于目前整个系统的吞吐性能非常优秀,所以在写入MongoDB时,会造成单分片热写问题,所以设置一个主动降级队列。具体实现是在消息仓库多租户场景下,隔离某个配置(某客户+配置详细消息类型)异常客户的过载流量,不影响整体客户,保证服务质量。底层存储介质,即异常流量超过阈值,则进入降级队列。b.JMQ消费线程调优等成本降低(非活跃期,白天消息量级晚上相对较小)serverless自动伸缩:利用秒级消息接收阈值和机器CPU阈值触发自动伸缩策略,通过调优,非大促期间消息仓库整体资源成本下降了52%。总结目前消息仓库从正式服已经步入V3.0+版本,不断迭代更新。已成功经历四次大升级,系统各项性能指标稳定。以最近的大促为例,2022年双十一开门红,消息相关接口表现稳定。MongoDB整体写入QPS为2w,查询QPS为4.3w。并且通过评估完全可以应对下一次独立farm切换带来的消息增长。在消息仓库整体架构演进升级的过程中,虽然基础中间件为我们提供了各种高可用能力,但可用性最终还是会回归到我们的业务架构本身。业务系统需要根据各个平台的业务特点,尽可能选择最优的可用性方案,在系统架构上遵循一些原则,比如最小化关键依赖;消除扩展瓶颈;预防和缓解交通高峰;过载时执行优雅降级等等。更重要的是,我们需要时刻思考架构如何支持业务的长期增长。如果以后有时间,您还可以同步我们其他的数据推送平台给您。(一键三连提醒)期待保持工匠精神,精益求精:在保证系统稳定性和可扩展性的同时,以业务为中心,继续践行数据驱动的实践方法,进一步完善各项系统客户和VOP。消息同步率,通过技术手段不断优化产品,提升客户搜索体验和订单成功率。消息数据治理:消息推送和消息拉取都有一个极其明显的特点。当客户系统的消费水平足够好时,大部分数据会在几秒内完成写入和删除,两个操作就完成了。这个数据毫无意义。(比如前一天有3000W+的消息数据生产和消费速度几乎是一样的。)在这种场景下,使用任何存储介质本身都是不合理的,就像插入一段几乎不可读的数据一样存储介质。将这种生命周期很短的数据放在存储介质中,不仅浪费资源,还会导致存储介质成为未来系统的瓶颈。考虑到服务器本身的成本,可以升级过滤器或者参考计算机三级存储架构的思路。未来,大量这样的消息交易将在Memory中完成,其他消息将按照原来的方式进行操作。级别的消息交易都在Memory中完成,节省了大量的服务器资源。推送方式标准化:在轮询状态下,数据的实时性取决于客户应用的轮询间隔。这种模式下API调用效率低下,浪费机器资源。如何结合业务端推进数据推送的标准化,为客户提供实时可靠的双向数据交换通道,大幅提升API调用效率,也是我们未来重点关注的方向。*这次写到这里,比较零散,很多细节(比如:如何优化线程提高吞吐量,大流量消息下的数据埋点和分析等)无法完整描述,如果你有任何问题,欢迎交流。希望文章中消息仓库的演进经验能给大家带来一些收获。换句话说,你不妨想一想你会用什么样的技术方案和方法来解决演化中遇到的问题。欢迎留言交流,希望与更多志同道合的伙伴交流。最后,和往常一样,欢迎大家点赞、收藏和关注+关注。

猜你喜欢