浅聊实时用车场景的派单抓车

160 阅读6分钟

派单系统简介

从外部一个打车用户的视角来看,网约车的派单系统,就是给打车的用户找到一个最合适的司机。

从内部一个代码开发者的视角来看,网约车的派单系统,至少得包含如下步骤:

  1. 确定好用户打车的完整需求信息、就是订单特征数据。
  2. 基于订单的起点位置,从周边范围抓取可用的司机。
  3. 确定好司机完整的特征信息,就是司机特征数据。
  4. 获取派单筛选策略,对订单抓取的司机进行过滤筛选。
  5. 确定好过滤后可匹配的订单和司机的组合。
  6. 获取派单倾斜策略,确定好订单和司机组合的派单权重。
  7. 对订单和司机的多个组合调用算法进行最优匹配。
  8. 确定每个订单最优匹配的司机,并完成乘客和司机之间需求的成交。

派单的整个流程,简而言之就是:确定需求 -> 抓取司机 -> 基于策略剔除不合适的司机 -> 确定好司乘可匹配的权重 -> 调用算法进行最优匹配 -> 完成司乘的成交。

对于网约车公司来说,派单系统是整个技术体系中最重要的一个节点;对于派单系统来说,抓车又是整个流程中最重要的一个步骤。

派单抓车

派单抓车更完整的含义是:基于订单的起点位置,找到其周边的可用司机。那么问题来了?

  • 如何基于位置,从周边去找司机呢?
  • 如何定义可用的司机?

先聊第一个问题

订单和司机为什么能够基于地理位置来确定关系?首先,要感谢Uber提前建立好了地球整体的位置索引系统 H3体系,地球表面任何一个位置都有其归属的六边形网格;然后,确定订单起点位置对应的六边形网格,司机当前位置对应的六边形网格;最终,基于六边形网格建立乘客和司机之间的关联关系。

但是司机的数量众多,比如:滴滴有千万的司机、小的平台也有百万或者十万级别的司机,这么多司机在马路上不停地移动,如何管理好如此多不停移动地司机位置数据?

全中国所有司机位置更新和查询的并发量会非常之高,几十万或者上百万QPS的数据更新,再加上几十万QPS的数据查询。这样级别的流量,司机的位置数据必须要进行分库分表,那么如何进行分库分表呢?

按照正常的思维,基于中国的行政区域进行划分,不同城市的司机建立不同的库和表,这样每个城市的订单都可以派给本城市的司机,做到城市级别的数据隔离。这样又出现了两个问题:

  1. 异地城市的司机,到了本地城市,如何让其接到本地城市的订单?
  2. 在城市交界处位置的打车需求,只能抓到需求归属城市的司机,无法抓到更多城市的司机?

要解决这两个问题,有个前提条件是 不同城市的交通政策不同,是否允许异地城市的司机在本地接单。如果允许,则解决司机城市级别数据隔离的问题,让本地城市的订单能够抓到异地的司机;如果不允许,则要让异地的司机能够接到返程单,让异地司机不至于空跑回去。

如何让异地司机接到返程单呢?

  • 返程订单本身就包含多个城市,可以按照城市从多个库中抓取司机,如果有司机符合要求,可以优先把订单派给此类返程司机。

如何让异地司机接到本地订单呢?

  • 司机一旦跨城,从一个城市到了另一个城市,位置更新要进行数据双写,既要更新到归属城市的数据库中,也要更新到实际所在城市的数据库中。其中更新到归属城市的数据库中,是为了保证司机在刚跨出城市边界时,归属城市的订单依然可以抓到司机,给其进行派单;而更新到实际所属城市的数据库中,是为了保证司机在异地时,异地城市的订单可以抓到此司机,给其进行派单。

还有一个问题没有解决,就是在城市交界处的打车需求抓车范围覆盖多个城市时,如何从多个城市去抓车派单呢?

  • 这个问题的关键是:如何确定需求抓车范围覆盖了多个城市,这个是GIS领域的能力,可以调用外部接口解决,或者建立本身的地图能力来解决。

再聊第二个问题

可用司机对于用户来说,其实就是这个司机现在可以为我们提供服务的司机。

现在立刻就可以为我们提供服务的司机,从外部要素简单来看需要包含如下:

  • 司机当前处于上线状态。
  • 司机当前处于空闲中,而没有在服务其它乘客。
  • 司机当前是合规的,双证齐全,符合平台的接单规则。
  • 司机当前符合城市政策要求,比如:单双号限行要求。

从开发者的视角来看,定义的方式又会更加的精细化,司机不可用的状态会更多。比如:

  • 司机当前处于待确认接乘状态,表示司机在决策是否接单的状态。
  • 司机服务过程中,点击了完单收车,表示司机只想服务完这一笔订单了。
  • 司机进入了某些禁止接单区域。
  • 司机多次违规,被平台进行了处置,限制接单。

总结

以上聊到的问题,都还只涉及到了普通实时用车的场景,基于用车的起点位置,从周边去抓取司机。

那么预约用车、司机在场站排队等单、包车等场景,派单抓车的方式又完全不同,后续再见。