本文转载自 InfoQ 官网
作者:Alluxio-钟荣荣;Meta-James Sun & Ke Wang
Raptor 是用来支持Meta(以前的Facebook)中的一些关键交互式查询工作负载的Presto连接器(presto-raptor)。尽管ICDE 2019的论文 Presto:SQL on Everything(https://research.facebook.com/publications/presto-sql-on-everything/)中提到过这一特性,但它对于许多 Presto 用户来说仍然有些神秘,因为目前还没有关于此特性的可用文档。本文将介绍 Raptor 的历史,以及为什么 Meta 最终替换了它,转而采用基于本地缓存的新架构RaptorX。
一般来说,Presto 作为一个查询引擎并不具备存储空间,因此开发了连接器来查询不同的外部数据源。这个框架非常灵活,但在存算分离的架构中,很难提供低延迟保证。网络和存储延迟导致很难确保数据访问的稳定性。为了解决这个问题,Raptor被设计成 Presto 的独享存储引擎(shared-nothing storage engine)。
在 Meta 公司,新的产品特性通常要经过 AB 测试,然后才能大范围发布。AB 测试框架允许工程师配置实验,在实验组启用新特性,然后通过监控一些关键指标与对照组进行比较。该框架为工程师提供了一个 UI(用户界面)来分析他们的实验统计数据,从而将配置转换为 Presto 查询,查询语句是已知且有限的。查询通常连接多个大型数据集,其中包括用户、设备、测试、事件属性等。这个用例的基本需求是:
1.准确性:数据必须完整、准确,不能有偏差
2.灵活性:用户应该能够根据分析需求随意划分其运行结果;
3.实时性:测试结果应在数小时内获得;
4.交互延迟短:查询需要在几秒钟内返回结果;
5.高可用:作为产品开发的关键服务,服务的宕机时间必须很短。
Presto 在典型的仓库设置中(比如使用 Hive 连接器直接查询仓库数据)可以轻松满足前两个要求,但无法满足其他的要求。仓库数据大多是 T+1 导入,没有近实时的数据导入,因此不能满足实时性的要求。此外,Meta 的数据中心已经转用存算分离的架构,当以高 QPS (查询吞吐率)扫描大型表时,无法保证低延迟。同时,典型的 Presto 部署会停止整个集群,因此也不能满足高可用需求。
为了支持这一关键用例,我们开始了 Raptor 的产品化进程。
Raptor连接器使用MySQL作为metastore来存储表和文件元数据。表数据存储在每个worker 节点的本地磁盘上,并定期备份到外部存储系统,以便在 worker节点崩溃时能够进行数据恢复。数据以足够小的批量方式导入Raptor集群中,从而确保分钟级别的延迟,满足实时性要求。此外,还创建了备用集群,提供高可用性。
想要了解更多Raptor存储引擎的相关信息,请查看附录—Raptor架构信息(https://prestodb.io/blog/2022/01/28/avoid-data-silos-in-presto-in-meta#raptor-architecture-details)或观看附录—Raptor讲座(https://prestodb.io/blog/2022/01/28/avoid-data-silos-in-presto-in-meta#raptor-talk)。
局限
通过存算耦合,Raptor 集群可以支持低延迟、高吞吐量的查询工作负载。但是,这种架构带来了以下几个问题:
集群利用率低
Raptor集群的大小通常取决于需要存储多少数据。由于存算耦合,随着表的增多,将需要更多的worker提供足够的存储空间,即使在集群空闲时段,重新将机器分配给其他业务使用的难度也变得非常大。
尾部性能较差
由于数据是对应分配给 worker 节点的,如果一个 worker 节点宕机或变慢,必然会影响查询性能,难以提供稳定的尾部性能。
- 工程开销较大
Raptor 需要很多存储引擎特有的特性和处理功能的支持,比如数据导入/释放、数据压缩、数据备份/恢复、数据安全等。对于直接查询 Meta 数据仓库的 Presto 集群而言,所有这些服务都由专门的团队管理,所有用例都能从中受益。而对于 Raptor 来说,情况就不同了,这导致了工程开销。
- 运维开销较高
由于Raptor集群需要部署额外的存储系统,因此也就带来额外的运维开销。不同的集群配置和行为意味着需要单独建立oncall的处理流程。
潜在的安全和隐私漏洞
随着安全和隐私需求的增加,安全与隐私策略的统一实现变得更加重要。使用单独的存储引擎使得这些策略执行起来非常困难且脆弱。
Raptor有着很多的痛点,因此从2019年开始,Meta的工程师们就在重新思考 Raptor的未来,是否有可能既从本地闪存中受益,又无需承担存算紧耦合架构带来的代价?最终确定的方向是在原生数据仓库之上添加一个新的本地缓存层。这个项目作为 Presto Raptor 连接器用例的替代品被命名为 RaptorX。
从技术层面来讲,RaptorX项目与Raptor无关。直观来说,同样的闪存设备在RaptorX里被当作数据缓存使用来存储Ratpor表,因此将热数据存放在计算节点上。将本地闪存作为缓存使用而不作为存储引擎使用的优点如下:
Raptor和 RaptorX的根本区别是如何使用 worker 上的本地固态硬盘(SSD)。在 RaptorX 中,Presto Worker 使用 Alluxio 在本地缓存文件数据。不同表列的访问模式可能差异很大,像 ORC 和 Parquet 这样的列式文件格式通常用于数据存储,增加文件中的数据本地性。通过在列式文件上以较小的页面大小缓存文件片段,只有频繁访问的数据才会被保存在接近计算的地方。Presto coordinator 会尝试将处理相同数据的计算任务调度到相同的worker节点上,以提高缓存效率。RaptorX 还实现了文件footer和元数据缓存,以及其他能进一步提高性能的智能缓存策略。
要了解更多有关 RaptorX 的信息,参见 《RaptorX: 将 Presto 性能提升十倍》(https://prestodb.io/blog/2021/02/04/raptorx)。
我们对 RaptorX 和 Raptor 进行了基准性能对比测试。基准测试运行在一个有大约 1000 个 Worker 节点和一个 coordinator 的集群上。Raptor和 RaptorX 使用相同的硬件,整个数据集都能够缓存到 RaptorX 的本地固态硬盘中,因此缓存
从基准测试结果中可以看到,RaptorX的P90延迟与Raptor相比降低了一半。RaptorX 中的平均查询延迟和 P90 查询延迟之间的差异要比 Raptor 小得多。这是因为在 Raptor 中,数据被物理绑定到计算它的 worker 点上,因此运行慢的节点将不可避免地影响查询延迟。而在RaptorX中,我们采用软亲和(soft affinity) 调度。软亲和调度将选择两个 worker 节点作为处理分片(split)的候选节点。如果首选的worker节点运行正常,则选择该节点,否则将选择辅助(secondary) worker 节点。数据很有可能在多个节点上缓存,因此对整体工作负载的调度策略可以进一步优化,从而达到更好的 CPU负载均衡。
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%左右。
由于 RaptorX 在正常的 Hive 连接器工作负载下作为booster使用起来很容易,我们也在 Meta 的数仓交互式工作负载中启用了 RaptorX。这些是多租户集群,通过 Presto 处理几乎所有Hive 数据的非 ETL 查询,包括 Tableau、内部仪表板、各种自动生成的 UI 分析查询、各种内部工具生成的工作负载、工作流原型(pipeline prototyping)、调试、数据探索等。RaptorX 为这些集群提供了支持,提高了相同数据集的查询性能。
Raptor架构信息
Raptor表是根据哈希函数进行桶(bucket)划分的。来自同一个bucket的数据被存储在同一个worker节点上。在同一列上的多个表被称为一个distribution。一个表桶可以包含多个分片(shard), 而分片是Raptor数据的基本不可变单位, 以ORC格式的文件存储。表也可以有排序属性,可以更好地优化查询。
# 执行优化
Raptor作为Presto的本地存储引擎,允许Presto将计算安排在数据节点上,从而提供低延迟、高吞吐量的数据处理能力。除了通用的SQL优化外,Raptor的数据组织方式还能实现更多的执行优化。
# 其他特性
Raptor讲座
如需了解更多有关Raptor的信息, 可点击此链接:Presto Raptor: MPP Shared-Nothing Database on Flash(https://engineering.fb.com/2016/06/16/core-data/data-scale-june-2016-recap/),查看2016年Data@Scale会议上关于Raptor的公开讲座。
想要获取更多有趣有料的【活动信息】【技术文章】【大咖观点】,请关注[Alluxio智库]: