为了账号安全,请及时绑定邮箱和手机立即绑定

优化数据仓库存储

标签:
MySQL

背景

在Netflix,我们当前的数据仓库包含存储在AWS S3中的数百PB的数据,而且每天我们都会提取并创建其他PB的数据。在这种规模下,当数据进入我们的仓库时,通过优化存储布局(记录,对象,分区),我们可以获得大量的性能和成本优势。

这样的优化有几个好处,例如,节省了存储空间,缩短了查询时间,降低了下游处理的成本,并通过删除仅为了提高查询性能而编写的其他ETL来提高开发人员的工作效率。另一方面,这些优化本身必须足够便宜,以使其自身的处理成本超过其带来的收益。

优化数据仓库存储

我们构建了AutoOptimize,可以高效透明地优化数据和元数据存储布局,同时最大程度地提高成本和性能优势。

本文将列出AutoOptimize的一些用例,讨论有助于提高效率的设计原理,并介绍高级体系结构。然后深入研究AutoOptimize的合并用例,并分享一些结果和好处。

用例

我们发现了几个用例,其中诸如AutoOptimize的系统可以带来大量价值。一些优化是高性能数据仓库的先决条件。有时,数据工程师在提取的数据上编写下游ETL,以优化数据/元数据布局,从而使其他ETL过程更便宜,更快速。AutoOptimize的目标是集中进行此类优化,以消除重复的工作,同时比普通ETL更有效地进行工作。

合并

当数据通过实时数据提取系统进入数据仓库时,它的大小有所不同。这将导致整个分区中的小文件数量不断增加。将大量的较小文件合并为少数较大的文件可以使查询处理更快,并减少存储空间。

种类

分区中的预排序记录和文件可加快查询速度并节省大量存储空间,因为它可以实现更高级别的压缩。我们已经有一些具有排序阶段的现有表,以减少表存储并提高下游查询性能。

压实

现代数据仓库允许更新和删除预先存在的记录。Iceberg计划以增量文件的形式启用此功能。随着时间的流逝,增量文件的数量会增加,将它们压缩到其源文件可以使读取操作更加优化。

元数据优化

在Iceberg中,通过保留到元数据中文件位置的映射,将物理分区与逻辑分区分离。这使我们能够在元数据中添加其他索引,以使点查询更加优化。我们还可以重组元数据以使文件扫描更快。

设计原则

为了使AutoOptimize有效地优化数据布局,我们做出了以下选择:

及时与定期优化仅在需要时(基于更改的内容)优化给定的数据集,而不是盲目的定期运行。基本优化与完整优化允许用户在收益递减时进行优化,而不是二进制设置。例如,我们允许分区中包含一些小文件,而不是始终合并大小合适的文件。最小替换与完全覆盖仅替换所需的最小文件量,而不是完全清除覆盖。

这些原则通过提高效率和效率,同时降低数据处理中的端到端延迟来减少资源使用。

除了这些原则之外,还有其他一些设计注意事项可以支持和启用:

具有数据库和表优先级的多租户。自动(事件驱动)和手动(临时)优化。对最终用户的透明度。高级设计优化数据仓库存储

> AutoOptimize High-Level Design

AutoOptimize分为2个子系统(服务和参与者),以使古玩交易决策与操作在较高层次上脱钩。职责的这种分离有助于我们独立设计,管理,使用和扩展子系统。

自动优化服务

服务是决策者。它决定响应传入事件时该做什么和何时去做。它负责侦听传入的事件和请求,并区分不同的表和操作的优先级,以充分利用可用资源。

服务中完成的工作可以进一步分为以下三个步骤:

观察:几乎实时聆听仓库中的变化。另外,响应最终用户手动创建的临时请求。

定向:为已更改的特定表收集调整参数。另外,根据积压情况调整表的资源分配或参与者的数量。

