Flink 流式写入Iceberg实现原理

Iceberg作为凌驾于HDFS和S3等存储系统之上的数据组织框架,提供了数据写入、读取、文件管理和元数据管理等基本功能,虽然Iceberg提供了丰富的API接口,但是面向API开发需要使用方比较了解其原理和实现细节,还是显得门槛过高。此外,在面向实时数据读写场景,需要有一个桥接框架来自动完成数据的读写,于是Iceberg和Flink成为天作之合,本文就来研究下Iceberg是如何跟Flink对接的。

Flink写入Iceberg总体流程介绍

Flink典型的数据处理链路是Source->Transform->Sink,对Iceberg来讲,也遵从这一模式,比如下图:

Custom Souce是自定义的数据源类型的Source,用于向下游发送数据,比如下面的数据来源于静态List集合:

DataStream<RowData> dataStream = env.fromCollection(list)

IcebergStreamWriter起着数据变换作用,跟Source 组成链式Operator,IcebergFilesCommiter作为Sink,将数据提交到本地文件test表。

在这里插入图片描述

Source端发送数据到IcebergStreamWriter,IcebergFilesCommiter将从IcebergStreamWriter获取的数据提交到元数据管理系统,比如Hive Metastore或者文件系统。当成功提交元数据之后,写入的数据才对外部可见。在这一个过程中,IcebergStreamWriter除了相当于上述链路模式中的Transform角色之外,还有一个重要原因:实现事务提交隔离。IcebergStreamWriter将数据暂时写入到一个缓冲文件,该文件暂时对外部是不可见的,然后IcebergFilesCommiter再将IcebergStreamWriter写入的文件的元信息,比如路径、文件大小,记录行数等写入到ManifestFile中,最后将ManifestFile文件元信息再写入到ManifestList(ManifestList即快照信息),ManifestList又被写入以版本号区分的metadata文件中(v%版本号%.metadata.json),下图展示了一个完整的数据包括元数据组织示例:

在这里插入图片描述

下面展开来讲下实现上述目标的细节内容:

首先Source端DataStream数据流经过IcebergStreamWriter变换,生成新的DataStream: SingleOutputStreamOperator ,输出类型是WriteResult:

//DataStream<RowData> input
//IcebergStreamWriter streamWriter
SingleOutputStreamOperator<WriteResult> writerStream = input
    .transform(operatorName(ICEBERG_STREAM_WRITER_NAME), TypeInformation.of(WriteResult.class), streamWriter)
    .setParallelism(parallelism);

其中WriteResult的定义如下:

public class WriteResult implements Serializable {
   
  private DataFile[] dataFiles;
  private DeleteFile[] deleteFiles;
  private CharSequence[] referencedDataFiles;
	...
}

从类定义可知,IcebergStreamWriter的输出结果其实只是该过程产生的数据文件,主要包括DataFile和DeleteFile,referencedDataFiles暂时先不关注。

然后,IcebergFilesCommiter对上游的Operator 做变换,生成新的DataStream:SingleOutputStreamOperator,这个过程只是提交元数据,本身不会再往下游发送数据,所以返回数据类型为Void:

//SingleOutputStreamOperator<WriteResult> writerStream
SingleOutputStreamOperator<Void> committerStream = writerStream
    .transform(operatorName(ICEBERG_FILES_COMMITTER_NAME), Types.VOID, filesCommitter)
    .setParallelism(1)
    .setMaxParallelism(1);

IcebergStreamWriter和IcebergFilesCommiter实现详细分析

从上面介绍可知,IcebergStreamWriter和IcebergFilesCommiter是最主要的两个数据处理过程,下面对其详细介绍。IcebergStreamWriter和IcebergFilesCommiter都是AbstractStreamOperator的子类,本身除了要实现对单个元素的处理逻辑,还有对快照处理的相关逻辑,先说说对单个元素的处理逻辑:

class IcebergStreamWriter<T> 
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值