【CSDN现场报道】2015年11月19-21日,由CSDN重磅打造的“2015 中国软件开发者大会”(以下简称SDCC 2015)在北京朗丽兹西山花园酒店隆重召开。今年是第七届,大会为期三天,除了阵容强大的全体大会外,主办方还精心筹备了九大技术专场论坛,包括:架构实践论坛、前端开发论坛、数据库实战论坛、研发管理论坛、安全技术论坛、算法实战论坛、编程语言论坛、产品与设计论坛、微信开发论坛。此外,还有五场特色活动及展览展示。
滴滴专车技术总监李添翼进行了主题为《揭秘全球最大一站式出行平台的技术真相》的演讲。在开始他首先分享了滴滴专车所获得的成就,然后他开始介绍在线业务系统和大数据平台结构,并就他们的服务架构进行剖析。他也就动态调价、分单系统、坐标数据处理流等功能或模块拎出来,从它的架构、设计上的考量等方面进行详细讲解。
以下是李添翼发表的主题演讲:
滴滴专车技术总监李添翼
我们讲一点滴滴自己的东西!我是来自滴滴出行的李添翼,现在在滴滴负责专车相关的研发工作。今天的分享主要是讲滴滴成长为一个一站式的出行平台,我们背后的技术支撑是什么样的?在开始正式的分享之前,我想给大家看一下数据!
这是当前的滴滴的市场占有情况,2.5亿注册用户、一千万注册司机,以及一千万的日订单,同时我们有出租车、专车、顺风车和代驾巴士这样的业务。这样的平台背后的技术体系是什么样的?简单分为两部分,一个是在线业务系统。另外是整个大数据平台,这些业务系统大家能看到或者用到的是端上的东西,乘客端、司机端会通过长链接服务和HTTP服务跟后端交互,通过HTTP服务,来进行订单、计价、券系统、支付、分账。在座的同学了解到ADD都是2014年开始的补贴到站,有补贴的地方就有人拔羊毛!有人会来刷我们的奖励和我们的券,我们有一个很强大的HTTP平台。后续有后端的服务、坐标流、弹性定价和分单,在线业务的支撑是大数据的平台!刚才说到滴滴数据量很大,有上千万的日订单,有数百万的司机在不断的上传坐标,每天产生的日志超过10T,这样的数据我们怎么用呢?我们大数据平台提供了这样的一些支撑,了解当前的一个供需情况,对我们供需进行预测!订单的密度是怎么样的?用户的画像,了解司机和我们的乘客,他们大概是什么样的偏好,在不当的时候应该派什么样的订单,大数据平台最主要的部分是弹性定价,知道以什么样的定价更合适?分单的环节怎么招到最合适乘客和司机的匹配情况!以及对应的标签服务或者特征服务。
这是我们整个系统的概貌,接下来我从出行需求从开始到结束这样的维度来分享整个滴滴的技术平台!专车这样的技术平台,所面临的挑战,一个在关键的技术点上我们的解决方案。乘客准备要出发了,他打开了我们的App,首先看到的是我们的一堆车标,有时候调头了,这是平滑移动的功能,如果是滴滴的老用户的话,应该了解到在出租车的时候,其实是没有这个功能的,打开App就看到周围有很多图标就不动了,这个功能为什么呢?是打开App的时候用户需要了解到的是周边到底有多少车?他能用哪些车?大致的情况是怎么样的?因为前期的技术原因,或者说我们要做的事情太多了,并没有把这部分做太多的优化和细化,所以对于体验的极致的追求,我们想这个需求应该是这样的,用户看到的是他能够用的这样的车,他看到这个车在这里有,一定会把这个单子派给这个司机,他一定能打到这样的车,这是所见即所得的想法!
我们面临的挑战是什么样的?我们的App一天千万次的这样被打开,我们司机的App会数百次的打开,司机的坐标上传这样的请求数是数十亿,针对司机的坐标进行检索、筛选,同时对这样的坐标我们需要是正确的,坐标系大家都了解,各种定位的原因会有很多造点,我们需要对数据进行清晰,了解到车头的方向,这都是我们要去做的东西! 我们怎么做的呢?乘客打开App,一定周期里面确切的说是5秒钟会发送一个请求,会到长链接里面,在长链接当中,他会把这个请求转发给一个平滑移动的模块!这个时候,已经返回了,这个模块会向后端进行查找,他想了解当前的地图信息,他要知道周边司机的情况!数据会通过LBS的检索模块,实现坐标信息返回,到map做数据的清洗,有的是噪点,要满足业务的需求,状态的筛选,状态的转化等。然后把相应的数据推送到我们整个的App,主要是司机的数组,会包含坐标的话,主要是它的方向、速度、精度、维度。每5秒一次的数据传输,如果数组里有新的元素产生,说明新的司机出来了,就冒出一个司机的图标出来,如果说数据变少了就消失掉,相应的方向和速度都有了。这是整个平滑移动实现的过程,它的后端数据支撑是司机上传的坐标信息,依赖的是我们的长链接服务,把坐标存储到LS的坐标里面去。
用户准备要发单了,他一按,我要用车,这时候有一个弹窗,你要加价1.2倍,或者1.5倍,用户可能有想法,用户可能有想法,怎么给我加价了?这里要澄清一下,你加价的钱是给到司机了,滴滴没有赚到这个加价的钱。滴滴虽然是出行平台,但是本质来说我们是综合交易的交易平台!我们提供一个交易引擎,更多的是希望交易更好达成。但是如果有一些经济学原理的知识的话就会了解到,其实价格才是调节市场供需的杠杆!在价格很低的情况下,乘客都愿意接受,但是司机是不愿意接活的,最后乘客愿意叫车,没有司机应答,没有促成成交,这是无效的。所以需要逐渐调整价格,达到一个平衡点,这时候乘客愿意叫车,司机愿意提供运力!正常的情况是我们对于价格的定价,但是有一些极端的情况,暴风雪天气,或者整个会场要结束的时候,大家同时要回家,需求是同时爆发的,但是供给不一定马上给上。这种情况下,我们以极端天气为例,比如暴风雪,乘客都愿意叫车,但是司机不愿意出来拉活,一个是堵车,另外暴风雪,他也希望待在家里面。这时候需要达到另外的平衡,我们逐渐的调整价格,让乘客能不能寻找到一些替代品?比如说他不再打车,他去做顺风车或者地铁,提高价格之后也会刺激司机的接单的积极性,达成新的平衡。
最后的情况这里有一堆乘客在叫单,这有几辆车,滴滴的架构系统的话,它需要做的事情是找到最合适的订单的价值!通过订单价值的识别,做好相应的调价的倍数,伺机使司机更好的接单。其中最主要的条件是怎么样找到订单的价值。对于订单价值的处理我们更多的借助我们的大数据。乘客的App要发单了,定单请求到我们的在线业务系统,把这个定单的需求专发到动态的模块,需要去参考很多的信息,这些都是我们大数据平台来提供的,当前的供给和需求是怎么样的?订单的状况?周围司机的情况?乘客相应的特征?周边司机的特征?以及我们会借助在线学习的方法来更好更快速的得到合理的定价。大家可能会好奇动态调价以后对这个平台有什么样的影响?在正常的情况下,动态条件下可以使我们的应答率提高两个点,但是应答量只有一个点。在极端的天气情况下,动态调价可以使我们的平均应答率提升10个点以上,应答量的损失只有两个点。在整个车速过程中有一个特别极端的例子,是在武汉,一次暴雨的天气动态调价没有上之前和上之后的调价是惊人的,在动调的逻辑上线之前只有53%,我们把动调的危机打开了以后成交率达到85%。这部分乘客是什么样的表现呢?被调价了以后,这些乘客更愿意留在平台!他比没有调价的用户留存率会提高17个点,这足以证明大家到这个平台上来更多的期许是能够打到车,也许会贵一两块钱,但是最重要的目的是能打到车,这是刚需,他的第一需求。
动调这个环节乘客已经把定单发出来了,订单到了整个平台这里,平台需要把整个定单分配出去,我们怎么样分配这个订单呢?这里主要有两部分会带来的挑战!怎么样找到最合适的这样的司机?把这个订单分配给他呢?另外在比较大的数据量的情况下我们怎么样保证我们分单的性能?我更多的分享我们的系统架构是怎么样的?先说挑战!在一个热点的城市,它的在线司机可能有数万这样体量,需要分配的订单可能有几千上万,针对这样的分配实际是二元组的矩阵,这个矩阵的节点数有十亿!如果是单机处理根本是没有办法处理的,所以我们价格上做了很多的重构,也做了很多版本的升级。这是整个专车的分单引擎是这样的,开始专车分单引擎之前我想说说出租车是怎么做的?专车是2014年8月份上线的产品,在这之前有一个滴滴打车的一款产品了,更多的是提供出租车的服务!我们第一版的时候是外包开发的产品,分单引擎或者模型非常的简单,一个订单来了,我们检索到周边的司机,做好分配,这个分配信息先写到数据库,司机来了以后,直接查找数据库,就能找到对应的定单信息了。这是出租车的1.0!提到这一点,更多的想说作为一个创业的企业,需要的是更快的速度,至于架构怎么用?或者说有多好?可以慢慢的来!最重要的是我们的迭代速度,在这种场景下支撑了一段时间,后来发现铁道数据库这个事情不靠谱,一个订单来了以后我直接通过步行推送出去,后面分配的效率不够高,我们需要对相应的定单和周边的司机做一个全局的优化,同时在分配效益上面能够类似于一个电梯的调度上,先聚一会,大概几百豪秒或者一秒的时间,先聚在一起,通过我们的策略进行优化订单,专车在这个模式下第一个分单引擎。
大家可以看到,司机的App通过长链接服务把它的IT信息放到我们的池子里,通过在线的系统把我们订单信息放到池子里,客户端有一个分单模块,从这个池子里取到当前的司机和订单,它会到另外一个服务,这是一个特征服务,从特征服务去取得司机和订单的特定信息。通过策略计算找到合适的订单和司机的消息然后分发出去!这都是源于我们在线系统的实时更新和大数据平台的黏性挖掘!这是专车刚上线的时候分单的架构,好处是不需要分片,单机就可以计算!随着定单量的逐渐提升,这种模式下面分单这个模块成为了一个瓶颈,为什么呢?因为它需要去池鱼里拿到ID信息,从特征服务里把每一个订单、每一个司机的特征全部拉回来,做一个矩阵的计算。计算完了以后分配出去,再把分配的结果保存下来!它能成为瓶颈。我们开始2.0的改进,2.0的时候,我们没有去调整分单,我们的想法是把分单的模块做分期部署,然后将订单和运力做一个切片,这都是在一个城市里所有的信息。
运力和定单都做了切片以后,现在性能没有问题了,但是我们会发现因为这种切片会对整个策略的分配情况是有影响的。主要还是在分片的边缘,如果是指派的情况下,我分配只能在分片里进行分配,分配的时机未必是最合适的时机,如果在这种分配的情况下造成司机并不愿意接单,如果有四个切片的话,对于我们应答率的影响是将近一个点!但是,如果把分片切成八个,我们应答率损失在三个点以上,这是巨大的损失。而且它的效率虽然提升了,但是并没有太好,如果说是有5万的在线司机和一两千的订单同时分配的话,它的分配时间大概要在2.5秒左右!这并不够高效,我们希望整个分配在1——2秒就能完成,同时支撑更大的数据量,我们探讨的是3.0的分单引擎。
大概10月份上线的分单引擎总的思路是不再做分片,把整个城市的订单和运力同时放在一个池子里,在分单的环节做分布式的计算。先从池子里把所有司机的ID和订单的ID全部拿过来做分配,分配到不同的分布式的处理器上,自己去拉取特征信息,做小的矩阵计算,所有的矩阵汇聚到一起,作为一个预算,最后得到大的预算,全局的矩阵。针对这个矩阵其实就是定单和司机二元组的关系,我们把它分配出去,分配完了以后需要将结果记录到我们的存储里面,以便于进行下一次的分配!这几个改造历时了一个半月左右,最后达到的效果还不错,如果十万个司机在线,一万的订单,我们可以在1.7秒以内把整个分配做完。
订单分配出去了,司机接单了,用户可以通过App向它行使过来,这里面的一个技术点的话,更多的是一个坐标流服务,把司机的坐标收集起来,然后给乘客一个更好的呈现。
从前面的分享中大家了解到这个数据量是巨大的,因为我们近千万的注册司机,数百万的在线情况,上传的数据量也是几十亿之多,怎么样设置这样的坐标流服务?最左边的是我们的司机端的App,分散在全国各地,接入到长链接服务,将坐标信息传递到坐标流里面,这样坐标流的模块主要是做这么四件事情;首先把坐标存储起来,在坐标存储的过程中,分为持久存储和缓存,持久存储做后面大数据挖掘和客户查询相应的坐标轨迹,在线的时候考虑到性能来存储的。
乘客在上传坐标的时候需要了解司机的坐标,所以整个后端会维护着司机和乘客的对应关系,当乘客上报坐标的时候就能知道司机的坐标,司机上传坐标的时候就了解乘客的位置,地址围栏是我们做营销活动的时候,你要去机场给你派一个机场券,接送机的券,再做活动,针对活动的人群做特殊的撤销。
在业务场景上面还会有一些特定的需求,往往是需要将一些业务状态,通过坐标流给带回来,这是整个坐标流服务。地理围栏是判定一个围栏形成一个事件,会放到消费队列里共各个业务方去调阅,随着坐标流的上传,带上业务状态,把这样的业务状态同样放到消费队列中,谁感兴趣就去订阅。
坐标还会被LBS这样的检索服务器定位,最终存储到我们的LBS这样的服务里,它是为了支持多个页面查询的场景。我们LBS空间检索这块大致是这样做的,坐标上传的时候有一个请求,会到Perc这个层面,这是写的请求,查询的请求的时候同样是经过perc这个层面定位到存储切片,保存的数据信息其实就是坐标一些业务状态的编码信息,它的数据结构是一个跳表,支持读写的并发处理,可以支持我们的节点的超时管理。由于整个数据可以放在内存是安全处理,相应的扩展性、各方面都挺好的。在五公里的范围内,如果节点密度超过几万的话,我们一次查询时间在一毫秒就可以完成。
整个检索服务的集群可以承载的数据节点可以超过一亿点。最后说到地理围栏的服务,往往做活动的促销或者营销事件的时候做一个响应。地理围栏我们是这样做的,是让运营的同学他们去有一个地理可以自己去自定义画一个围栏出来,在围栏边上设一个预警的区域,通过整个坐标流服务当中去触发一些事件来告知真正的在线系统去调用!
有这样的一个场景,我们要针对北京机场的用户去派一张接送机的券!乘客如果在机场的话就可以消费这张券你会怎么做?首先运营的同学围着手机机场画一个圈,然后会设定外面预警的圈。等到坐标上传的过程中,这个地址围栏服务是否进入这样的围栏圈?是否到了一个预警区?到预警区的时候写一个事件放到消费队列里面,业务系统订阅了这个消息,就知道这个时候乘客已经到了首都机场周边500米了,这个时候会触发一个行为,不管派一张券还是发一个短信还是弹窗提醒?告诉我们的用户我们有这样的活动,或者这样的促销!真正到了围栏的时候,是另外一个事件,只有在围栏里面才允许他使用这样的券,这也是基于反作弊的考量。
我们整个围栏的话,可以是这样的功能,自定义的多边形和行政区域任意的组合形成围栏,针对围栏可能有几千几万几百万这样的围栏,一个坐标来了之后我需要知道到底属于哪个围栏?需要做一个预盼和筛选!我们的做法是这样的,针对围栏区域设置内聚型和外聚型快速判定他是否属于这个围栏,从而优化我们查询的速度!关于围栏内部的监测是基于一个比较常规的方法,针对多边形的边区引入一些射线出来,判定这个射线的焦点是奇数还是负数,当前我们单机实力可以支撑水平的扩展。
司机到达以后,接到乘客,点开实际价,计价开始,在计价的环节,我们更多面临的挑战是在于到底怎么去计价?怎么样把价格记的更准确?这是在出租车时代没有的挑战!因为出租车有一个计价器,不需要记价,到终点的时候司机告诉你是十块还是二十块,大家直接拿出微信支付或者支付宝直接支付就完了!再不计线下支付就完了,专车的时候就是挑战,首先不能线下支付,没有记价器了!这个计价怎么办?在8月份的时候产品要上线,我们面临的挑战是到底用乘客端、司机端上计价还是怎么样?考虑到相应作弊的行为以及定价的灵活性,我们选择了计价,GPS芯片很差,被安全软件拦截了没有办法进行上传和定位,上传的数据质量也不是太高,精度问题和定位漂移问题,尤其是一辆车停下来以后,整个坐标上传的结果在周边不停的跳动!还有移动网络的不可靠,到地下通道的时候没有网络了,坐标没有办法上传!这都是针对计价准确性的挑战。
针对产品的形态在我们的场景里都有快车、专车!还有企业用车,根据不同的时段计价又不一样!他去机场和火车站定价又不一样,这是产品形态的多变,会在灵活性和对于整个架构和复杂度带来的提升。对于灵活性的事情,大概是这样的,司机端每一秒会去做定位,十秒形成一个包,将这个包通过长链接的服务上传上来,上传到实时计价模块,需要解决两个事情,一个是降噪,另外是补偿器。整个坐标的方向。在30米以内我们会采用这个点,如果精度在30米以外我们会抛弃掉,会通过地图的API的接口做数据补偿!经过模块处理了以后,这基本上是一个比较准确的数据线路,我们还需要去防范做反作弊处理。在反作弊的环节会考虑这样的事情,司机的历史信用是什么样的人?是不是经常作弊的人?司机和乘客的路线是否有重合?是不是靠这种模拟器去定位的虚假信息?最后做全网的数据校对!这样得到的数据通过和出租车计价器这样的比较,我们有一个好处,是在专车上线的时候出租车已经有很大的体量了,而且出租车的数据是依赖出租车计价数据来的,是比较准确的数据!我们计价系统和出租车计价进行对比,有一两个点的不那么准。坐标流服务我们有离线的价格追诉这样的环节,如果四层之间产生的纠纷,出现了问题,我们依赖这样的一套体系是可以判定到底谁在说谎!去完成一个客诉的问题。这是在解决计价准确性的点上。关于计价系统的灵活性,更多的是依赖规则引擎,它是通过一条规则,在规则引擎里进行解析,最后得到一个结果,针对我们各种各样的活动,不同的产品形态,还有不同的乘客的画像,这次出行的起点在哪里?终点在哪里?什么时候出发的?多个维度定义出一条规则来?通过规则引擎做解析以后得到一个计价ID,这就确保了一个计价的灵活性。
计价完了乘客可以选择多种支付渠道、支付宝和手Q、微信支付、待充值这样的支付方式,这次出行就结束了。这是当前针对出行过程中的核心系统的概况。我们以后要做一些什么东西呢?我们接下来或者当前比较急迫的是需要进行跨机房的过程,它面临的问题是网络、机房可能不靠谱,一旦建筑工人一铁锹挖下去光缆就断了,我们在10月份的时候就有过一次机房的网络瘫痪了,终止服务了一段时间。针对整个跨机房的解决方案,我们构想是这样的,前面有一个Proxy来解决,到底是机房1还是机房2,北京是一个围栏,上海是另外一个围栏,北京部署在机房1,上海部署在机房2。对应着这样的部署。所有的业务流程往走,但是到存储节点的时候,会把数据信息囤到相应的机房。这是我们急切或者正在做的动作。
另外是关于自动化运维平台的构想!数据收集平台会收集各种各样的数据信息,全部收集起来,它就形成了数据支撑,在自动化的运维平台里要去关注对于机器的管理,对于预警的处理和容量的管理,以及容灾处理。容量的管理这一部分更多的是为了应对我们不定期的促销活动,可能一个决策信息或者是一次快乐周末的大促,我们需要评估当前的容量是否能够支撑?有一个容量的评估模型?快速的判定哪些模块需要改造的?哪些需要扩容的?经过自动化部署把扩容这个事情做了,针对线上出现的灾难,比如光缆被建筑工人刨断了,有相应的降低预案,通过监控的处理和预制判断,制度的流程和平台的切换,最终会产生一个解决方案,通过配置和更改的方式,影响到了我们在线业务系统。
最后给大家分享一个比较好玩的东西,我们发现司机在不断的上传他的坐标,司机的坐标流是三秒一次,只要他在线,这个坐标就会不断上传,这个时间轴上,在这个时间轴上去加入一些事件会怎么样?司机当前是出车了还是收车了?是否在接单?他是否已经到达了乘客的位置?这样的状态信息能够覆盖就形成了数据流,每一个司机都是这样的信息。有了这样的流以后,任何一个查询过来我就知道司机当前是在什么样的位置?它的历史轨迹怎么样?历史状态是怎么样的?当订单需要分配的时候,我们的乘用模块通过检索找到一个时间切片,当前这个时间切片或者司机是空闲的做一些筛选就可以完成自己的订单分配。
更多精彩内容,请关注新浪微博:@CSDN、图文直播专题:2015中国软件开发者大会。