帮助 Meta 解决 Presto 中的数据孤岛问题

本文转载自 InfoQ 官网
作者:Alluxio-钟荣荣;Meta-James Sun & Ke Wang

Raptor 是用来支持 Meta(以前的 Facebook)中的一些关键交互式查询工作负载的 Presto 连接器(presto-raptor)。尽管 ICDE 2019 的论文 Presto:SQL on Everything(https://research.facebook.com...)中提到过这一特性,但它对于许多 Presto 用户来说仍然有些神秘,因为目前还没有关于此特性的可用文档。本文将介绍 Raptor 的历史,以及为什么 Meta 最终替换了它,转而采用基于本地缓存的新架构 RaptorX。

帮助 Meta 解决 Presto 中的数据孤岛问题_第1张图片

Raptor 简介

一般来说,Presto 作为一个查询引擎并不具备存储空间,因此开发了连接器来查询不同的外部数据源。这个框架非常灵活,但在存算分离的架构中,很难提供低延迟保证。网络和存储延迟导致很难确保数据访问的稳定性。为了解决这个问题,Raptor 被设计成 Presto 的独享存储引擎(shared-nothing storage engine)。

>> 动机—AB 测试框架中的一个初始用例 <<

在 Meta 公司,新的产品特性通常要经过 AB 测试,然后才能大范围发布。AB 测试框架允许工程师配置实验,在实验组启用新特性,然后通过监控一些关键指标与对照组进行比较。该框架为工程师提供了一个 UI(用户界面)来分析他们的实验统计数据,从而将配置转换为 Presto 查询,查询语句是已知且有限的。查询通常连接多个大型数据集,其中包括用户、设备、测试、事件属性等。这个用例的基本需求是:

1.准确性:数据必须完整、准确,不能有偏差
2.灵活性:用户应该能够根据分析需求随意划分其运行结果;
3.实时性:测试结果应在数小时内获得;
4.交互延迟短:查询需要在几秒钟内返回结果;
5.高可用:作为产品开发的关键服务,服务的宕机时间必须很短。

Presto 在典型的仓库设置中(比如使用 Hive 连接器直接查询仓库数据)可以轻松满足前两个要求,但无法满足其他的要求。仓库数据大多是 T+1 导入,没有近实时的数据导入,因此不能满足实时性的要求。此外,Meta 的数据中心已经转用存算分离的架构,当以高 QPS (查询吞吐率)扫描大型表时,无法保证低延迟。同时,典型的 Presto 部署会停止整个集群,因此也不能满足高可用需求。

为了支持这一关键用例,我们开始了 Raptor 的产品化进程。

>>>   RaptorX 架构   <<<

帮助 Meta 解决 Presto 中的数据孤岛问题_第2张图片

Raptor 连接器使用 MySQL 作为 metastore 来存储表和文件元数据。表数据存储在每个 worker 节点的本地磁盘上,并定期备份到外部存储系统,以便在 worker 节点崩溃时能够进行数据恢复。数据以足够小的批量方式导入 Raptor 集群中,从而确保分钟级别的延迟,满足实时性要求。此外,还创建了备用集群,提供高可用性。

想要了解更多 Raptor 存储引擎的相关信息,请查看附录—Raptor 架构信息(https://prestodb.io/blog/2022...)或观看附录—Raptor 讲座(https://prestodb.io/blog/2022...)。

局限

通过存算耦合,Raptor 集群可以支持低延迟、高吞吐量的查询工作负载。但是,这种架构带来了以下几个问题:

集群利用率低

Raptor 集群的大小通常取决于需要存储多少数据。由于存算耦合,随着表的增多,将需要更多的 worker 提供足够的存储空间,即使在集群空闲时段,重新将机器分配给其他业务使用的难度也变得非常大。

尾部性能较差

由于数据是对应分配给 worker 节点的,如果一个 worker 节点宕机或变慢,必然会影响查询性能,难以提供稳定的尾部性能。

工程开销较大

Raptor 需要很多存储引擎特有的特性和处理功能的支持,比如数据导入/释放、数据压缩、数据备份/恢复、数据安全等。对于直接查询 Meta 数据仓库的 Presto 集群而言,所有这些服务都由专门的团队管理,所有用例都能从中受益。而对于 Raptor 来说,情况就不同了,这导致了工程开销。

运维开销较高

由于 Raptor 集群需要部署额外的存储系统,因此也就带来额外的运维开销。不同的集群配置和行为意味着需要单独建立 oncall 的处理流程。

潜在的安全和隐私漏洞

随着安全和隐私需求的增加,安全与隐私策略的统一实现变得更加重要。使用单独的存储引擎使得这些策略执行起来非常困难且脆弱。

RaptorX 的启用

Raptor 有着很多的痛点,因此从 2019 年开始,Meta 的工程师们就在重新思考 Raptor 的未来,是否有可能既从本地闪存中受益,又无需承担存算紧耦合架构带来的代价?最终确定的方向是在原生数据仓库之上添加一个新的本地缓存层。这个项目作为 Presto Raptor 连接器用例的替代品被命名为 RaptorX。

从技术层面来讲,RaptorX 项目与 Raptor 无关。直观来说,同样的闪存设备在 RaptorX 里被当作数据缓存使用来存储 Ratpor 表,因此将热数据存放在计算节点上。将本地闪存作为缓存使用而不作为存储引擎使用的优点如下:
●   Presto 无需管理数据生命周期;
●  单个 worker 故障导致的数据丢失对查询性能的影响较小;
●  缓存作为文件系统层的一个特性,是 presto-hive 连接器的一部分,因此 RaptorX 集群的架构类似于其他 presto 集群,减少了运维开销。

>>>   RaptorX 架构   <<<

帮助 Meta 解决 Presto 中的数据孤岛问题_第3张图片

Raptor 和 RaptorX 的根本区别是如何使用 worker 上的本地固态硬盘(SSD)。在 RaptorX 中,Presto Worker 使用 Alluxio 在本地缓存文件数据。不同表列的访问模式可能差异很大,像 ORC 和 Parquet 这样的列式文件格式通常用于数据存储,增加文件中的数据本地性。通过在列式文件上以较小的页面大小缓存文件片段,只有频繁访问的数据才会被保存在接近计算的地方。Presto coordinator 会尝试将处理相同数据的计算任务调度到相同的 worker 节点上,以提高缓存效率。RaptorX 还实现了文件 footer 和元数据缓存,以及其他能进一步提高性能的智能缓存策略。

要了解更多有关 RaptorX 的信息,参见 《RaptorX: 将 Presto 性能提升十倍》(https://prestodb.io/blog/2021...)。

>>> RaptorX 和 Raptor 性能基准测试 <<<

我们对 RaptorX 和 Raptor 进行了基准性能对比测试。基准测试运行在一个有大约 1000 个 Worker 节点和一个 coordinator 的集群上。Raptor 和 RaptorX 使用相同的硬件,整个数据集都能够缓存到 RaptorX 的本地固态硬盘中,因此缓存

帮助 Meta 解决 Presto 中的数据孤岛问题_第4张图片

从基准测试结果中可以看到,RaptorX 的 P90 延迟与 Raptor 相比降低了一半。RaptorX 中的平均查询延迟和 P90 查询延迟之间的差异要比 Raptor 小得多。这是因为在 Raptor 中,数据被物理绑定到计算它的 worker 点上,因此运行慢的节点将不可避免地影响查询延迟。而在 RaptorX 中,我们采用软亲和(soft affinity) 调度。软亲和调度将选择两个 worker 节点作为处理分片(split)的候选节点。如果首选的 worker 节点运行正常,则选择该节点,否则将选择辅助(secondary) worker 节点。数据很有可能在多个节点上缓存,因此对整体工作负载的调度策略可以进一步优化,从而达到更好的 CPU 负载均衡。

>>>   从 Raptor 迁移到 RaptorX   <<<

Meta 公司所有以前的 Raptor 用例都迁移到了 RaptorX 上, RaptorX 提供了更好的用户体验,并且易于扩展。

A/B 测试框架

在前一节中,我们提到了 A/B 测试框架的要求是:准确性、灵活性、实时性、低交互延迟和高可用性。因为 RaptorX 是 Hive 原始数据的缓存层,所以 Hive 保证了数据的准确性。它享受所有来自核心 Presto 引擎的查询优化,以及 Hive 连接器中的许多特定优化。基准测试结果表明,RaptorX 的平均查询和 P90 查询延迟都优于 Raptor。对于实时性要求,我们能够从 Meta 的近实时仓库数据导入框架优化中受益,它提高了所有 Hive 数据的实时性。与 Raptor 一样,备用集群保证了高可用性。

在迁移过程中,由于用户体验良好,测试框架的使用量增长了 2 倍。RaptorX 集群能够按照与迁移前的 Raptor 集群相同的容量支持额外的用量。集群的 CPU 资源得到充分利用,无需担心存储限制。

仪表板

在 Meta 中 Raptor 的另一个典型用例是优化仪表板体验。Presto 用于支持 Meta 中的许多仪表板用例,一些数据工程团队通过预聚合一些数据表,并且手动导入指定的 Raptor 集群来获得更好的查询性能。在迁移到 RaptorX 之后,数据工程师便可以省去数据导入操作,也不再需要担心基础表(base tables)和预聚合表之间的数据一致性问题,同时,P50 以上的大多数分位的查询延迟的降幅都达到了 30%左右。

>>>   Raptor 范围之外   <<<

由于 RaptorX 在正常的 Hive 连接器工作负载下作为 booster 使用起来很容易,我们也在 Meta 的数仓交互式工作负载中启用了 RaptorX。这些是多租户集群,通过 Presto 处理几乎所有 Hive 数据的非 ETL 查询,包括 Tableau、内部仪表板、各种自动生成的 UI 分析查询、各种内部工具生成的工作负载、工作流原型(pipeline prototyping)、调试、数据探索等。RaptorX 为这些集群提供了支持,提高了相同数据集的查询性能。

附录

Raptor 架构信息

帮助 Meta 解决 Presto 中的数据孤岛问题_第5张图片

Raptor 表是根据哈希函数进行桶(bucket)划分的。来自同一个 bucket 的数据被存储在同一个 worker 节点上。在同一列上的多个表被称为一个 distribution。一个表桶可以包含多个分片(shard), 而分片是 Raptor 数据的基本不可变单位, 以 ORC 格式的文件存储。表也可以有排序属性,可以更好地优化查询。

执行优化
Raptor 作为 Presto 的本地存储引擎,允许 Presto 将计算安排在数据节点上,从而提供低延迟、高吞吐量的数据处理能力。除了通用的 SQL 优化外,Raptor 的数据组织方式还能实现更多的执行优化。

●  本地关联:当在桶列上关联同一 distribution 的表时,Raptor 将进行本地关联(Collocated Join),因为具有相同连接键的数据在同一个 worker 上,避免了重新分配。
●  数据裁剪: Raptor 可以进行分片粒度和 ORC 读取器粒度的裁剪
o   分片粒度的裁剪:分片的列范围存储在元数据中,可以根据查询谓词跳过分片。如果表有排序属性,分片将在该 worker 内被排序,这也可用于分片裁剪。
o   ORC 读取器粒度的裁剪:ORC 读取器基于谓词,通过利用 Stripe(一组行数据)元数据针对 Stripe 和行组进行裁剪。如果数据是有序的,排序属性也有助于数据裁剪。

其他特性
●  时间列:一个时间或日期类型的列可以被指定为时间列。如果指定了一个时间列,Raptor 会在分片上严格按天进行限制(即一个 shard 里的记录都是属于某一天的)。鉴于数据保留策略,这将能够提高大表的数据留存性能。
●  后台压缩:为了保证实时性,数据通常是以小的时间粒度导入 Raptor 的,这可能导致产生很多小文件,对查询性能不利。Raptor worker 定期运行后台作业,将多个小分片压缩成大分片,并进行外部排序,保证排序属性。
● 数据恢复:如果某个 worker 发生故障,coordinator 将在集群的其他节点上重新分配故障 worker 的数据。所有 worker 将从备份存储中下载必要的数据。在恢复过程中,如果某个查询需要访问缺失数据,该操作将被阻止,直到数据下载/恢复完毕。
●  数据清理:每个 worker 都有一个后台进程,将其分配的数据与本地数据进行比较,从而恢复缺失的数据,更新陈旧的数据。
●  数据再平衡:如果 coordinator 检测到数据不平衡(例如,增加了新的 worker 节点),它会修复不平衡的数据分布。 

Raptor 讲座
引用
如需了解更多有关 Raptor 的信息, 可点击此链接:Presto Raptor: MPP Shared-Nothing Database on Flash(https://engineering.fb.com/20...),查看 2016 年 [email protected] 会议上关于 Raptor 的公开讲座。

想要获取更多有趣有料的【活动信息】【技术文章】【大咖观点】,请关注[[Alluxio智库]](https://page.ma.scrmtech.com/...):
帮助 Meta 解决 Presto 中的数据孤岛问题_第6张图片

你可能感兴趣的:(帮助 Meta 解决 Presto 中的数据孤岛问题)