Arctic 是一个开放式架构下的湖仓管理系统,在开放的 lceberg 数据湖格式之上, 提供更多面向流和更新场景的优化,以及一套可插拔的数据自优化机制和管理服务。
湖数据与数据仓库都是常见的大数据存储系统。得益于其低廉的成本优势,数据湖一般用来存储海量的原始数据。原始数据经过清洗、标准化后会再导入到数据仓库中进行数据分析。数据在两个系统间流转无疑增加了额外的存储与维护开销。
近年来随着 Apache lceberg、Apache Hudi、Delta Lake 等数据湖表格式技术的不断发展使得直接在数据湖上构建一套统一的存储系统来满足所有的大数据存储需求成为可能。业界将这种直接建立在数据湖之上,却能同时覆盖数据湖与数据仓库存储场景的架构为湖仓一体(LakeHouse)。
然而开源表格式距离生产可用的湖仓一体架构还有着较大的鸿沟,在这个背景下网易在 2022 年开源了湖仓管理系统 ——Arctic。Arctic 是一个开放式架构下的湖仓管理系统,在开放的数据湖格式之上,Arctic 提供更多面向流和更新场景的优化,以及一套可插拔的数据自优化机制和管理服务。基于 Arctic 可以帮助各类数据平台,工具和产品快速搭建开箱即用,流批统一的湖仓。
要构建一套开箱即用的湖仓系统,自动优化是第一个需要解决的需求。现在大部分开源的数据湖表格式都要求用户投入大量的精力来维护你数据湖表中的文件结构,稍不留神表的查询性能就可能出现较大的下滑。
湖仓上有两类常见的优化需求:文件合并与文件清理。文件合并可分为以下场景:
常见的文件清理场景包括:
Apache lceberg 通过在 Spark 引擎内提供了丰富的存储过程来应对文件合并与文件清理的优化需求。不过在实际使用时需要用户来判断何时需要进行优化、使用什么样的优化参数,并保证优化任务能正确完成工作。这无疑增大了用户的使用成本。
Apache Hudi 则提供在写入任务里同时运行优化任务,与使用另一个独立任务来完成优化的方式。前者可能造成写入任务与优化任务互相影响的问题。后者则需要为每个表维护一个长期运行的优化任务,任务多了将难以管理,同时很难保证优化任务的资源使用率。
可见要解决湖仓表的自动优化需求并没有那么简单,我们要面临如下难点:
Arctic 引入了一套 Self-optimizing 机制,目标是基于新型数据湖表格式打造像数据库,传统数据一样开箱即用的流式湖仓服务,Self-optimizing 包含但不限于文件合并、去重、排序、孤儿文件和过期快照的清理。Self-optimizing 的架构与工作机制如下图所示:
AMS (Arctic Management Service) 是 Arctic 的中心管理服务,它负责规划所有表的 self-optimizing 任务,并将任务下发给下面的 Optimizer 执行。Optimizer 是 self-optimizing 的执行组件,收到优化任务后负责具体的任务执行过程,最后再将执行结果上报给 AMS 后进行提交。Arctic 通过 Optimizer Group 对 Optimizers 实现物理隔离。
Arctic 的 self-optimizing 的核心特性有:
AMS 会持续收集表上的写入信息并实时更新表上的统计信息,当表上的统计指标达到了触发自动优化的条件即会开始对表进行自动优化。统计指标会精确到分区级别,即写入频繁的分区会更频繁得触发自动优化。触发自动优化的条件包括:
频繁的对表里的文件进行优化会消耗过多的资源,而如果不及时进行文件优化又会造成表上查询性能的下降。为了权衡资源开销与查询性能,Arctic 将文件优化任务进行了进一步的细分。
Arctic 将表中的文件按照大小分为了两类:
基于以上的文件分类,Arctic 将文件优化任务分为以下三类:
类型 | 定义 | 目标 | 任务大小 | 调度频率 |
---|---|---|---|---|
Minor Optimizing | 在 Fragment File 上的优化任务 | 降低文件碎片,将写友好的文件转换为读友好的文件 | 较小(比如 16MB) | 非常频繁(比如每 5 分钟一次) |
Major Optimizing | 在 Segment File 上的优化任务 | 将文件大小推进到目标大小,并减少冗余数据 | 中等(比如 128MB) | 较频繁(比如每 1 小时一次) |
Full Optimizing | 表或者分区内所有文件上的优化任务 | 将所以文件全局排序后重写 | 取决于表或分区的大小 | 不频繁(比如每一天) |
具体来说,对于 Iceberg 格式的表,Minor optimizing 会将小于 16MB 的 insert File 合并到大于 16MB,并将 equality-delete file 转换为 position-delete file,转换过程中会为每个 insert file 生成对应的 position-delete file,并将已有的 position-delete file 数据合并到新的 position-delete file 内,具体过程如下图:
而 Major optimizing 则会将那些已经积攒了较大的 position-delete file 的 insert file 与其对应的 delete file 进行合并而消除其冗余数据。Full optimizing 会将所有的文件进行重写,重写过程会消除掉多有的 delete file。具体过程如下图:
为了保证优化任务能被及时调度执行,Arctic 采用维护一套长期运行的优化资源而非为每个优化任务临时调度优化资源的方案。所有表的优化任务都运行在统一的资源上,为了提升优化资源的利用率,同时避免表与表之间的相互影响,Arctic 提出了如下概念:
一个 Optimizing group 下一般会有多个 Optimizer,Optimizer 是一个独立的无状态的计算资源,如果某个 Optimizer 离线了,它上面的任务会被重新调度到同 group 下的其他 optimizer 上继续执行。当某个 group 下的 optimizer 利用率过大时,用户也可以简单的扩容新的 optimizer 来提升处理能力。
Arctic 抽象了一套 Optimizer container 接口来扩展不同的 optimizer 调度方式,项目内已经实现了新增本地进程和在 Yarn 集群上调度 Flink 任务的实现。用户也可以根据自己内部的调度框架扩展自己的 optimizer 运行方式。
Arctic 在其 WEB 界面工具中提供了单独的页面展示系统内每个表所处的自动优化状态,具体如下图:
界面中不仅展示了表当前是否正在进行 自动优化,也给出了当前待优化的文件的具体情况,及配置和已经消耗的优化资源。
另外每个表的详情页面里也能看到已经发生过的自动优化任务,具体如下图:
界面中展示了每次自动优化任务的类型、耗时、优化前的文件情况和优化后的文件情况。
Arctic 提供了一套自动、异步、透明的自动优化服务保证湖仓表的性能。这套实现方案已经在网易内部和开源社区内都得到了验证。
为了更直观得展现自动优化的效果,下面是 Arctic 团队内部分别测试在开启和关闭自动优化功能时,Iceberg 表的分析性能表现。测试模拟了表上持续有写入的情况下,Iceberg 表的查询性能,测试中发现随着时间推移不开启自动优化功能时,Iceberg 表查询性能急剧下降,在超过一小时后甚至因为内存溢出无法正确查询出需要的数据,而开启自动优化后随着时间变化表的查询耗时都能维持在一个较低的水平。具体的测试场景可以参考:Arctic Benchmark(https://arctic.netease.com/ch/benchmark/benchmark/)
未来 Arctic 在湖仓表的自动优化方面将沿着下面的路径继续演进:
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。