类Uber/滴滴分单引擎中应用到的技术原理 (2)
结合之前文章
继续深入一层推导‘分单引擎’面临的问题
回顾上一节,提到了此类‘分单引擎’ 核心需要解决的问题是:完成叫车订单的分配。策略上的核心原则是:“站在全局视角,尽量去满足尽可能多的出行需求,保证乘客的每一个叫车需求都可以更快更确定的被满足,并同时尽力去提升每一个司机的接单效率,让总的接驾距离和时间最短。”
那么,进行合理推断,业务上需要解决的核心问题如下:
- 如何且何时去触发乘客订单和司机之间的匹配计算进而完成派单(除了派单这种模式,何种场景下会使用抢单模式)才能满足乘客乘车需求?
- 考虑不同乘客的订单需求(接乘体验、效率)、司机自身的需求(如,有的司机只想接回家顺路单、司机只在限行区域内行驶、司机只听预约单),那么如何保障在各种业务场景都正确性的前提下,来找目标函数下的最优解?
- 从打分分配过程来看,目标函数考虑的因素不仅考虑乘客与司机之间的导航距离,还会考虑到司机的服务等级分、价格、供需紧张程度等多种因素。那么,如何在效率指标和成本等指标之间做出权衡?
- 在垂直的子场景下,优化子场景的目标,从而间接支撑核心目标,如动态定价、供需调度(基于供需热力图,给司机发空单调度司机到需求密度更好的地区)、分场景派单(机场、火车站的派单距离会长一些,且进行公平派单 - 先来后到的原则)、不同运力层之间互转(运力不足等情况下,快车单给专车)
... ...
基于问题推断总结这类‘分单引擎’的边界
可以预见,继续推导下去,需要解决的业务问题还有很多,但尝试对这类‘分单引擎’做一个总结和定位的话,应该有如下几个要点:
- 职责:在合适的时刻,把合适的订单,分配给合适的司机
- 主要的业务目标:兼顾业务运营上的需要,保障体验和全局效率最优
- 猜测来看,从业务运营上,应该会分各类不同的场景,且围绕不同场景,定义出更具体的成本、体验、效率的指标,足见‘分单引擎’是实现业务运营目标的重要抓手
- 系统上的目标:支撑全国各个城市(跨城)订单最优分配,保障系统对于业务规则类需求和策略类需求能够快速扩展开发落地、系统架构具备根据容量规模的横向扩展能力以及性能保障
- 逻辑结构上,需要能够将分单的整个过程进行抽象,拆分成相对固定的模块/步骤。围绕模块/步骤,再嵌入可插拔的规则扩展实现。如,
- 通过规则引擎来支撑上述所需要的为保障分单业务正确性的各类业务规则;
- 通过策略引擎让算法同学基于统一的同一套数据结构可以按场景去叠加各种寻优策略来找到最优匹配(如,二分图,乘客与司机可以为两个顶点集合,通过计算各种边的权重,以找到图的最大匹配));
- 核心系统架构上,需要有,
- 实现‘延迟分单’的定时器
- 有能够进行全局资源监控和管理的资源管理器
- 有对分单计算任务和资源匹配的任务调度器
- 有用于具体执行分单匹配计算的任务计算节点服务。且在任务执行过程中,可以根据任务计算量,动态决定拆分一个大任务成多个可并行执行的小任务,然后再聚合结果
- 存储着司机位置、订单数据等高效的索引存储系统
... ...
一种简化版的分单引擎的架构从上图可以看出,一次分单计算的任务类似一次Hadoop 中MapReduce的批量的执行计算任务过程(结合Yarn 资源调度管理来说):
- 定时触发生成的Job中,所有需要匹配计算的订单和司机数据,类似于MR程序要处理的数据;只是真正执行的程序不像MR Jar 那样,可以在Hadoo环境下,执行时再通过HDFS动态加载执行(即移动计算式的方式)。这里,执行的匹配计算逻辑,都预先启动在各个分单计算节点当中;
- 提交的任务根据需要计算的任务负载,从资源管理器匹配可以满足其需求的资源(包括master 机器信息以及可以进行并行执行子任务的Slave 机器信息)。根据任务的大小,如Yarn中所支持的能力(Uber 模式和non-uber 模式),可以实现动态判定对小任务类的匹配逻辑都执行在一个机器资源中并一起顺序执行,而大任务类的匹配计算(订单和司机之间的匹配过滤、打分等逻辑)则由资源管理器预先分配好哪些机器可以用于执行具体的匹配计算任务(包括指定一个Master节点和多个Slave 节点),在Master 节点中可以根据预先配置的分片阈值,拆分成多个分片,在并行执行完之后,再回到Master 节点执行最终的司机派单计算;
- 每个任务计算执行节点,定期上报自己的资源使用情况。Yarn中是通过Container 的抽象概念,综合了CPU、内存等多维度的资源模型;而基于统一的资源管理器和无状态的分单计算节点集群(被资源管理所管理),并结合任务大小自动决策资源分配,将使得资源可以在充分利用的情况下,并支持水平扩容;