Flink源码阅读之FileSystem Connector

本文详细探讨了Flink的FileSystem Connector,从Sink的角度分析了数据写入filesystem、checkpoint机制和partition commit策略。同时,也介绍了Source部分的数据读取流程。通过对Flink-table-runtime-blink模块的源码解读,阐述了FileSystemTableSink的构造、数据处理和状态快照的实现,以及FileSystemTableSource的创建和数据读取过程。
摘要由CSDN通过智能技术生成

代码在flink-table-runtime-blink模块,用户指南参考官网.

目前是旧的实现方式,将会按FLIP-95重新实现FLINK-19336

入口类FileSystemTableFactory,如何做Factory discover的可以参考之前的博文,这里就不赘述了。

Sink

构造FileSystemTableSink对象,传入相关属性参数

public TableSink<RowData> createTableSink(TableSinkFactory.Context context) {
   
		Configuration conf = new Configuration();
		context.getTable().getOptions().forEach(conf::setString);

		return new FileSystemTableSink(
				context.getObjectIdentifier(),//connector标识符
				context.isBounded(),//是否有界流
				context.getTable().getSchema(),//表的schema
				getPath(conf),//file 路径
				context.getTable().getPartitionKeys(),//分区key
				conf.get(PARTITION_DEFAULT_NAME),//默认分区名称
				context.getTable().getOptions());//参数
	}

FileSystemTableSink会根据DataStream构造DataStreamSink

consumeDataStream主要做几个事情:

  1. 构造RowDataPartitionComputer,将分区字段和非分区字段index和type分开。
  2. EmptyMetaStoreFactory空的metastore实现。
  3. UUID生成文件前缀
  4. 构造FileSystemFactory的实现
  5. 根据是否有界流走不同分支处理
