在优步,我们使用数据分析在我们的产品中构建更神奇的用户体验。只要有可能,我们就利用这些数据工程能力,使我们的合作伙伴能够更好地为客户服务。例如,在2016年底,UberEATS工程团队建立了一个全面的分析仪表板,为餐厅合作伙伴提供有关其业务健康状况的额外见解。
该解决方案必须能够从实时、细粒度、高可用性和可靠的数据管道中收集见解。(报告的净支出相差哪怕一分钱都是不可接受的,更不用说支持的噩梦了。)我们需要一个渠道,可以为数万家餐厅提供多个垂直领域的数据洞察,并有潜力扩展到数十万家甚至更多。
于2017年3月推出,餐厅经理是一个全面的分析仪表板和管道,我们的餐厅合作伙伴。在本文中,我们将讨论如何构建这个分析平台及其健壮的数据管道。
餐厅经理背后的秘诀
我们的餐厅合作伙伴最突出的要求之一是更深入地了解他们的业务,这可以通过定期的调查和访问来体现。我们的解决方案?Restaurant Manager是一个分析仪表板,他们可以利用UberEATS的数据来改善他们在UberEATS上的业务以及内部业务。
在与我们的合作伙伴进行了彻底的用户研究后,我们确定了一组最初的雷竞技是骗人的核心指标:净支出、每日和每周销售的商品、订单接受率、订单准备速度和商品评级(“赞”或“赞”,表示客户满意度)。一旦我们综合了我们的发现,我们将这些指标分为三大类数据:客户满意度、销售额和服务质量。
设计一个美妙的用户体验
考虑到这些核心指标和三个类别,我们构建了用户友好的Restaurant Manager:
客户满意度
在我们的客户满意度门户网站上,我们提供对客户满意度的洞察。为了衡量这一点,我们在其他指标中汇总了用餐评分和分类反馈。通过了解顾客的满意度,餐馆可以有针对性地改进,从而更好地为顾客服务。
销售
在我们的销售门户网站上,我们提供了一个窗口,让您了解餐厅在UberEATS应用程序上的财务表现。实时净支出、销售项目和最畅销菜肴等指标,对于餐厅老板在制定菜单和确定营销策略时都是有用的信息。
服务质量
最后,通过我们的服务质量门户网站,我们向餐厅展示订单接受率、食物准备时间和菜单可用性如何影响客户满意度。通过向餐厅提供这些数据,我们可以帮助他们实现收入最大化,优化食客体验。
接下来,我们将研究一个餐厅经理用例,以更好地描述餐厅合作伙伴如何从该工具中受益。
餐厅经理案例分析:潜在收益
通过餐厅经理,餐厅合作伙伴可以了解他们的潜在收入。前提很简单:当餐厅合作伙伴在营业时间内拒绝接受订单时,我们捕获订单的价格并将其显示在restaurant Manager仪表板上,如下所示:

