当前位置: 首页 > 科技观察

智能配送系统场景分析最佳实践

时间:2023-03-17 23:14:28 科技观察

背景作为业内最大的O2O平台,新美达平台以短信/推送为运营方式,每天触达数千万用户。美团点评在线POI超过1000万个,覆盖2000多个城市,25000个后台商圈。在海量数据存在的前提下,实时投放用户在场景选择上存在一些困难,所以我们提供场景的粒度查询和智能建议,为用户解决三大问题:我要投放的区域在哪里,实时和历史流量是什么样的?我想瞄准的地区已经发生和正在发生什么,表现如何?这个区域适合我投放吗,系统建议我投放在哪里?如图1所示,整个产品致力于解决以上三大问题,能够为活动开展前期的运营提供有效的参考和决策依据。图1场景查询模块渲染图挑战场景查询器需要展示多种类型的数据,因此数据过滤和组装的时间很大程度上取决于基础数据量。但随着维度的下钻,基础数据量巨大,数据实时计算的响应时间难以承受。数据源都是RPC服务,有各种服务需要调用。每个服务的响应时间都会影响最终的结果返回,很难提供前端接口的响应时间。需要组装的数据五花八门,没有统一的数据模型,导致代码耦合度高,后期维护难度大。针对上述挑战,我们给出以下解决方案。总体方案图2场景查询器的架构如图2所示,我们的整体架构是分层设计的。底层是各类服务,上层是预计算层和数据层。预计算层的作用是显而易见的,是连接服务和数据的核心层。数据层是从后台服务中拉取各种数据,然后预先计算形成的。再往上是中台服务层,包括服务熔断降级的核心功能,以及通用服务,为具体的业务逻辑提供统一的服务。最上层是具体的业务逻辑,对应具体的场景和需求。后台服务层该层是Thrift的RPC服务,提供各种投递反馈数据。数据组装后台服务层数据具有数据分散、结果多样的特点。数据组装就是对多个服务调用返回的结果进行过滤和组合。图3后台服务结果数据组装示例如图3所示,服务1、2、3分别用黄色、蓝色、棕色表示。A、B、C为调用相应服务返回的数据,A、B的数据格式为列表,C为单条数据。最后一个虚线框代表数据组装算法。A和B的列表相交,结果是一个长度为2的列表,然后依次调用服务3单独获取数据C。数据拼装痛点过程繁琐,如取路口、单独拼装等,拼装时间受数据量影响较大。在组装过程中,大量服务调用混杂,组装时间受服务响应时间影响较大。后台服务层主要负责提供数据和保证服务的可用性。但在组装过程中遇到了以上痛点,导致请求响应时间长,用户体验差。避免此类问题的主要方法是提前对服务调用数据进行组合计算存储,即数据预计算。预计算层的主要作用是提前计算数据,快速响应请求。构建过程依次为数据建模和计算模式构建。该层主要包括以下核心功能。构建通用数据模型,让上层控制和处理更高效。在保证计算速度的同时,计算大量的基础数据。为了保证数据的实时性,实现了高密度并行计算。数据模型图4预计算数据模型在场景查询器中,提供给前端的数据一般是上下层数据。比如页面要显示全国汇总数据,同时层叠显示下属省份数据。如果显示省级汇总数据,则同时级联显示下属地级市的数据。通过分析业务需求,发现需要的数据多为分上下级的级联数据。抽象后,数据模型被设计为树状结构,如图4所示,左侧为概念模型。树的高度只有两层。根节点为汇总数据,叶节点为地理层面维度下钻的数据;右侧是实际使用模型,由于底层维度的基数比较大,不利于下层数据的遍历、过滤和分页,所以在实际使用中,下层节点数据为存储在列表中。一个节点可以存储多个指标,具体类型取决于地理维度。该模型的特点是:一是支持地理维度的连续下钻,二是在后台服务支持的情况下,可以对历史数据进行预计算。数据存储和获取有了数据模型,需要确定一种高效的数据存储和数据定位方法,因为结果数据多为非半结构化数据,低维数据的数据量大,所以采用NoSQL存储数据。图5数据存储和提取方式示意图,如图5所示。ID表示地理维度值,level表示地理维度的级别,数据节点(包括根节点和叶节点)以ID+level为key将它们转换成树形的JSON格式数据存储,通过ID+level可以唯一获取一条数据。如果数据量不大,也可以通过级联得到下层模型,即图中的虚线表示级联得到下层数据。计算模型是建立在数据模型的基础上的。这一层的核心是预计算模型。从业务需求出发,数据需要在地理层面的维度上不断下钻,从全国出发,下到POI层面。每一层分别分层计算,然后存储计算结果。图6预计算模式示意图如图6所示,每个矩形代表一个一级维度的计算,维度从左到右向下钻取,从全国数据到商圈,以及计算层是针对每一层单独计算的。实现方法图7序列计算示意图如图7所示,是两种计算方式的实现方法,上半部分为串行序列计算,下半部分为并行序列计算。每个部分从上到下分为不同的颜色,以区分不同的计算级别。每个矩形对应一个特定ID的计算,t代表计算时间。这里假设所有计算单元的计算时间相同,方便比较计算时间。1)串行顺序计算如图7所示,普通串行计算采用单线程计算,从上到下计算。这种计算有两个痛点。首先是时间复杂度,每个计算单元的计算时间都会累加。比如第一层的计算时间是3t,第二层是4t,第三层是6*t,总时间是13t。其次是空间复杂度,因为数据是通过调用后台服务获取的。在计算第一层的时候,需要把下层的数据全部存储起来,然后在计算下层的时候遍历数据计算。2)并行序列计算依赖于ApacheStorm计算框架,将数据抽象成流,然后通过不同的Bolts计算不同维度的数据。每一级Bolt首先处理数据,然后将低级数据流入下一级Bolt。同时随着维度的向下钻取,计算的数据量越来越大,通过增加Bolt的并发来加速计算。在预计算过程中,主要利用Storm高速数据分发和高密度并行计算的特点,规避串行计算的痛点。首先,时间复杂度大大降低,如图7所示,因为可以并行计算,所以每一层的时间只有t,所以总时间为3*t。当然,这个估计是不准确的,因为在传输数据之前,不需要把一层中的所有数据都计算完,可以在每个计算单元中运行。,只是传输数据。这样可以形成上下数据计算流水线,进一步压缩计算时间。其次,空间复杂度大大降低。在Storm中,不需要保存下层的数据,因为数据是不断流动的,经过计算后会发送给下层的Bolt。为此,本文使用Storm进行预计算。计算拓扑如图8所示。图8Storm计算拓扑结构示意图如图8所示,只有一个数据源(ChinaSpout)。Spout首先计算全国到省的数据,包括全国汇总数据和省数据,然后立即将所有省数据流入其中。ProvinceBolt在下层,这一层要考虑增加并发度,因为从省到市级的数据层级开始扩大,设置并发度为40,计算完从省到市的数据城市层面,数据开始流入CityBolt,这一层涉及到城市层面的数据,可以扩展并发。当前配置为300,计算完成后,数据流入最后一层BareaBolt,计算从商圈到POI层级的数据。各级Bolt预计算产生的结果数据将存储在数据层中。我在存储中遇到了问题。在计算商圈到POI级别的数据时,发现POI的量级比较大,不能直接存储。为了不影响数据模型的通用性,我们在POI层面对数据进行压缩后存储。为了保证数据的实时性,数据源会周期性地产生数据流来更新预先计算好的数据。其实这是Storm的一个计算模型----DRPC。数据源是传输的参数,Storm各级的bolt承担计算。.这一层解决的最大问题就是计算速度慢的问题。通过高密度并发计算,减少重复数据过滤,合并大量数据,批量数据获取慢对响应时间的影响。数据层预计算后的数据需要存储起来供业务逻辑使用。存储选择需要满足以下几点:预计算生成的数据模型是树形结构,不适合关系型数据库。数据具有时效性,数据过期会带来脏数据的高密度并行计算,大量并发写入,需要保证写入速度实现容灾,当存储不可用时,需要降级服务为了满足上述需求,选择了美团点评内部自研的公共KV存储组件Squirrel和Tair分别进行存储和容灾。其中,Squirrel是基于RedisCluster的纯内存存储。Squirrel属于KV存储,具有写入和查询速度快、并发度高、数据支持丰富、时效性好的特点。但是Tair支持持久化,性价比更高。它适用于灾难恢复。当Squirrel不可用时,使用Tair提供服务。在熔断层的预计算过程中,为了实现容灾,还需要利用熔断技术实现服务降级。熔断器虽然在上层控制,但严格来说应该属于数据层。图9服务熔断和降级工作原理熔断技术采用公共组件Rhino(美团点评自研稳定性保障平台,比Hystrix更轻量、易用、可控,提供故障模拟、降级演练、服务熔断、和服务限制。流媒体等功能),主要功能有:a.保护服务,防止服务雪崩b.及时熔断保证服务稳定c.提供多种降级策略,灵活适配服务场景如图9,虚线框代表Rhino控制区,当request1到达时,squirrel没有问题,正常提供服务。当request2到来时,访问squirrel出现异常(超时、异常等),请求切换到Tair。在squirrel恢复期间,Rhino会心跳到squirrel以验证服务可用性。Request3请到squirrel,此时已经恢复正常。由于Rhino会定期检查,请求再次切换到squirrel,恢复正常。中端服务层数据准备好后,不能直接供业务逻辑使用。需要提供统一的服务来应对不断变化的业务逻辑。该层主要解决以下问题:数据模型的修改对业务逻辑有影响,数据服务需要对上层的具体业务逻辑透明。业务逻辑对数据有一些通用操作,需要抽象通用操作,防止数据服务在存储不可用时紧耦合。需要进行服务熔断和降级,以减少对业务逻辑的影响。业务扩展和增强能力不能影响正常的业务逻辑。该层对外提供RPC服务,直接处理数据模型,提供数据分页、数据压缩、数据解压、数据筛选、数据批量提取等功能。而数据原子抽取等功能基本涵盖了大部分对数据的操作,让业务逻辑更加简单。在提取数据时,添加Rhino实现服务熔断和降级,为业务逻辑层提供稳定可靠的服务。由于该层直接操作模型数据,即使数据模型发生变化,也不会影响业务逻辑,大大降低了数据与业务的耦合度。另外,这一层支持服务的横向扩展,在消费者数量众多的情况下,依然可以保证服务的可靠运行。通过一系列的抽象和分层,可以直接使用一个简单的服务接口来实现最终的业务逻辑。客户端的响应从最初的十几秒提升到不到1秒,数据和代码的耦合度大大降低,对于后续的业务变更,只需要修改数据模型,增量提供几个中端服务接口来满足需求,大大降低了开发难度。作者简介张腾,美团点评系统开发工程师,2016年毕业于西安电子科技大学,同年加入招银网络科技,从事系统开发和数据开发工作。2017年加入美团点评数据中心,长期从事BI工具开发。【本文为栏目机构“美团点评技术团队”原创稿件,转载请微信联系机构♂获得授权】点此查看作者更多好文