基于AIGC的写作尝试:Presto: A Decade of SQL Analytics at Meta(翻译)

2023-04-19 11:47:40 浏览数 (3)

ABSTRACT

Presto是一个开源的分布式SQL查询引擎,支持多个EB级数据源的分析工作负载。Presto用于低延迟的交互式用例以及Meta的长时间运行的ETL作业。它最初于2013年在Meta推出,并于2019年捐赠给Linux基金会。在过去的十年中,随着Meta数据量的超级增长以及新的SQL分析需求,维护查询延迟和可扩展性对Presto提出了令人印象深刻的挑战。其中一个最重要的优先事项是确保查询可靠性不会随着向更小、更弹性的容器分配的转变而退化,这需要查询在显著较小的内存余量下运行,并且可以随时被抢占。此外,来自机器学习、隐私政策和图形分析的新需求已经促使Presto维护者超越传统的数据分析。在本文中,我们讨论了近年来几个成功的演变,这些演变在Meta的生产环境中将Presto的延迟和可扩展性提高了数个数量级。其中一些值得注意的是分层缓存、本地矢量化执行引擎、物化视图和Presto on Spark。通过这些新的能力,我们已经弃用了或正在弃用各种传统的查询引擎,以便Presto成为为整个数据仓库服务的单一组件,用于交互式、自适应、ETL和图形处理工作负载。

CCS CONCEPTS

(ACM Computing Classification System Concepts)

  • Information systems → Database query processing;
  • Parallel and distributed DBMSs;
  • Online analytical processing engines.

KEYWORDS

Data Warehouse, Presto, OLAP, SQL, Distributed Database, Data Analytics, ETL

INTRODUCTION

Presto是一个开源的分布式查询引擎,自2013年以来一直支持Meta的生产分析工作负载。它提供了一个SQL接口,用于查询存储在不同存储系统上的数据,例如分布式文件系统。自2019年捐赠给Linux基金会以来,Presto在美国科技行业领袖中的使用和贡献持续增,包括Uber、、Intel、Ahana等。在捐赠后,Meta仍然积极参与Presto的贡献,50%的提交来自Meta。Meta的Presto部署也在顶级分支上,以确保每个版本都在Meta规模上进行了测试。

在Meta内部,Presto用于大规模的交互式、自适应和提取转换加载(ETL)工作负载。使用案例包括仪表板、A/B测试、自适应分析、数据清理和转换。随着将所有SparkSQL工作负载迁移到Presto,Presto将很快成为公司仓库的唯一SQL接口。

虽然Presto最初是为交互式SQL查询的纯内存处理而设计的,但Meta的各趋势挑战了它的能力。由于其效率,员工开始将其用于运行长达数十分钟的轻量级ETL工作负载[44],随着数据呈指数级增长,Presto变得越来越慢。向更灵活和弹性的资源管理模型的转变,使用更小、短暂的容器,导致可靠性降低。此外,随着对更丰富的分析需求的增长,例如机器学习特征工程和图形分析,它们得不到很好的支持。最后,遵守Meta的数据隐私政策需要新的数据抽象和数据存储机制,以有效支持隐私策略执行。本文的主要重点是描述我们如何改进Presto的架构,以应对这些挑战,从以下三个方面说明。

首先,延迟和效率。随着数据量的增加,相同查询的扫描成本增加,导致等待变长。由于集群中机器的RPC连接数量不能无限增加,添加更多机器到集群中会达到一个极限。此外,使用更多机器本质上增加了单个机器故障的可能性。其他延迟改进,以保用户可以在大规模可扩展数据扫描的情况下仍然具有低延迟的仪表板体验。特别是对于重要的仪表板,用户希望Presto表现得好像数据已经被裁减或存储在内存中,可以任意切片和切块。

其次,可扩展性和可靠性。SQL是Meta ETL工作负载的首选,这推动了Presto的流行。由于Presto不提供容错性,并且硬件限制了内存,因此需要新的方法来支持比Presto当前支持的CPU、内存运行时间重得多的ETL工作负载[44]。此外,Meta已经调整了容器分配,使其具有更弹性的可管理性和更小的内存占用。弹性允许更灵活的容量来平衡公司中不同类型工作负载的高峰和低使用然而,它也带来了一个复杂的挑战,因为机器可能会任意宕机。在这些限制下需要新的设计原则来扩展工作负载,以处理任意大的内存消耗和任意长的运行时间,同时具有不稳定的基础架构。

