【Flink connector】文件系统 SQL 连接器:实时写文件系统以及(kafka到hive)实战举例

本文概述

flink支持动态写数据到文件系统,提供了分块写数据以及动态分区,接下来看flink是如何分块写数据,以及如何配置动态分区的建立。

 

文件系统连接器支持写入,是基于 Flink 的 文件系统 写入文件的。

我们可以直接编写 SQL,将流数据插入到非分区表。 如果是分区表,可以配置分区操作相关的属性。具体参考分区提交

 

一. 滚动策略:sink后文件切分(暂不关注)

1. 切分分区目录下的文件

分区目录下的数据被分割到 part 文件中。每个分区对应的 sink 的 subtask 都至少会为该分区生成一个 part 文件。
该策略基于大小,和指定的文件可被打开的最大 timeout 时长,来滚动 part 文件。

默认值 类型 描述
sink.rolling-policy.file-size 128MB MemorySize 当part达到设定值时,文件开始滚动。
sink.rolling-policy.rollover-interval 30 min Duration 滚动前,part 文件处于打开状态的最大时长(默认值30分钟,以避免产生大量小文件)。 检查频率是由 sink.rolling-policy.check-interval 属性控制的。
sink.rolling-policy.check-interval 1 min Duration 周期检查文件打开时长。

根据描述默认情况下Flink采取了如上默认值的滚动策略。

 


todo:checkpoint 也会影响part文件的生成


对于 bulk formats 数据 (parquet、orc、avro):滚动策略与 checkpoint 间隔(pending 状态的文件会在下个 checkpoint 完成)控制了 part 文件的大小和个数。

 

2. 小文件合并


todo: checkpoint的间隔会影响文件产生的效率


file sink 支持文件合并,允许应用程序使用较小的 checkpoint 间隔但不产生大量小文件。

默认值 类型 描述
auto-compaction false Boolean 在流式 sink 中自动合并功能。数据首先会被写入临时文件。当 checkpoint 完成后,该检查点产生的临时文件会被合并。这些临时文件在合并前不可见。
compaction.file-size (无) MemorySize 合并目标文件大小,默认值为滚动文件大小

如果启用文件合并功能,会根据目标文件大小,将多个小文件合并成大文件。

在生产环境中使用文件合并功能时,需要注意:

  • 只有 checkpoint 内部的文件才会被合并,至少生成的文件个数与 checkpoint 个数相同。
  • 合并前文件是不可见的,那么文件的可见时间是:checkpoint 间隔时长 + 合并时长。
  • 如果合并时间过长,将导致反压,延长 checkpoint 所需时间。

 

二. 分区提交

sink动态写分区包括如下两个操作:

  1. Trigger-提交分区的时机:通过什么来识别分区(watermark或处理时间),什么时候提交分区
  2. Policy-提交分区后通知下游:写_SUCCESS,hive metadata 中新增分区,或自定义:合并小文件等。

注意: 分区提交仅在(什么是?)动态分区插入模式下才有效。

 

1. 分区提交触发器 (什么时候创建分区)

1.1. 逻辑说明

Flink 提供了两种类型分区提交触发器:

  • 第一种:根据分区的处理时间(没有根据字段吗)。基于分区创建时间(这里指的是什么)和当前系统时间来触发分区。 这种触发器更具通用性,但不是很精确。例如,数据延迟或故障将导致过早提交分区。
  • 第二种:根据从分区字段提取的时间以及 watermark。 这需要 job 支持 watermark 生成,分区是根据时间来切割的,例如,按小时或按天分区。

 

感知分区的几种情况:

  1. 不管分区数据是否完整而只想让下游尽快感知到分区:(不推荐)

‘sink.partition-commit.trigger’=‘process-time’ (默认值)
‘sink.partition-commit.delay’=‘0s’ (默认值) 一旦数据进入分区,将立即提交分区。注意:这个分区可能会被提交多次(提交多次产生的影响ing:浪费多余的资源)。

  1. 如果想让下游只有在分区数据完整时才感知到分区,并且 job 中有 watermark 生成,也能从分区字段的值中提取到时间

‘sink.partition-commit.trigger’=‘partition-time’
‘sink.partition-commit.delay’=‘1h’ (根据分区类型指定,如果是按小时分区可配置为 ‘1h’) 该方式是最精准地提交分区的方式,尽力确保提交分区的数据完整。

  1. 如果想让下游系统只有在数据完整时才感知到分区,但是没有 watermark,或者无法从分区字段的值中提取时间:

‘sink.partition-commit.trigger’=‘process-time’ (默认值)
‘sink.partition-commit.delay’=‘1h’ (根据分区类型指定,如果是按小时分区可配置为 ‘1h’) 该方式尽量精确地提交分区,但是数据延迟或者故障将导致过早提交分区

延迟数据的处理:延迟的记录会被写入到已经提交的对应分区中,且会再次触发该分区的提交。

 

如下参数:

确定何时提交分区:这里只关注process-time trigger下的两个参数

sink.partition-commit.trigger:
默认值:process-time
描述:

  • 基于机器时间: ‘process-time’:不需要分区时间提取器也不需要 watermark 生成器。
  • 一旦 “当前系统时间” 超过了 "分区创建系统时间(比如flink消费到一条数据,触发了分区创建操作对应的时间)" 和 'sink.partition-commit.delay' 之和立即提交分区。
  • 基于提取的分区时间:‘partition-time’。需要 watermark 生成。一旦 watermark 超过了 “分区创建系统时间” 和 ‘sink.partition-commit.delay’ 之和立即提交分区。

sink.partition-commit.delay
默认值:0s
描述: 该延迟时间之前分区不会被提交。如果是按天分区,可以设置为 ‘1 d’,如果是按小时分区,应设置为 ‘1 h’,当然也可以设置分钟,例如 30min

 

1.2. 举例说明

--默认值可以不配置
'sink.partition-commit.trigger'='process-time' 
--当来第一条数据时(记录为时刻1),先创建hive分区文件夹,当时间超过 时刻1+1h 时,分区提交
--分区未提交时文件为.data开头的临时文件,分区提交时,会从cp中同步数据到临时文件中,并命名为正式文件。 
'sink.partition-commit.delay'='1h' 

 

2. 分区时间提取器 (用于partition-time情况下partition commit策略)

2.1. 逻辑说明

时间提取器从分区字段值中提取时间。

partition.time-extractor.kind
默认值:default
描述:从分区字段中提取时间的时间提取器。
支持default 和 custom。在默认情况下,可以配置 timestamp-pattern/formatter。对于custom,应指定提取器类。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

roman_日积跬步-终至千里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值