010-82449668

EN 中文

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

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

Raptor简介

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

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

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

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

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

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

Raptor 架构

下面是使用 Raptor 连接器的 Presto 集群的高层次架构:

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

想要了解更多Raptor存储引擎的相关信息,请查看附录—Raptor架构信息或观看附录—Raptor讲座

 

局限

通过存算耦合,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 架构

下图为RaptorX 的架构:

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

要了解更多有关 RaptorX 的信息,参见 《RaptorX: 将 Presto 性能提升十倍》。

RaptorX 和 Raptor 性能基准测试

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

从基准测试结果中可以看到,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架构信息

数据组织

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

执行优化

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

① 本地关联:当在桶列上关联同一distribution的表时,Raptor将进行本地关联(Collocated Join),因为具有相同连接键的数据在同一个worker上,避免了重新分配。
② 数据裁剪: Raptor可以进行分片粒度和ORC读取器粒度的裁剪
(1)分片粒度的裁剪:分片的列范围存储在元数据中,可以根据查询谓词跳过分片。如果表有排序属性,分片将在该worker内被排序,这也可用于分片裁剪。
(2)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,查看2016年Data@Scale会议上关于Raptor的公开讲座。

Alluxio在数据索引和模型分发中的核心价值与应用

在当前的技术环境下,搜索、推荐、广告、大模型、自动驾驶等领域的业务依赖于海量数据的处理和复杂模型的训练。这些任务通常涉及从用户行为数据和社交网络数据中提取大量信息,进行模型训练和推理。这一过程需要强大的数据分发能力,尤其是在多个服务器同时拉取同一份数据时,更是考验基础设施的性能。

南方科技大学分享:大数据技术如何赋能大模型训练及开发

南方科技大学是深圳在中国高等教育改革发展的时代背景下创建的一所高起点、高定位的公办新型研究型大学。2022年2月14日,教育部等三部委公布第二轮“双一流”建设高校及建设学科名单,南方科技大学及数学学科入选“双一流”建设高校及建设学科名单。

Shopee 在 Alluxio 加速 AI 训练的实践与探索

Shopee是东南亚领航电商平台,覆盖新加坡、马来西亚、菲律宾、泰国、越南、巴西等十余个市场,同时在中国深圳、上海和香港设立跨境业务办公室。2023年Shopee总订单量达82亿,2024年第二季度总订单量同比增长40%,增势强劲。