导读 本文将分享Iceberg实时数仓数据分析的性能优化,主要内容包括以下4个方面:
1. Iceberg MOR原理介绍
2. Arctic基于Iceberg性能优化
3. 优化效果评估--CH-benchmark
4. 未来规划
分享嘉宾|史大洋 网易数帆 软件工程师
编辑整理|吴旺旺 东北大学
出品社区|DataFun
01
Iceberg MOR原理介绍
1.MOR介绍
MOR是Merge On Read的简称,是一种行级更新技术,本质上是out-of-place update,更新和删除不直接修改历史数据,而是单独记录数据变更,在读取的时候再合并历史数据和变更得到修改后的值。这种方式更新的时候代价比较小,读取的时候代价较大。比较适合实时写入的场景,因为实时写入对数据湖写入性能要求比较高。
2.Iceberg内部的三种文件
Iceberg 内部主要有三种数据文件。第一种文件是data-file,data-file存储的是正常 insert操作插入的数据。第二种文件是equality-delete-file存储的是删除数据,它根据标记的字段,现在一般是主键,然后跟data-file主键字段进行比对,如果匹配相等,这条主键匹配上的值就会被丢弃。第三种文件是position-delete-file存储的是删除数据,它根据标注的文件位置进行删除。
3.equality-delete作用方式
在读取的时候,equality-delete数据会被先读入内存,然后按照equality-delete-columns指示的列构建hash表。然后读取data数据,取相应的列和hash表进行比对,丢弃掉和hash表匹配的数据。像示意图中所示的equality-delete它标志的是“id=1”这条数据被删除,然后在内存中构建Hash表之后会读取对的file,如果对应的file中发现“id=1”的这条数据就会被删除,最终读出来的数据是“id=2”和“id=3”的数据。
4.Positioned-delete作用方式
Position-delete有两种作用形式:
- 构建bitmap
先把position-delete-file数据读入内存,position-delete-file只是标记要删除data-file的行号,所以需要按照删除的行号构建bitmap,这种方式对内存的消耗非常小。在读取data-file的时候,丢弃掉与bitmap里行号匹配的数据。例如图中所示bitmap内保存行号为2,于是data-file中行号为2即id=3的数据会被丢弃。
- Sort-Merge
另一种作用方式是Sort-Merge。data-file的行号是自然增加的,position-delete-file记录的删除行号也是升序排序。于是可以对两种文件做Sort-Merge。
5.Iceberg文件组织形式及task结构
图中所示的Flink做了三次写入及提交,每次写入时,insert操作的数据会写入data-file。delete操作的数据会写两种文件,一个是equality-delete-file,一个是position-delete-file。equality-delete-file总是作用于历史快照的数据,它不会作用于当前快照的data-file,于是它需要一个position-delete-file来作用于当前快照。
在读取的时候,task按照data-file为主导划分,一个data-file可以划分为一个或多个task。每一个task是一个最小读取单元。
02
Arctic基于Iceberg性能优化
1.Arctic简介
Arctic是网易研发的一个开放式架构下的湖仓管理系统,在开放的数据湖格式 Iceberg之上,提供了更多面向流和更新场景的优化,以及一套可插拔的数据自优化机制self-optimizing和管理服务。基于Arctic可以帮助各类数据平台,工具和产品快速搭建开箱即用、流批统一的湖仓。
2.为什么需要 Optimize
在使用数据湖的时候经常会遇到一些问题,第一个是小文件问题,小文件太多。因为实时提交每一个快照都需要提交,写入的文件都比较零碎。第二个是冗余数据太多,记录了很多delete数据,这些delete数据应该和data-file数据进行删除。非常多的delete-file,一方面增加了存储,另一方面delete在读取的时候性能非常低。第三是数据组织形式比较低效的问题。第四是过期无效文件的残留问题,在原数据中已经标志一个文件删除了,但是它并不会真的被删除,这些文件需要定时的清理。
3.Arctic Self-optimizing
Self-optimizing具有三个特性。一是定时监控,Self-optimizing提供一套自动执行的机制,定时扫描每个表检查,发现这个表需要做optimizing的时候会自动调度起来做optimizing。二是资源隔离,提供资源组管理和配额设置,每个组中可以配置一些不同的参数以及调度策略规则,允许资源在表级隔离和共享。三是灵活部署,基于Flink引擎部署,支持YARN、K8s,支持通过AMS在线扩缩容。
4.Self-optimizing -- 小文件合并
常见的小文件合并是把多个小文件合并成一个大文件,小文件合并的好处是降低了HDFS的NameNode的压力,降低Iceberg元数据的数量,减少查询时打开文件的代价。
5.Self-optimizing -- 消除delete文件
Flink写入的时候会有非常多的delete文件,在读取的时候读取这些delete文件,会带来一定的性能损耗,如果把delete和data-file合并成一个新的文件,这样既减少了文件数量,也减少了读取的数据量,并且降低了MOR时应用delete文件的代价,释放了CPU和内存。
6.Self-optimizing -- Equality-delete转Position-delete
equality-delete-file会先读入内存,然后构建hash表和data-file数据进行比对,这样对于内存消耗比较高,且需要读取 data-file 时额外读取比对字段。position-delete-file可以读入内存构建bitmap比对,也可以通过sort-merge比对,对于内存消耗较少,且不需要额外的字段比对。通过把equality-delete-file转换为position-delete-file 可以提高查询性能,和上文的消除delete方式相比,这种方式可以在删除比例不高的时候减少写放大。在转换过程中我们让一个position-delete-file对应一个data file,这样可以充分利用Iceberg的data-skipping,让读取的时候避免读其他无效的position-delete文件。
7.Self-optimizing性能优化效果对比图
这张图展示的是 self-optimizing 对性能的影响,蓝色表示有self-optimizing的情况,橘黄色表示没有self-optimizing的情况。横轴表示的是更新数据写入时间。上图表明没有self-optimizing,Iceberg的MOR性能会急剧下降。在60~90minutes的时候表基本上不可用,此时读取数据已经读取不出相应的数据。有self-optimizing的Iceberg的性能会维持在一个非常平稳的水平。
8.Delete 文件重复读取问题
- 问题所在
如图所示,有6个date-file以及6个equality-delete-file,在读取的时候,每1个data-file对应着6个equality-delete-file,于是plan出来的6个task,而每1个task都会读这6个equality-delete-file,也就说这个equality-delete-file被读取了36次,也就是他多读了30次的data-file,对性能的损耗是非常高的。
- Mixed Iceberg format精细化data文件和delete文件对应关系
引入文件分组策略,文件写入的时候按照主键进行hash分组,可以精确化对应data-file和equality-file的关系。这种分桶策略是一种一致性哈希的方案,这种方案的好处是可以低成本修改分组数量。
- Mixed Iceberg format复用delete数据
对于不同data-file文件对应的equality-delete-file文件相等的情况下,可以将不同的data-file文件合并到同一个Task,从而复用delete-file数据。读取的时候,相同的node下的多个data文件分配在一个task里面,读取的时候delete文件只读取一次。
- Mixed Iceberg format task均衡分配
在进行分组操作后,因为数据的分布不均衡,每个组下的数据量差异会很大,在实际使用中经常发现一些数据倾斜的问题,有的节点可能十几秒就执行完了,有的节点二十几秒才执行完,严重拖累了整体的一个执行效率。如何均衡分配这些file-group,等效于K-way number partitioning problem,是一个NP-Hard问题。我们采用排序+贪心算法分配,具体步骤就是先对 Task 从大到小排序,然后依次取出放入最小的 parttion 里面。最终得到一个很好的次优解。
- Delete文件复用及task分配策略效果
通过性能对比图,可以看出在实时场景下性能有许多提升。
9.对性能影响较大的参数
文件类型。文件类型对查询性能影响较大,parquet文件相较于AVRO由于采用列存模式具有较高的压缩比,写入和读取的IO会更少,并且可以列裁剪,谓词过滤,读取性能很高,有时能达到数倍差距,但是parquet对内存消耗更高,有时甚至因为同时读取的parquet文件过多导致OOM。
压缩类型。各种压缩类型的特性都有区别,有的压缩比更高但是解压缩代价就更高,有的压缩比不高但是解压缩代价更低,需要根据机器、业务情况进行选择。
03
优化效果评估
1.TPC-C、TPC-H
如何对优化策略给出一个比较标准的评估,目前各个数据湖都会发布一些测试报告,但各方口径并不一致。传统比较标准的测试方案有两套,TPC-C和TPC-H,TPC-C用于OLTP负载,使用只读和更新密集型业务事务的混合来评估性能。TPC-H是一个决策支持基准测试,它对检查大量数据、执行高度复杂的查询并回答关键业务问题的决策支持系统进行建模。但是这两种都不能很好的评估数据湖在行级更新场景下的性能。
2.CH-benchmark
最终采用了CH-benchmark的方案,CH-benchmark以未经修改的TPC-C的模式与事务为基础,结合经过调整的TPC-H查询,形成了一个复杂的混合工作负载。
通过方案中的benchmark工具,分为两部分进行执行,第一步先生成TPCC数据,然后写入MySQL,在MySQL上进行数据事务型的数据更新,模拟实际业务中的MySQL使用情况,然后通过Flink CDC同步变更数据进数据湖,在数据湖里面模拟一个最典型的场景,就是CDC数据入湖,然后在数据湖里源源不断产生变更数据,通过查询引擎进行TPCH查询。
04
未来规划
- 异步数据全局排序(普通排序、Z-order)
- 异步二级索引构建