然而,这个方程的实现有点复杂。为了获得完整的潜在收益图,我们将来自不同服务的多个数据流合并并处理成最终结果,并按餐厅位置分组。
在下一节中,我们将剖析餐厅管理架构,这是一个强大的可扩展系统,利用了Uber现有的许多数据处理服务。
餐厅经理架构
平台的体系结构依赖于黑比诺,一个开源的在线分析处理(OLAP)数据存储,为我们的分析仪表板填充几乎所有数据。Pinot支持接近实时的表摄取,对相对较大的数据集提供类似sql的查询支持,非常适合低延迟、高每秒查询(QPS)和可扩展的分析查询。Pinot还支持在线数据加载(例如:卡夫卡流)和离线(例如Hadoop作业)源,如下所示:
在线数据摄取管道
该实时工作流可分为四个阶段:
- UberEATS服务,包括我们的餐厅账户管理、工作流管理和评级服务,将捕获用户与UberEATS系统的交互,并将数据转储到Kafka流中。
- 流作业连接来自多个Kafka流的事件,然后转换和聚合它们,最后将装饰事件生成到不同的Kafka流中。
- Pinot使用Kafka流中的数据,存储数据,并为高效查询创建索引。
- Restaurant Manager向Pinot查询具有高QPS的新鲜数据,Pinot以低延迟交付结果。
流作业将UberEATS订单的状态更改和UberEATS订单维度事件连接起来,然后将未接受的订单(以及餐厅合作伙伴可能从接受这些订单中获得的潜在收益)发布到Kafka流中。我们使用优步的流分析平台AthenaX使用以下SQL实现流作业:
Pinot使用流并使用以下模式构建表:{restaurantUUID字符串,jobUUID字符串,skuName字符串,price double, currency字符串,dateStr字符串}.
使用这个模型,当餐厅合作伙伴想要知道他们在特定时间段内的潜在收入时,前端服务将发送如下所示的皮诺查询:
选择和(价格)
从potential_earnings
WHERE restaurantUUID = " ?和dateStr之间(?, ?)
脱机数据摄取管道
经过实时处理后,所有UberEATS业务事件将通过提取,转换,加载(ETL)协议移动到HDFS,并在蜂巢查询。Hive表的新鲜度取决于ETL管道的速度,通常需要几个小时才能完成。为了解决可能的数据收集问题,我们将离线工作流调度为Oozie来回填Pinot离线服务器上的数据。离线管道包括Hive,火花Oozie和Pinot。
Hive上的数据被用作真相来源,但只能在事件发生后24小时内使用。为了满足这个紧张的时间表,我们安排了Oozie作业来每天追加和更新Pinot离线表。将数据从Hive移动到Pinot有三个步骤:
- 通过Spark作业查询Hive,然后将查询结果转储到AvroHDFS上的文件。
- 运行Spark作业,从第一步创建的Avro文件中生成Pinot索引段(Pinot数据存储单元)。
- 将这些片段推到皮诺集群中。
查询服务
一旦上了皮诺,我们的UberEATS事件就可以存储和处理了。如上面的图2所示,Pinot REST代理、Pinot代理和Pinot实时/脱机服务器是查询服务的主要组件。
Pinot查询首先被发送到Pinot REST代理,该代理负责查询路由和负载平衡。我们的Pinot REST代理将根据数据源将查询路由到相应的Pinot代理。然后,Pinot Broker对查询进行时间分区,将查询分散到相应的服务器,并收集结果。Pinot服务器存储和索引数据,并回答具体的查询。
体系结构的性能
在本节中,我们将详细介绍用于测量基于pinot架构的性能的主要指标,包括吞吐量、延迟、可伸缩性、可靠性和工程安装时间。对于我们的性能基准,我们设置了三个24核和128GB RAM的在线服务器。
吞吐量和延迟
经过全面的测试,我们确定在数据摄取阶段,Pinot可以以每个线程每秒20,000条消息的速度从Kafka摄取查询。
为了确保我们可以服务所有用户,我们必须保证当QPS上升时,Pinot仍然可以在SLA内响应。为了保证水平可伸缩性,我们还测试了以不同速率处理查询的延迟。使用1,000个QPS,三个Pinot服务器仍然可以以低于100毫秒(ms)的99%的延迟回答查询。
可扩展性和可靠性
因为Pinot是水平扩展的,所以我们可以向租户添加更多硬件来扩展集群。目前,Pinot为Uber面向用户的分析平台提供99.99%的可用性服务。
工程入职时间
使用我们的端到端流分析架构,我们已经在我们的平台上缩短了一个工作或表的平均工程时间,从几周缩短到几小时。
数据呈现
为了将系统捕获的数据以一种高效且易于导航的方式呈现给我们的餐厅合作伙伴,我们利用了反应作为我们视图层和的基础回来的作为我们数据层的基础。这些选择很容易做出,因为Uber的大部分网络工程生态系统都是用React构建的,多个团队为其他团队提供可重用的组件。
在探索了许多不同的图表呈现选项之后,我们选择了Recharts,一个简单而强大的声明性组件库,用于为我们的仪表板生成图表D3.js图书馆。数据呈现的前提很简单:客户机对节点每个分析部分的服务器,然后将请求代理给Pinot;一旦数据返回给客户端,它将被调整为Recharts可使用的格式,并在页面上呈现。结果是一个干净和交互式的UI,使其易于理解和应用我们的分析。
构建优步分析的未来
通过餐厅管理和其他工具,优步工程的流分析和UberEATS团队正在构建可扩展的实时分析解决方案,为我们的餐厅合作伙伴收集可操作的商业见解。如果您对构建优步的下一代分析平台感兴趣,请访问我们的网站数据平台/基础设施工程职位空缺.我们也有开放的角色在构建我们当前平台的UberEATS工程团队中。
通过观看下面的视频了解更多关于餐厅经理的知识:
樊静(Jing Fan)和付翔(Xiang Fu)是Uber流分析团队的软件工程师。法伊兹·阿巴西(Faiz Abbasi)是UberEATS餐厅体验团队的软件工程师。UberEATS餐厅体验团队的工程经理Jonathan Chao也对本文有贡献。