最后,需要超越数据分析的要求。现代仓库已经成为数据湖,以根据不同用例的需求允许数据使用。一个典型的用例是机器学习特征工程。Meta的机器学习相关数据量已经超过了分析。机器学习工程师利用像Presto或SparkSQL这样的分析引擎从原始数据中提取特征,用于训练目的。隐私政策是另一个重要的要求。Facebook、Instagram和WhatsApp用户可以选择退出个人数据用于内容推荐或Meta已经收集的任何其他数据用例。Presto正在确保数据得到适当的保护。此外,Meta关注社交图谱。我们已经看到用户要求通过Presto进行类似SQL的图分析,以表达具有数十亿个节点和边的复杂逻辑。

本文的其余部分结构如下。第2节概述了Presto的原始架构以及在过去几年中在Meta的架构基础上面临的挑战。第3、4和5节分别介绍了Presto的演变,以改善延迟、可扩展性和效率。第6节讨论了机器学习、隐私和图形分析等领域,以说明用户如何利用Presto作为引擎来操作Meta仓库数据,进行更丰富的分析。第7节演示了这些演变如何帮助提高在Meta规模下生产数据的性能。第8节讨论了这个领域的相关工作,第9节总结了剩余的挑战和计划的工作来解决它们。我们在第10节的结论中强调了本文讨论的改进以及我们弃用各种引擎,使Presto成为我们仓库的核心。

ARCHITECTURE AND CHALLENGES

Meta在2022年拥有21个数据中心[12],每个数据中心的面积都是数百万平方英尺。Meta的数据仓库在这些数据中心中拥有大量存储空间。绝大多数Meta员工每天都直接或间接地使用Presto或其他工具访问这些数据。

随着Meta仓库数据呈指数级增长,Presto面临各种困难,以保证用户具有相同的延迟和可扩展性体验。随着扫描变得更大,仪表板变得更慢,用户开始利用内存或共存存储计算引擎[40,44]以获得更好的性能。在ETL方面,更可扩展的引擎,如Spark [57],被视为首选,因为内置的容错性可以保证长时间运行的作业即使容器崩溃也能完成。使用弹性容量的不断增长趋势需要以更高的频率分配和取消分配容器。今天,没有保证一个容器可以连续几个小时专用于Presto集群。Presto的原始架构采用分离的存储和内存处理,只能最优地处理运行几秒钟到几分钟之间的查询。随着Presto需求超出其原始要求,我们设计了方法来使Presto本身演以克服所面临的挑战。

Figure 1: Original Presto architectureFigure 1: Original Presto architecture

图1说明了Presto集群的原始架构[44]。它由一个协调器和数千个可扩展的工作节点组成。协调器负责排队和解析查询字符串,然后将其转换为计划。计划将应用优化,并根据shuffle边界分成计划片段或简单片段。这些片段将并行地调度到工作节点上。工作节点负责使用内存中的所有数据进行查询处理,并通过网络上的流式RPC进行数据Shuffle。每个工作节点将启动任务来处理接收到的片段数据。处理后的数据将被洗牌到不同的内存缓冲区中,等待不同的下游任务获取。一个集群可以同时运行多个查询和它们的任务,具有完全的多租户共享内存、IO、网络和CPU。Presto还支持存储连接器,允许扫描异构数据源进行相同的查询。

正如我们从原始架构中可以看出的那样,由于外部存储与计算引擎分离,延迟可能会受到IO的瓶颈限制。此外,所有工作节点目前都是用Java编写的,这在程序上比没有对内存分配进行精细控制的本地代码慢。存储连接器也成为一把双刃剑:为了支持低延迟的仪表板,像Raptor [44]这样的系统被构建为使用专门类型的机器将仓库数据转储到本地内存或磁盘中,以便仪表板可以更快地加载。共存存储不仅引入了数据管理开销,而且也减少了存储和计算的独立扩展的好处。

Figure 2: New Presto architectureFigure 2: New Presto architecture