决定:使用此特定更改的正确参数确定最高价值的操作以及何时执行操作,具体取决于该操作在所有表和操作中的优先级如何降低。

在AutoOptimize中,该服务是使用Redis保持状态的Java(Spring Boot)应用程序的集群。

自动优化演员

AutoOptimize中的参与者负责实际工作(合并/排序/压缩等)。AutoOptimize Service将命令发送给参与者,以指定要执行的操作。Actor的工作是以分布式且容错的方式执行这些命令。

Autoptimize中的参与者是由Autoptimize服务管理的长期运行的Spark作业的池。

这不是故意的,但是我们发现模块化AutoOptimize决策流程的方式与OODA循环非常相似,因此决定使用相同的分类法。

其他组件

Iceberg我们使用Apache Iceberg作为表格格式。AutoOptimize依靠Iceberg的某些特定功能(例如快照和原子操作)以准确和可扩展的方式执行优化。

简而言之,AutoAnalyze可以为表找到最佳的调整/配置参数。它使用“假设”实验以及先前的经验和启发式方法来查找表的最合适属性。将来,我们将发布有关AutoAnalyze的后续博客文章。对于AutoOptimize,它可以查找表是否需要文件合并或建议目标文件大小和其他参数。

深入研究文件合并

文件合并是我们为AutoOptimize构建的第一个用例。以前,我们有一个名为Ursula的本地系统,负责将数据提取到基于Hive的仓库中。基于Ursula的管道还定期对提取的表分区执行文件合并。从那时起,我们将摄取内容移至Keystone,并将表布局移至Iceberg。

从Ursula迁移到基于Keystone / Iceberg的提取开始,需要替换Ursula文件合并。文件合并对于低延迟的流式传输管道来说是必需的,因为数据经常延迟到达并且不均匀。随着时间的推移,跨分区的小文件数量会减少,并且可能会产生一些严重的副作用,例如:

放慢查询速度。更多处理资源。增加存储空间。

AutoOptimize中文件合并的目标是有效减少副作用,同时不增加数据管道的额外延迟。

解决方案

本节将讨论一些有助于我们实现上述目标的解决方案。

及时优化

通过表更改事件触发自动优化文件合并。这使AutoOptimize能够以最小的延迟立即采取行动。但是,由事件驱动的问题在于,每次更改分区时都要扫描它们,这很昂贵。如果可以滚动方式从变更集中确定分区“有多嘈杂”,则可以消除来自快照的早期信号所造成的不必要的全分区扫描。

基本工作

在对整个分区进行扫描之后,“自动优化”将获得有关分区状态的更全面视图。我们可以在此阶段获得更准确的分区状态,并避免不必要的工作。

分区熵我们引入了一个称为分区熵(PE)的概念,用于在每个步骤中进行早期修剪,以减少实际工作量。这是有关分区状态的一组统计信息。我们在每次快照扫描后以滚动方式计算此值,并且在每次分区扫描后以更详尽的方式计算此值。

PE中处理文件大小的部分称为文件大小熵(FSE)。分区的FSE从分区中文件大小的均方误差(MSE)中得出。我们将术语FSE和MSE互换使用。

我们使用标准的均方误差公式:

优化数据仓库存储

在哪里,

N=分区中的文件数目标=目标文件大小实际=最小值(实际文件大小,目标)

扫描分区后,使用上面的公式可以很容易地计算出MSE,因为我们知道该分区中所有文件的大小。我们将每个分区的MSE和N存储在Redis中,以备后用。

在快照扫描阶段,我们得到一个提交定义,其中包含在提交中添加和删除的文件及其元数据(如大小,记录数等)的列表。我们使用以下公式,根据快照信息和先前存储的统计信息,以滚动方式来计算已更改分区的新MSE。

优化数据仓库存储

在哪里,

M=快照中添加的文件数Target=目标文件大小Actual=min(实际文件大小,目标)N=分区中先前存储的文件数MSE=先前存储的MSE

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消