public final DataStreamSink<RowData> consumeDataStream(DataStream<RowData> dataStream) {
   
		RowDataPartitionComputer computer = new RowDataPartitionComputer(
				defaultPartName,
				schema.getFieldNames(),
				schema.getFieldDataTypes(),
				partitionKeys.toArray(new String[0]));

		EmptyMetaStoreFactory metaStoreFactory = new EmptyMetaStoreFactory(path);
		OutputFileConfig outputFileConfig = OutputFileConfig.builder()
				.withPartPrefix("part-" + UUID.randomUUID().toString())
				.build();
		FileSystemFactory fsFactory = FileSystem::get;

		if (isBounded) {
   
			FileSystemOutputFormat.Builder<RowData> builder = new FileSystemOutputFormat.Builder<>();
			builder.setPartitionComputer(computer);
			builder.setDynamicGrouped(dynamicGrouping);
			builder.setPartitionColumns(partitionKeys.toArray(new String[0]));
			builder.setFormatFactory(createOutputFormatFactory());
			builder.setMetaStoreFactory(metaStoreFactory);
			builder.setFileSystemFactory(fsFactory);
			builder.setOverwrite(overwrite);
			builder.setStaticPartitions(staticPartitions);
			builder.setTempPath(toStagingPath());
			builder.setOutputFileConfig(outputFileConfig);
			return dataStream.writeUsingOutputFormat(builder.build())
					.setParallelism(dataStream.getParallelism());
		} else {
   
			Configuration conf = new Configuration();
			properties.forEach(conf::setString);
			Object writer = createWriter();
			TableBucketAssigner assigner = new TableBucketAssigner(computer);
			TableRollingPolicy rollingPolicy = new TableRollingPolicy(
					!(writer instanceof Encoder),
					conf.get(SINK_ROLLING_POLICY_FILE_SIZE).getBytes(),
					conf.get(SINK_ROLLING_POLICY_ROLLOVER_INTERVAL).toMillis());

			BucketsBuilder<RowData, String, ? extends BucketsBuilder<RowData, ?, ?>> bucketsBuilder;
			if (writer instanceof Encoder) {
   
				//noinspection unchecked
				bucketsBuilder = StreamingFileSink.forRowFormat(
						path, new ProjectionEncoder((Encoder<RowData>) writer, computer))
						.withBucketAssigner(assigner)
						.withOutputFileConfig(outputFileConfig)
						.withRollingPolicy(rollingPolicy);
			} else {
   
				//noinspection unchecked
				bucketsBuilder = StreamingFileSink.forBulkFormat(
						path, new ProjectionBulkFactory((BulkWriter.Factory<RowData>) writer, computer))
						.withBucketAssigner(assigner)
						.withOutputFileConfig(outputFileConfig)
						.withRollingPolicy(rollingPolicy);
			}
			return createStreamingSink(
					conf,
					path,
					partitionKeys,
					tableIdentifier,
					overwrite,
					dataStream,
					bucketsBuilder,
					metaStoreFactory,
					fsFactory,
					conf.get(SINK_ROLLING_POLICY_CHECK_INTERVAL).toMillis(
### 回答1: 我可以提供一些建议:首先,使用Flink SQL编写代码,然后使用Hive建立外表。接下来,可以使用'CREATE EXTERNAL TABLE'语句来定义外表。最后,通过在Hive中注册外表,可以完成对Hive外表的建立。 ### 回答2: 要使用Flink SQL在Hive中创建外部表,你可以按照以下步骤操作: 1. 首先,确保你已经安装了Flink,并且Flink的SQL客户端已经启动。 2. 在Flink SQL客户端中,执行以下命令来创建Hive表的外部表: CREATE EXTERNAL TABLE hive_external_table ( col1 INT, col2 STRING ) STORED AS PARQUET LOCATION '<HDFS_path_to_parquet_files>'; 在上述命令中,你需要指定外部表的名称(hive_external_table)以及表中的列名和数据类型。同时,你还需要指定外部表存储的文件格式,这里我们使用的是Parquet格式。最后,你需要指定外部表存储在HDFS上的位置,即<HDFS_path_to_parquet_files>。 3. 接下来,你需要将Flink的查询结果写入到Hive的外部表中。你可以使用类似如下的代码将数据写入外部表: INSERT INTO hive_external_table SELECT col1, col2 FROM flink_source_table; 在上述代码中,flink_source_table是Flink中的源表,它包含了要写入到Hive外部表中的数据。通过将查询结果插入到外部表中,你就能将Flink SQL的结果保存到Hive中的外部表中了。 需要注意的是,Flink SQL默认的Hive版本是1.2.1。如果你使用的是不同的Hive版本,那么你可能需要在创建外部表时指定与你的Hive版本相匹配的存储格式和语法。 希望以上步骤能够帮助你成功地使用Flink SQL创建Hive的外部表。 ### 回答3: 要生产 Flink SQL 代码建立 Hive 外表,可以按照以下步骤进行操作: 1. 首先,你需要在 Hive 中创建一个外部表。可以使用 Hive SQL 语句来定义外部表的结构,并指定数据的存储位置和格式。例如,使用如下的 Hive SQL 语句创建一个外部表: ``` CREATE EXTERNAL TABLE IF NOT EXISTS my_external_table ( column1 INT, column2 STRING ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS TEXTFILE LOCATION '/path/to/data'; ``` 在上述示例中,`my_external_table` 是外部表的名称,`column1` 和 `column2` 是表的列定义,`ROW FORMAT DELIMITED` 指定行格式为逗号分隔,`STORED AS TEXTFILE` 指定数据以文本文件形式存储,`LOCATION` 指定数据的存储路径。 2. 接下来,你需要使用 Flink SQL 编写代码来建立 Hive 外部表,以便 Flink 可以与之进行交互。在 Flink SQL 代码中,你可以使用 `CREATE TABLE` 语句来定义外部表的结构和元数据,以与 Hive 中的外部表一致。例如,使用如下的 Flink SQL 代码建立 Hive 外部表: ``` CREATE TABLE my_external_table ( column1 INT, column2 STRING ) WITH ( 'connector' = 'filesystem', 'path' = '/path/to/data', 'format' = 'csv', 'csv.field-delimiter' = ',', 'hive-table-name' = 'my_external_table', 'hive-partition-keys' = '', 'hive-partition-values' = '' ); ``` 在上述示例中,`my_external_table` 是外部表的名称,`column1` 和 `column2` 是表的列定义,`connector` 指定连接器类型为文件系统,`path` 指定数据的路径,`format` 指定数据的格式为 CSV,`csv.field-delimiter` 指定字段分隔符为逗号,`hive-table-name` 指定 Hive 外部表的名称,`hive-partition-keys` 和 `hive-partition-values` 这两个参数用于指定分区的键和值。 通过以上步骤,你就可以使用 Flink SQL 代码建立 Hive 外部表了。在建立外部表后,你可以使用 Flink SQL 进行数据操作和分析,同时也可以在 Hive 中使用外部表进行数据查询和处理。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值