从可扩展性的角度来看,协调器作为单点故障和工作节点缺乏容错能力的问题随着数据增长以及弹性容量的引入而被放大。内存处理设计也定义了系统可以容纳多少数据的上限。基于网络的Shuffle由于连接限制无法扩展到数千个工作节点以上。

除了延迟和可扩展性方面的挑战之外,以机器学习为重点和以隐私政策为重点的不断增长的趋势逐渐将传统的面向分析的数据仓库转变为更开放和灵活的“数据湖”设置。分析数据不再是不可变的。Meta需要有能力根据用户的隐私选择删除用户数据。在机器学习特征工程期间,还可以高度灵活地添加列以尝试不同的候选特征。

在本文的其余部分,我们将讨论在Meta成功推出的几个Presto演变,以解决上述挑战。其中一些改进在我们的prestodb博客[1、8、17、29、37、54、55]中有更深入的讨论。图2说明了新Presto架构的高级想法。当一个查询被发送到Presto集群时,它可以在以下两种设置中的任何一种上运行:(1)原始的Presto架构,但具有多个协调器以避免单点故障,本地矢量化执行以提高性能,闪存数据缓存以避免IO瓶颈,以及许多其他将在本文中讨论的改进;或者(2)Presto on Spark,利用Spark作为运行时,Presto作为可扩展性的评估库。在这两种设置中,我们提供了物化视图来提高查询性能,并为机器学习特征工程和隐私用例提供数据可变性。此外,这两种设置都可以将内存中的数据溢出到临时存储中,以克服内存限制。原始的Presto架构现在也增强了可恢复性,以物化中间数据。另一方面,Presto on Spark设置利用临时存储进行洗牌。还引入了额外的元数据。类型存储用于支持用户定义的类型,函数存储用于支持SQL函数编写和评估,统计存储用于更好的优化决策。远程函数用于运行用户定义的函数。

LATENCY IMPROVEMENTS

随着数据的增长,查询延迟自然会受到降级的影响。本节介绍了几个增强Presto的方法,以从CPU、IO和内存的角度改善延迟。

Caching

分离的存储使得扩和独立计算成为可能。然而分离引入了新的查询延迟挑战,因为在网络饱和时通过网络扫描大量数据甚至元数据可能会受到IO限制。为了解决这个问题,我们在各个层面引入了缓存。在本文的其余部分,我们使用文件的概念来表示物理存储在远程存储中的数据切片。

原始数据缓存:工作节点上的本地闪存设备上的数据缓存可以帮助减少从远程存储节点读取数据的IO时间。Presto工作节点在读取时将远程数据以其原始形式(压缩和可能加密)缓存在本地闪存中。如果将来有一个读取请求覆盖了可以在本地闪存中找的范围,请求将直返回结果。缓存单元的大小是对齐的,以避免碎片化。例如,如果一个读取请求覆盖了范围2.3MB,4.5MB),Presto将发出范围[2MB,5MB)的远程读取,并为[2MB,3MB)、[3MB,4MB)和4MB,5MB)的块缓存和索引。对于任何来与[2MB,5MB)范围重叠的读取,重叠部分将直接从本地磁盘获取。这些缓存单元的驱逐策略是LRU(最近最少使用)。

片段结果缓存:此外,正在运行叶子阶段的任务(负责从远程存储中拉取数据的任务)可以决定在本地闪存缓存部分计算结果,以防止在多个查询中重复计算。一典型的方法是在具有一级扫描、过滤、投和/或聚合的叶子阶段上缓存计划片段结果。例如,用户可能决定查询过去1天的报告聚合结果。稍后,他们可以调整仪表板以查看过3天的聚合结果。然后对于第二个查询,我们可以通过缓存来防止第一天的重复计算。只有剩余的2天数据需要扫描和部分聚合。

请注意,片段结果基于叶子查询片段,这可能会因用户调整过滤器或投影而高度变化。为了在用户频繁更改过滤器或投影时最大化缓存命中率,我们依赖基于统计的规范化。规范化首先执行从不同变量名称到固定名称的同构映射,以便具有相同含义的不同别名的查询最终具有相同的计划。然后,它对表达式进行排序,以便像

0 人点赞