Uber平台上数百万次乘车和送餐服务所涉及的数据不仅促进了交易,还帮助Uber团队不断分析和改进我们的服务。当我们推出新的服务时,我们可以快速衡量成功与否,当我们在数据中发现异常时,我们可以快速寻找根本原因。
我们的数据仓库团队负责为日常运营分析提供这些数据,并在Vertica(一个流行的交互式数据分析平台)上维护一个大型并行数据库。每天,我们的系统处理数百万个查询,其中95%的查询在15秒内返回响应。
迎接这一挑战并不容易,尤其是考虑到优步多年来的乘车量和送餐量呈指数级增长。这个系统不断增长的存储需求使得我们最初的策略是添加完全复制的Vertica集群来增加查询量的成本。
通过我们的数据仓库和数据科学团队的联合力量,解决方案应运而生。通过成本分析,我们的数据科学家帮助数据仓库工程师提出了部分复制Vertica集群的方法,以更好地扩展数据量。以这种方式优化我们的计算资源意味着我们可以扩展到目前的速度,在我们的平台上服务超过10亿次旅行,从而改善全球的用户体验。
查询量的伸缩性
在Uber快速发展的最初阶段,我们采用了一种相当常见的方法,即安装多个独立的Vertica集群来处理每天数百万的分析查询。这些集群是彼此完全隔离的镜像,提供了两个关键优势。首先,它们为集群故障提供了容忍度,例如,如果集群故障,业务可以照常运行,因为备份集群拥有所有所需数据的副本。其次,我们可以将传入查询分布到不同的集群,如下面的图1所示,从而帮助增加可以同时处理的查询量:
由于数据存储在多个孤立的集群中,我们研究了平衡查询负载的策略。我们发现的一些常见策略包括:
- 随机分配:随机地将传入查询分配给集群,假设随机化将自动产生均衡的负载。
- 用户分类:将用户分配到不同的集群,这样来自给定用户的所有查询都只定向到指定的集群。
- CPU平衡:跟踪不同集群的CPU使用情况,并将查询分配给CPU使用情况最低的集群。
依赖具有路由层的多个完全隔离的集群来在集群级别强制执行用户细分带来了管理这些数据库集群的挑战,以及跨每个集群复制每个数据块相关的存储效率低下。例如,如果我们将100 pb的数据复制6次,则总数据存储需求为600 pb。复制的其他挑战也很明显,比如与写入数据和创建与增量数据更新相关的必要投影和索引相关的计算成本。
这些挑战由于我们在全球的快速增长以及对食品配送、货运和共享单车等新业务的涉足而进一步加剧。随着我们开始将越来越多的数据输入Uber的数据仓库,以支持我们不断增长的业务需求,Vertica将计算和存储结合在单独的机器上,这意味着支持业务所需的硬件数量也相应增加。从本质上讲,我们将为增加存储而支付硬件成本,而不会增加查询量。如果我们选择添加更多的集群,复制过程中隐含的资源浪费将意味着实际查询量不会线性增长。在资本配置和性能方面,效率的极度缺乏意味着我们需要跳出固有思维,找到一个可扩展的解决方案。
将数据科学应用于数据基础设施
考虑到Uber在数据科学方面的专业知识,我们决定应用该领域的原则来优化我们的数据基础设施。我们与数据科学团队密切合作,开始为我们的快速分析引擎提高查询和数据量的可伸缩性。
克服存储挑战的自然策略是从完全复制的数据库转移到部分复制的数据库。如下图2所示,与完全复制的数据库系统(其中所有数据都复制到所有隔离的数据库集群)相比,部分复制的数据库系统将数据划分为不同的重叠数据元素集,这些数据元素集与集群的数量相等:
由于问题的规模很大,涉及数千个查询和数百个表,因此构建这些不同的重叠数据元素集并非易事。此外,部分复制策略通常是短期的,因为数据元素以不同的速度增长,并且这些数据元素随着业务的发展而变化。除了考虑数据库可用性、计算和存储可伸缩性之外,我们还必须考虑部分复制数据库的迁移成本。
考虑到这一数据基础设施的挑战,我们的数据仓库和数据科学团队为我们的最佳解决方案提出了三个基本要求:
- 最小化整体磁盘空间需求:正如上面所述,我们的快速增长意味着我们现有的添加完全复制集群的策略并不有效。任何新的解决方案都必须能够使我们的存储更加密集,并有效地利用资源。
- 集群间均衡磁盘使用率:理想情况下,我们希望每个集群中所填充的磁盘空间几乎相同。假设所有集群中的数据以相同的速度增长,这是可取的,因为它可以确保没有一个集群先于其他集群耗尽磁盘空间。
- 在集群间平衡查询量:在优化磁盘空间的同时,我们还希望确保在集群之间均匀地分配查询量。如果忽略这一点,我们可能会遇到所有查询都路由到单个集群的情况。
我们的数据科学团队将这些需求形式化为一个成本函数,可以描述为:
下面是对上述方程中三个变量的简要描述,更详细的讨论可以在我们的论文中找到,临时部分复制数据库.
- 年代的最大存储利用率描述为NVertica集群。存储利用率是存储在单个集群上的数据元素与数据元素总大小的比率。例如,如果存储在Vertica集群上的数据元素的总大小为60 pb,对于给定的部分候选配置,所有数据元素的总大小为100 pb,那么存储利用率将为0.6
- l的最大计算利用率描述为NVertica集群。计算利用率则被描述为给定集群可以处理的查询量的百分比。
- 米描述为跨越的最大迁移成本NVertica集群。如上所述,使用部分复制数据库的挑战之一是,由于不同数据元素的增长速度不同,以及业务提供的服务和产品的性质不断变化,最优的部分配置最终会变成次优配置。因此,复制的数据库通常必须重新配置。这种重新配置需要将数据元素从一个数据库移动到另一个数据库,从而消耗计算资源。理想情况下,我们更喜欢将迁移成本最小化的配置。与数据库集群相关的迁移成本被描述为将从数据库的给定状态复制到同一数据库的新状态的新数据元素的数量。
为数千个表和数百万个查询最小化上述代价函数是一项艰巨的任务。根据经验观察,我们的数据科学团队发现,10%的最大表占据了大约90%的磁盘利用率。因此,大多数磁盘空间效率将通过仅10%的表的优化配置来实现。
专注于这些表可以显著减少优化所需的决策参数的数量。此外,我们的数据科学团队开发了一种算法,通过贪婪地将表和查询分配给成本最低的集群,有目的地生成次优解决方案。与最优解决方案相比,这种贪婪算法减少了5%的磁盘节省,速度明显更快,在几分钟内完成。我们决定生产这种算法,以提高速度而不是磁盘使用率。
一旦我们解决了数据科学问题,下一步就是解决工程挑战。为了支持部分复制,我们必须显著增强两个组件,代理管理器和数据管理器,如下所示:
- 代理经理:使用完全复制的Vertica数据库,代理管理器在客户端与其对应的数据库之间提供了一个瘦抽象,同时还充当了负载平衡器。所有传入查询都通过该层路由,该层了解查询负载、数据位置和集群运行状况,以确保每个查询都路由到能够处理它的集群
- 数据管理:第二个组件是数据管理器。在完全复制的世界中,所有数据都从上游数据湖复制到所有可用的Vertica数据库。但是,在我们提出的设计中,每个数据元素根据部分配置被复制到不同的数据库。数据管理器保存有关哪些集群需要将哪些表加载到其上的信息,并将与代理管理器共享此信息。
有了所有这些组件,我们的解决方案能够显著降低30%以上的总体磁盘消耗,同时继续提供相同级别的计算可伸缩性和数据库可用性。在查询量增长的情况下,所实现的节省降低了硬件成本,并确保我们能够在集群间均匀地平衡负载。对于使用这些数据的Uber内部团队来说,这种负载平衡意味着提高了正常运行时间,因为所有查询总是指向最健康的集群,并减少了故障etl.
建设智能基础设施
在这个项目上,我们与数据科学团队密切合作,展示了机器学习和数据科学的力量如何被注入到数据基础设施世界中,并被用来不仅对Uber的业务产生有意义的影响,而且对Uber内部成千上万的用户产生有意义的影响,从人工智能研究人员到城市运营经理,他们依赖我们来推动洞察收集和决策。雷竞技是骗人的这个项目的成功促进了我们的基础设施和数据科学团队之间更深入的合作,并导致了一个新的智能基础设施团队的发展,以重新思考大数据应用的基础设施设计。
如果你有兴趣和我们一起工作,我们将建立一个数据驱动的平台,推动世界的发展,来加入我们的团队吧!






