目前Delta支持flink 的的写入和查询
Flink/Delta Connector 是一个 JVM 库,用于从 Apache Flink 应用程序读取和写入数据到 Delta 表 利用 Delta 独立 JVM 库。 连接器提供恰好一次的交付保证。
Flink/Delta 连接器包括:
DeltaSink
用于将数据从 Apache Flink 写入 Delta 表。DeltaSource
用于使用 Apache Flink 读取 Delta 表。
根据连接器的版本,您可以将其与以下 Apache Flink 版本一起使用:
Delta连接器的版本 | flink的版本 |
---|---|
0.4.x(仅限接收器) | 1.12.0 <= X <= 1.14.5 |
0.5.0 | 1.13.0 <= X <= 1.13.6 |
0.6.0 | X >= 1.15.3 |
3.0.0 | X >= 1.16.1 |
Delta Sink写入
Metrics指标
Delta Sink currently exposes the following Flink metrics:
metric name | description | update interval |
---|---|---|
DeltaSinkRecordsOut | Counter for how many records were processed by the sink | on every record |
DeltaSinkRecordsWritten | Counter for how many records were written to the actual files on the file system | on checkpoint |
DeltaSinkBytesWritten | Counter for how many bytes were written to the actual files on the underlying file system | on checkpoint |
例子:
1. 为非分区表创建接收器
在此示例中,我们展示了如何创建一个并将其插入到 现存。DeltaSink
org.apache.flink.streaming.api.datastream.DataStream
import io.delta.flink.sink.DeltaSink;
import org.apache.flink.core.fs.Path;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.table.data.RowData;
import org.apache.flink.table.types.logical.RowType;
import org.apache.hadoop.conf.Configuration;
public DataStream<RowData> createDeltaSink(
DataStream<RowData> stream,
String deltaTablePath,
RowType rowType) {
DeltaSink<RowData> deltaSink = DeltaSink
.forRowData(
new Path(deltaTablePath),
new Configuration(),
rowType)
.build();
stream.sinkTo(deltaSink);
return stream;
}
2. 为分区表创建接收器
在此示例中,我们展示了如何创建一个 for to 使用一个分区列将数据写入分区表。DeltaSink
org.apache.flink.table.data.RowData
surname
import io.delta.flink.sink.DeltaBucketAssigner;
import io.delta.flink.sink.DeltaSinkBuilder;
public DataStream<RowData> createDeltaSink(
DataStream<RowData> stream,
String deltaTablePath) {
String[] partitionCols = { "surname" };
DeltaSink<RowData> deltaSink = DeltaSink
.forRowData(
new Path(deltaTablePath),
new Configuration(),
rowType)
.withPartitionColumns(partitionCols)
.build();
stream.sinkTo(deltaSink);
return stream;
}
3. 通过对 Delta 独立多群集的支持创建接收器
在此示例中,我们将展示如何使用多集群配置进行创建。DeltaSink
public DataStream<RowData> createDeltaSink(
DataStream<RowData> stream,
String deltaTablePath) {
String[] partitionCols = { "surname" };
Configuration configuration = new Configuration();
configuration.set("spark.hadoop.fs.s3a.access.key", "USE_YOUR_S3_ACCESS_KEY_HERE");
configuration.set("spark.hadoop.fs.s3a.secret.key", "USE_YOUR_S3_SECRET_KEY_HERE");
configuration.set("spark.delta.logStore.s3a.impl", "io.delta.storage.S3DynamoDBLogStore");
configuration.set("spark.io.delta.storage.S3DynamoDBLogStore.ddb.region", "eu-central-1");
DeltaSink<RowData> deltaSink = DeltaSink
.forRowData(
new Path(deltaTablePath),
configuration,
rowType)
.build();
stream.sinkTo(deltaSink);
return stream;
}
delta 源
模式
增量源可以在下面所述的两种模式之一中工作。
该类提供工厂方法来为这两种模式创建源代码。有关详细信息,请参阅文档和示例。DeltaSource
有界模式
适用于批处理作业,我们只想读取特定表版本的 Delta 表的内容。使用 API 创建此模式的源。DeltaSource.forBoundedRowData
与此模式相关的选项包括
versionAsOf
- 加载该版本的增量表的状态。timestampAsOf
- 在给定时间戳或之前写入的表版本加载 Delta 表的状态。columnNames
- 要阅读的列。如果未提供,增量源源将读取所有列。
连续模式
适用于流式处理作业,我们希望在其中持续检查 Delta 表以获取新的更改和版本。使用 API 创建此模式的源。DeltaSource.forContinuousRowData
请注意,默认情况下,增量源将加载最新增量表的完整状态,然后开始流式传输更改。在 上使用 或 API 时,增量源将仅处理来自相应历史版本的更改。startingTimestamp
startingVersion
ContinuousDeltaSourceBuilder
与此模式相关的选项包括
startingVersion
- 开始读取此表版本中的更改。startingTimestamp
- 开始从给定时间戳或之后写入的表版本读取更改。updateCheckIntervalMillis
- 我们将检查基础 Delta 表是否有任何更改的时间间隔(以毫秒为单位)。ignoreDeletes
- 设置为 时,增量源将能够处理删除数据的表版本,并跳过这些已删除的记录。true
ignoreChanges
- 设置为 时,增量源将能够处理数据已更改(即更新)的表版本,并返回这些更改的记录。请注意,这可能会导致重复处理,因为某些 Delta 操作(如 )可能会导致在新文件中重写现有行。这些新文件将被视为新数据并重新处理。此选项包含 。因此,如果设置为 ,则流不会因删除或更新源表而中断。true
UPDATE
ignoreDeletes
ignoreChanges
true
columnNames
- 要阅读的列。如果未提供,增量源源将读取所有列。
表架构发现
Flink 增量源连接器将使用增量表日志来发现列及其类型。 如果用户未在源定义中指定任何列,则将读取基础 Delta 表中的所有列。 如果用户使用 Delta 源生成器方法指定了列名的集合,则只会从基础 Delta 表中读取这些列。 在这两种情况下,源连接器都会发现每列的增量类型是什么,并将它们转换为相应的 Flink 类型。
分区列发现
Flink 增量源连接器将使用增量表日志来确定哪些列是分区列。 用户端无需执行其他操作。
例子
1. 创建 Delta 表的源代码,以在有界模式下读取所有列。适用于批处理作业。此示例加载最新的表版本。
import org.apache.flink.api.common.eventtime.WatermarkStrategy;
import org.apache.flink.core.fs.Path;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.table.data.RowData;
import org.apache.hadoop.conf.Configuration;
public DataStream<RowData> createBoundedDeltaSourceAllColumns(
StreamExecutionEnvironment env,
String deltaTablePath) {
DeltaSource<RowData> deltaSource = DeltaSource
.forBoundedRowData(
new Path(deltaTablePath),
new Configuration())
.build();
return env.fromSource(deltaSource, WatermarkStrategy.noWatermarks(), "delta-source");
}
2. 为Delta表创建源,以在有界模式下读取所有列。适用于批处理作业。此示例执行时间旅行并加载历史版本。
public DataStream<RowData> createBoundedDeltaSourceWithTimeTravel(
StreamExecutionEnvironment env,
String deltaTablePath) {
DeltaSource<RowData> deltaSource = DeltaSource
.forBoundedRowData(
new Path(deltaTablePath),
new Configuration())
// could also use `.versionAsOf(314159)`
.timestampAsOf("2022-06-28 04:55:00")
.build();
return env.fromSource(deltaSource, WatermarkStrategy.noWatermarks(), "delta-source");
}
3. 为 Delta 表创建源,以在有界模式下仅读取用户定义的列。适用于批处理作业。此示例加载最新的表版本。
public DataStream<RowData> createBoundedDeltaSourceUserColumns(
StreamExecutionEnvironment env,
String deltaTablePath,
String[] columnNames) {
DeltaSource<RowData> deltaSource = DeltaSource
.forBoundedRowData(
new Path(deltaTablePath),
new Configuration())
.columnNames(columnNames)
.build();
return env.fromSource(deltaSource, WatermarkStrategy.noWatermarks(), "delta-source");
}
4. 为增量表创建源,以连续模式读取所有列。适用于流式传输作业。此示例执行时间旅行以获取历史版本及其之后的所有更改,然后监视更改。它不会在该历史版本加载完整的表状态。
public DataStream<RowData> createContinuousDeltaSourceWithTimeTravel(
StreamExecutionEnvironment env,
String deltaTablePath) {
DeltaSource<RowData> deltaSource = DeltaSource
.forContinuousRowData(
new Path(deltaTablePath),
new Configuration())
// could also use `.startingVersion(314159)`
.startingTimestamp("2022-06-28 04:55:00")
.build();
return env.fromSource(deltaSource, WatermarkStrategy.noWatermarks(), "delta-source");
}
5. 创建 Delta 表的源,以连续模式读取所有列。适用于流式传输作业。此示例加载最新的表版本,然后监视更改。
public DataStream<RowData> createContinuousDeltaSourceAllColumns(
StreamExecutionEnvironment env,
String deltaTablePath) {
DeltaSource<RowData> deltaSource = DeltaSource
.forContinuousRowData(
new Path(deltaTablePath),
new Configuration())
.build();
return env.fromSource(deltaSource, WatermarkStrategy.noWatermarks(), "delta-source");
}
6. 创建 Delta 表的源,在连续模式下仅读取用户定义的列。适用于流式传输作业。此示例加载最新的表版本,然后监视更改。
public DataStream<RowData> createContinuousDeltaSourceUserColumns(
StreamExecutionEnvironment env,
String deltaTablePath,
String[] columnNames) {
DeltaSource<RowData> deltaSource = DeltaSource
.forContinuousRowData(
new Path(deltaTablePath),
new Configuration())
.columnNames(columnNames)
.build();
return env.fromSource(deltaSource, WatermarkStrategy.noWatermarks(), "delta-source");
}
SQL 支持
从版本 3.0.0 开始,Delta 连接器可用于 Flink SQL 作业。 Delta Source 和 Delta Sink 都可以用作 SELECT 和 INSERT 查询的 Flink 表。
Flink/Delta SQL 连接器必须与 Delta Catalog 一起使用。尝试对增量表执行 SQL 查询 在未配置增量目录的情况下使用 Flink API 将导致 SQL 作业失败。
功能支持 | 笔记 |
---|---|
创建目录 | 增量 Flink SQL 支持需要增量目录。 |
创建数据库 | |
创建表 | |
创建类似表格 | |
更改表 | 仅支持更改表属性;不支持列和分区更改。 |
拖放表 | 从元存储中删除数据,使文件系统上的增量表文件保持不变。 |
SQL 选择 | 支持批处理(默认)和流式处理模式。 |
SQL 插入 | 支持流式传输和批处理模式。 |
delta目录
增量日志是增量表的真实来源,增量目录是唯一的 强制执行这一点的 Flink 目录实现。 每次通过 Flink SQL API 与 Delta 表进行交互时都需要它。如果您尝试使用 除增量目录之外的任何其他目录,SQL 查询都将失败。
同时,任何其他 Flink 连接器(Kafka、文件系统等)都可以与 Delta Catalog 一起使用。 (只要它没有任何自己的限制)。这是通过增量目录代理实现的 作为非增量表的代理。
但是,对于增量表,增量目录可确保任何 DDL 操作都反映在 基础增量表。换句话说,增量目录确保只有有效的增量表。 可以由 Flink 作业创建和使用。
装饰目录
增量目录充当其他目录实现的包装器。 目前,我们支持和装饰目录。 该类型是临时的,不会在外部元存储中保留任何数据。这意味着 它仅限于单个会话。in-memory
hive
in-memory
该类型基于 Flink 的 Hive 目录,其中元数据是持久性外部 Hive 元存储。 在这种情况下,用户 A 定义的表可以由用户 B 使用。hive
对于增量表,仅提供最少的信息,例如数据库/表名称、连接器类型 增量表文件路径将存储在元存储中。 对于增量表,元存储中不会存储有关表属性或架构的任何信息。 增量目录将把这些存储在 中。_delta_log
增量目录配置
通过执行以下查询来创建和命名目录:
CREATE CATALOG <catalog_name> WITH (
'type' = 'delta-catalog',
'catalog-type' = '<decorated-catalog>',
'<config_key_1>' = '<config_value_1>',
'<config_key_2>' = '<config_value_2>'
);
USE CATALOG <catalog_name>;
替换为目录的名称。 替换为要用作修饰目录的目录实现类型。 目前,仅支持(默认)目录和修饰目录。<catalog_name>
<decorated-catalog>
in-memory
hive
可以设置以下属性:
type
- 必须是 。这个选项是 Flink 所必需的。delta-catalog
catalog-type
- 一个可选选项,允许指定装饰目录的类型。允许的选项包括:in-memory
- 如果未指定其他值,则为默认值。将使用 Flink 的内存目录作为修饰目录。hive
- 使用 Flink 的 Hive 目录作为装饰目录。
任何额外定义的属性都将传递到修饰的目录。
hive元存储
由 Hive 目录支持的增量目录并使用 Hive 的目录选项调用以下查询:hadoop-conf-dir
CREATE CATALOG <catalog_name> WITH (
'type' = 'delta-catalog',
'catalog-type' = 'hive',
'hadoop-conf-dir' = '<some-path>'
);
USE CATALOG <catalog_name>;
解析配置的逻辑取决于 Flink Hive 目录的实现。 Flink Hive 目录预计,它将包含至少一个文件:hadoop-conf-dir
hadoop-conf-dir
- 核心站点.xml
- HDFS-site.xml
- 纱线站点.xml
- 地图网站.xml
配置文件中必须包含的确切属性列表取决于您 Hive 元存储终结点/服务器。可以存储在文件中的最低配置如下所示:core-site.xml
<configuration>
<property>
<name>hive.metastore.uris</name>
<value>thrift://hive-metastore:9083</value>
<description>IP address (or fully-qualified domain name) and port of the metastore host</description>
</property>
</configuration>
应解析为 Hive 元存储服务的 IP 地址。hive-metastore
为了将 Hive Catalog 与 Flink 集群一起使用,需要额外的 Flink 集群配置。简而言之,需要将文件添加到 Flink 的 lib 文件夹中,并且 通过设置 HADOOP_CLASSPATH 环境变量来提供 Hadoop 依赖项:。flink-sql-connector-hive-x-x-x.jar
export HADOOP_CLASSPATH='hadoop classpath'
我们的连接器经过以下测试:
flink-sql-connector-hive-2.3.9_2.12-1.16.0.jar
- 蜂巢 2.3.2 元存储
- Hadoop 3.3.2
建议使用 Hadoop 版本 3.3.2。使用3.3.2之前的版本时,我们遇到了许多关于不兼容的问题 Flink fs、Flink Hive 连接器和 Delta Standalone 之间的类定义。 目前,没有对Hadoop版本>3.3.2进行测试。
由不兼容的Hadoop版本引起的问题示例(Flink作业pom中的env或hadoop依赖项.xml) 部署 Flink 增量 SQL 作业时:HADOOP_CLASSPATH
<span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><span style="color:#1f2328"><span style="color:var(--fgColor-default, var(--color-fg-default))"><span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><code>Caused by: java.lang.IllegalArgumentException:
Cannot invoke org.apache.commons.configuration2.AbstractConfiguration.setListDelimiterHandler on bean class
'class org.apache.commons.configuration2.PropertiesConfiguration' - argument type mismatch -
had objects of type "org.apache.commons.configuration2.convert.DefaultListDelimiterHandler"
but expected signature "org.apache.commons.configuration2.convert.ListDelimiterHandler"
</code></span></span></span></span>
<span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><span style="color:#1f2328"><span style="color:var(--fgColor-default, var(--color-fg-default))"><span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><code>Caused by: java.lang.LinkageError: loader constraint violation: when resolving method 'void org.apache.hadoop.util.SemaphoredDelegatingExecutor.(com.google.common.util.concurrent.ListeningExecutorService, int, boolean)' the class loader org.apache.flink.util.ChildFirstClassLoader @2486925f of the current class, org/apache/hadoop/fs/s3a/S3AFileSystem, and the class loader 'app' for the method's defining class, org/apache/hadoop/util/SemaphoredDelegatingExecutor, have different Class objects for the type com/google/common/util/concurrent/ListeningExecutorService used in the signature (org.apache.hadoop.fs.s3a.S3AFileSystem is in unnamed module of loader org.apache.flink.util.ChildFirstClassLoader @2486925f, parent loader 'app'; org.apache.hadoop.util.SemaphoredDelegatingExecutor is in unnamed module of loader 'app')
at org.apache.hadoop.fs.s3a.S3AFileSystem.create(S3AFileSystem.java:769)
at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:1118)
at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:1098)
at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:987)
at io.delta.storage.S3SingleDriverLogStore.write(S3SingleDriverLogStore.java:299)
</code></span></span></span></span>
<span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><span style="color:#1f2328"><span style="color:var(--fgColor-default, var(--color-fg-default))"><span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><code>java.lang.NoSuchMethodError: org.apache.hadoop.util.SemaphoredDelegatingExecutor.<init>(Lcom/google/common/util/concurrent/ListeningExecutorService;IZ)V
at org.apache.hadoop.fs.s3a.S3AFileSystem.create(S3AFileSystem.java:769)
at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:1195)
at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:1175)
at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:1064)
at io.delta.storage.S3SingleDriverLogStore.write(S3SingleDriverLogStore.java:299)
at io.delta.standalone.internal.storage.DelegatingLogStore.write(DelegatingLogStore.scala:91)
</code></span></span></span></span>
增量目录表缓存
作为性能优化,增量目录会自动缓存增量表, 因为这些表重新计算的成本可能很高。
此缓存的默认大小为 100(表),并使用 LRU 策略逐出旧的缓存条目。 您可以通过将 deltaCatalogTableCacheSize 添加到 Flink 集群的 Hadoop配置。请注意,此配置将对每个 在群集上运行的增量目录实例。有关详细信息,请参阅 Hadoop 配置部分。
DDL 命令
创建数据库
默认情况下,增量目录将使用数据库。 使用以下示例创建单独的数据库:default
CREATE DATABASE custom_DB;
USE custom_DB;
创建表
创建非分区表使用语句:CREARTE TABLE
CREATE TABLE testTable (
id BIGINT,
data STRING
) WITH (
'connector' = 'delta',
'table-path' = '<path-to-table>',
'<arbitrary-user-define-table-property' = '<value>',
'<delta.*-properties>' = '<value'>
);
要创建分区表,请使用:PARTITIONED BY
CREATE TABLE testTable (
id BIGINT,
data STRING,
part_a STRING,
part_b STRING
)
PARTITIONED BY (part_a, part_b);
WITH (
'connector' = 'delta',
'table-path' = '<path-to-table>',
'<arbitrary-user-define-table-property' = '<value>',
'<delta.*-properties>' = '<value'>
);
Delta 连接器支持所有 Flink 的表模式类型。
目前不支持语句中的计算列和元数据列、主键和水印定义。CREATE TABLE
必需的 DDL 选项包括:
connector
必须设置为“增量”table-path
增量表的路径(文件系统、S3 等)。 如果文件系统上不存在该表,则会为您创建该表。
此外,对于必需选项,增量表的 DDL 可以接受其他表属性。 这些属性将保存到已创建表的_delta_log中。但是,它们不会被使用 在处理过程中通过三角连接器。
不允许将属性作为 DDL 中定义的表属性:
- 特定于作业的属性,例如:
- 版本如
- 时间戳作为
- 开始时间戳
- 模式
- 忽略更改
- 忽略删除
- 增量独立日志存储配置,例如属性
delta.logStore.*
- “镶木地板格式”选项,例如
parquet.*
创建增量表
执行 Delta 连接器时,我们可能有两种情况:CREATE TABLE
- 下不存在增量表
table-path
- 增量表已存在于
table-path
在第一种情况下,增量目录将创建增量表文件夹并初始化 具有 DDL 中定义的架构的空(零行)增量表。此外,DDL 中定义的所有表属性 除外,将添加到增量表元数据中。最重要的是元存储条目 将创建新表。connector
table-path
在第二种情况下,如果已存在于指定 下,增量目录将在以下情况下引发异常:_delta_log
tabl-path
- DDL 架构与架构不匹配。
_delta_log
- DDL 分区定义与 中的分区定义不匹配。
_delta_log
- DDL 中的表属性将覆盖 中的现有表属性
_delta_log
如果上述所有检查均通过,增量目录将为新表添加元存储条目,并将 将新的表属性添加到现有的 ._delta_log
创建类似表格
要创建与另一个表具有相同架构、分区和表属性的表,请使用 。CREATE TABLE LIKE
CREATE TABLE testTable (
id BIGINT,
data STRING
) WITH (
'connector' = 'delta',
'table-path' = '<path-to-table>'
);
CREATE TABLE likeTestTable
WITH (
'connector' = 'delta',
'table-path' = '%s'
) LIKE testTable;
更改表
增量连接器仅支持:
- 改变表名,
- 改变表属性值,
- 添加新表属性。
ALTER TABLE sourceTable SET ('userCustomProp'='myVal1')
ALTER TABLE sourceTable RENAME TO newSourceTable
拖放表
要删除表,请运行:
DROP TABLE sample;
此操作将仅删除元存储条目。不会删除任何增量表文件。
使用 SQL 进行查询
选择查询
增量连接器支持 Flink 作业的批处理(默认)和流式读取。 为了在模式下运行查询:SELECT
batch
SELECT * FROM testTable;
上面的查询将读取所有记录并停止。它适用于 Flink 作业。testTable
BATCH
为了在模式下运行查询:SELECT
streaming
SELECT * FROM testTable /*+ OPTIONS('mode' = 'streaming') */;
上述查询将读取所有记录,并将继续监视基础增量表 对于任何新数据(追加)。testTable
上面的两个查询都将读取 Delta 表中的所有列。为了指定列的子集 应该读取,在语句中指定这些列,而不是像这样使用:SELECT
*
SELECT col1, col2, col3 FROM testTable;
有关 Flink 声明的更多详细信息,请查看 Flink SELECT 文档。SELECT
插入查询
要使用 Flink 作业将新数据附加到 Delta 表中,请使用语句。INSERT INTO
在调用的 Delta 表中插入三行并停止。sinkTable
INSERT INTO sinkTable VALUES
('a', 'b', 1),
('c', 'd', 2),
('e', 'f', 3);
对于下面的示例,假定引用增量表(增量连接器)。 将调用的表的全部内容插入 Delta 表并停止。表架构必须匹配。sourceTable
sourceTable
sinkTable
INSERT INTO sinkTable SELECT * FROM sourceTable;
将整个数据插入到静态分区下的 Delta 表中并停止。sourceTable
sinkTable
region = europe
INSERT INTO sinkTable PARTITION (region='europe') SELECT * FROM sourceTable;
创建一个连续查询,该查询将调用的表的全部内容插入到 Delta 表中,并持续监视新数据。sourceTable
sinkTable
sourceTable
INSERT INTO sinkTable SELECT * FROM sourceTable /*+ OPTIONS('mode' = 'streaming') */;
Hadoop 配置
Delta Connector 将解析 Flink 集群 Hadoop 配置,以便使用诸如 增量日志存储属性或增量目录缓存大小。
对于 SQL 作业,Delta 连接器将在指定中解析 Flink 集群 hadoop 配置,其优先级更高/更低:
HADOOP_HOME
环境变量- hdfs-default.xml 指向已弃用的 flink 配置选项(已弃用),
fs.hdfs.hdfsdefault
HADOOP_CONF_DIR
环境变量- Flink 集群配置中的属性前缀为 .
flink.hadoop
SQL API 限制
Delta 连接器当前仅支持物理列。“元数据”和“计算”列 当前不受支持。有关详细信息,请参阅此处。
其他不支持的功能:
- 创建表语句的水印定义。
- 创建表语句的主键定义。
- 架构 ALTER 查询(创建、删除列),包括分区列。
- 表和列注释。
用法
您可以使用自己喜欢的构建工具将 Flink/Delta 连接器库添加为依赖项。请注意 它期望提供以下包:
仅限数据流 API:
delta-standalone
flink-parquet
flink-table-common
hadoop-client
表/SQL API 的其他库:
flink-clients
flink-table-planner_2.12
用于 AWS/S3 支持的其他库
- 在 Flink 集群上启用 Flink-S3-FS-Hadoop 插件的详细信息在这里
hadoop-aws
马文
有关更多详细信息,请参阅以下构建文件。
斯卡拉 2.12:
<project>
<properties>
<scala.main.version>2.12</scala.main.version>
<delta-connectors-version>3.0.0</delta-connectors-version>
<flink-version>1.16.1</flink-version>
<hadoop-version>3.1.0</hadoop-version>
</properties>
<dependencies>
<dependency>
<groupId>io.delta</groupId>
<artifactId>delta-flink</artifactId>
<version>${delta-connectors-version}</version>
</dependency>
<dependency>
<groupId>io.delta</groupId>
<artifactId>delta-standalone_${scala.main.version}</artifactId>
<version>${delta-connectors-version}</version>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-clients_${scala.main.version}</artifactId>
<version>${flink-version}</version>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-parquet_${scala.main.version}</artifactId>
<version>${flink-version}</version>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-table-common</artifactId>
<version>${flink-version}</version>
<scope>provided</scope>
</dependency>
<!-- Needed for Flink Table/SQL API -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>${hadoop-version}</version>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-table-runtime_${scala.main.version}</artifactId>
<version>${flink-version}</version>
<scope>provided</scope>
</dependency>
<!-- End needed for Flink Table/SQL API -->
<!-- Needed for AWS S3 support -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-aws</artifactId>
<version>${hadoop-version}</version>
</dependency>
<!-- End needed for AWS S3 support -->
</dependencies>
</project>
SBT
请将依赖项的版本替换为您正在使用的版本。
libraryDependencies ++= Seq(
"io.delta" %% "delta-flink" % deltaConnectorsVersion,
"io.delta" %% "delta-standalone" % deltaConnectorsVersion,
"org.apache.flink" %% "flink-clients" % flinkVersion,
"org.apache.flink" %% "flink-parquet" % flinkVersion,
"org.apache.hadoop" % "hadoop-client" % hadoopVersion,
"org.apache.flink" % "flink-table-common" % flinkVersion % "provided",
"org.apache.flink" %% "flink-table-runtime" % flinkVersion % "provided")
建筑
该项目是使用 SBT 编译的。
环境要求
- JDK 8 或以上。
- 斯卡拉 2.11 或 2.12。
生成命令
- 要编译项目,请运行
build/sbt flink/compile
- 若要测试项目,请运行
build/sbt flink/test
- 要发布 JAR,请运行
build/sbt flink/publishM2
UML 图
UML 图可以在这里找到
常见问题 (FAQ)
是否可以使用此连接器将数据追加到增量表?
是的,您可以使用此连接器将数据追加到现有或新的 Delta 表(如果没有现有的 在给定路径中增量登录,然后由连接器创建)。
我可以将此连接器与其他模式(覆盖、更新插入等)一起使用吗?
否,目前仅支持追加。将来的版本中可能会添加其他模式。
创建增量表时是否需要指定分区列?
如果您希望对数据进行分区,那么您应该这样做。如果您使用的是 , 您可以使用 API 提供分区列。DataStream API
RowDataDeltaSinkBuilder.withPartitionColumns(List<String> partitionCols)
为什么需要指定表架构?它不应该存在于基础 Delta 表元数据中还是从流的元数据中提取?
不幸的是,我们无法从泛型中提取模式信息,并且交互也需要它 与增量日志。接收器必须知道增量表的架构和流中的事件结构 命令不违反表的完整性。DataStream
如果我更改基础增量表架构怎么办?
从 到 Delta 日志执行的下一次提交(在提到的架构更改之后)将失败,除非您调用 。在这种情况下,增量独立将尝试合并两个架构并检查 它们的兼容性。如果此检查失败(例如,更改包括删除列),则对增量日志的提交将失败,这将导致 Flink 作业失败。DeltaSink
RowDataDeltaSinkBuilder::withMergeSchema(true)
本地开发与测试
- 在 IntelliJ 中对测试进行本地调试之前,请使用 SBT 运行所有测试。它将 在目标目录下生成对象,该目录为连接器提供正确版本的 连接器。
flink
flink
Meta.java
已知问题:
-
(0.4.x)由于与某些 Apache Flink 软件包存在依赖冲突,因此可能需要着色 生产胖罐时包装中的类 在将连接器部署到 Flink 集群之前使用此连接器的 Flink 作业。
org.apache.flink.streaming.api.functions.sink.filesystem
如果该包未着色,您可能会遇到如下错误:
<span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><span style="color:var(--fgColor-default, var(--color-fg-default))"><span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><code>Caused by: java.lang.IllegalAccessError: tried to access method org.apache.flink.streaming.api.functions.sink.filesystem.OutputStreamBasedPartFileWriter.<init>(Ljava/lang/Object;Lorg/apache/flink/core/fs/RecoverableFsDataOutputStream;J)V from class org.apache.flink.streaming.api.functions.sink.filesystem.DeltaBulkPartWriter </code></span></span></span>
下面是实现此目的的示例配置:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.3.0</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <shadedArtifactAttached>true</shadedArtifactAttached> <relocations> <relocation> <pattern>org.apache.flink.streaming.api.functions.sink.filesystem</pattern> <shadedPattern>shaded.org.apache.flink.streaming.api.functions.sink.filesystem</shadedPattern> </relocation> </relocations> <filters> <filter> <artifact>*:*</artifact> <excludes> <exclude>META-INF/*.SF</exclude> <exclude>META-INF/*.DSA</exclude> <exclude>META-INF/*.RSA</exclude> </excludes> </filter> </filters> </configuration> </execution> </executions> </plugin>
来源:flink-delta