Flink对接Delta 数据湖

目前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.01.13.0 <= X <= 1.13.6
0.6.0X >= 1.15.3
3.0.0X >= 1.16.1

Delta Sink写入

Metrics指标

Delta Sink currently exposes the following Flink metrics:

metric namedescriptionupdate interval
DeltaSinkRecordsOutCounter for how many records were processed by the sinkon every record
DeltaSinkRecordsWrittenCounter for how many records were written to the actual files on the file systemon checkpoint
DeltaSinkBytesWrittenCounter for how many bytes were written to the actual files on the underlying file systemon checkpoint

例子:

1. 为非分区表创建接收器

在此示例中,我们展示了如何创建一个并将其插入到 现存。DeltaSinkorg.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 使用一个分区列将数据写入分区表。DeltaSinkorg.apache.flink.table.data.RowDatasurname

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 时,增量源将仅处理来自相应历史版本的更改。startingTimestampstartingVersionContinuousDeltaSourceBuilder

与此模式相关的选项包括

  • startingVersion- 开始读取此表版本中的更改。
  • startingTimestamp- 开始从给定时间戳或之后写入的表版本读取更改。
  • updateCheckIntervalMillis- 我们将检查基础 Delta 表是否有任何更改的时间间隔(以毫秒为单位)。
  • ignoreDeletes- 设置为 时,增量源将能够处理删除数据的表版本,并跳过这些已删除的记录。true
  • ignoreChanges- 设置为 时,增量源将能够处理数据已更改(即更新)的表版本,并返回这些更改的记录。请注意,这可能会导致重复处理,因为某些 Delta 操作(如 )可能会导致在新文件中重写现有行。这些新文件将被视为新数据并重新处理。此选项包含 。因此,如果设置为 ,则流不会因删除或更新源表而中断。trueUPDATEignoreDeletesignoreChangestrue
  • 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-memoryhivein-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-memoryhive

可以设置以下属性:

  • 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-dirhadoop-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.jarexport 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 中定义的所有表属性 除外,将添加到增量表元数据中。最重要的是元存储条目 将创建新表。connectortable-path

在第二种情况下,如果已存在于指定 下,增量目录将在以下情况下引发异常:_delta_logtabl-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 作业的批处理(默认)和流式读取。 为了在模式下运行查询:SELECTbatch

SELECT * FROM testTable;

上面的查询将读取所有记录并停止。它适用于 Flink 作业。testTableBATCH

为了在模式下运行查询:SELECTstreaming

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 表并停止。表架构必须匹配。sourceTablesourceTablesinkTable

INSERT INTO sinkTable SELECT * FROM sourceTable;

将整个数据插入到静态分区下的 Delta 表中并停止。sourceTablesinkTableregion = europe

INSERT INTO sinkTable PARTITION (region='europe') SELECT * FROM sourceTable;

创建一个连续查询,该查询将调用的表的全部内容插入到 Delta 表中,并持续监视新数据。sourceTablesinkTablesourceTable

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 支持的其他库

马文

有关更多详细信息,请参阅以下构建文件。

斯卡拉 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 APIRowDataDeltaSinkBuilder.withPartitionColumns(List<String> partitionCols)

为什么需要指定表架构?它不应该存在于基础 Delta 表元数据中还是从流的元数据中提取?

不幸的是,我们无法从泛型中提取模式信息,并且交互也需要它 与增量日志。接收器必须知道增量表的架构和流中的事件结构 命令不违反表的完整性。DataStream

如果我更改基础增量表架构怎么办?

从 到 Delta 日志执行的下一次提交(在提到的架构更改之后)将失败,除非您调用 。在这种情况下,增量独立将尝试合并两个架构并检查 它们的兼容性。如果此检查失败(例如,更改包括删除列),则对增量日志的提交将失败,这将导致 Flink 作业失败。DeltaSinkRowDataDeltaSinkBuilder::withMergeSchema(true)

本地开发与测试

  • 在 IntelliJ 中对测试进行本地调试之前,请使用 SBT 运行所有测试。它将 在目标目录下生成对象,该目录为连接器提供正确版本的 连接器。flinkflinkMeta.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​​​​​​​

<think>好的,用户想了解关于数据湖Paimon的学习教程。首先,我需要确认Paimon是什么。根据我的知识,Apache Paimon(原名Flink Table Store)是一个流式数据湖平台,与Apache Flink紧密集成,支持实时数据分析和更新。用户可能想学习如何使用它进行大数据处理。 接下来,我需要考虑用户可能的背景。他们可能是大数据开发者或数据工程师,对数据湖技术有一定了解,但需要具体的学习资源。用户可能希望从基础开始,逐步掌握Paimon的核心概念和实际操作。 然后,我需要整理学习路径。通常,学习新技术需要从官方文档开始,然后是快速入门指南,接着是核心概念,比如数据存储结构、流批一体、实时更新等。实践部分包括环境搭建、数据读写、与Flink集成以及优化技巧。可能还需要社区资源和进阶内容,如源码贡献和案例研究。 还要注意用户提到的格式要求:行内公式用$...$,独立公式用$$...$$。虽然Paimon的内容可能不涉及太多数学公式,但如果有性能指标或算法,可能需要适当使用LaTeX,比如写入性能$O(n)$,查询延迟$T$等。 需要确保回答结构清晰,分步骤介绍,帮助用户系统地学习。同时检查资源链接是否有效,推荐书籍、社区等是否相关。可能还需要提醒用户实践的重要性,以及如何参与社区获取帮助。 最后,验证信息准确性,比如确认Paimon的最新版本和功能,避免过时的内容。确保推荐的学习资源是当前权威的,比如官方网站、GitHub仓库和Flink相关文档。</think>以下为Apache Paimon(原Flink Table Store)的系统化学习路径,采用分阶段结构帮助您掌握核心技术: $$ \text{学习路径} = \text{基础理论} \oplus \text{环境实践} \oplus \text{高级特性} $$ ### 一、基础准备阶段 1. **核心概念理解** - 数据湖核心特征:支持ACID事务、Schema演化、流批统一处理 - 技术定位:面向流式数据处理的Table Storage(区别于Hudi/Delta/Iceberg) - 架构优势:低延迟数据摄入($\leq 5min$)、实时更新能力、高并发查询 2. **官方文档精读** - 必读章节: ```markdown - 架构设计原理(LSM结构 + 列式存储) - 数据版本管理(MVCC实现机制) - 流式CDC对接方案 - 性能优化白皮书 ``` ### 二、环境搭建实践 1. **本地开发环境** ```shell # Maven依赖配置示例 <dependency> <groupId>org.apache.paimon</groupId> <artifactId>paimon-flink</artifactId> <version>0.6</version> </dependency> ``` 2. **Flink集成配置** ```sql -- Flink SQL 表声明示例 CREATE TABLE user_behavior ( user_id BIGINT, item_id BIGINT, action STRING, dt STRING ) WITH ( 'connector' = 'paimon', 'path' = 'file:///tmp/paimon/user_behavior', 'auto-create' = 'true' ); ``` ### 三、核心功能实践 1. **数据写入模式对比** | 模式 | 语法示例 | 适用场景 | |---|---| ---| | 流式写入 | `INSERT INTO user_behavior SELECT ...` | 实时数据管道 | | 批量导入 | `BATCH INSERT INTO ...` | 历史数据迁移 | 2. **实时更新演示** ```sql -- 创建支持主键的表 CREATE TABLE user_profile ( user_id BIGINT PRIMARY KEY, name STRING, last_login TIMESTAMP ) WITH (...); -- 使用CDC数据更新 INSERT INTO user_profile SELECT user_id, name, login_time FROM kafka_cdc_source; ``` ### 四、进阶优化技巧 1. **存储优化公式** $$ Q_{\text{优化}} = \frac{\text{Compaction频率}}{\text{文件大小阈值}} \times \text{索引效率} $$ - 配置建议: ```properties # 合并策略 compaction.max.file-num = 10 # 列式存储优化 format.compression-codec = zstd ``` 2. **查询加速方案** - 物化视图构建: ```sql CREATE MATERIALIZED VIEW daily_active_users PARTITIONED BY (dt) AS SELECT dt, COUNT(DISTINCT user_id) FROM user_behavior GROUP BY dt; ``` ### 五、学习资源矩阵 1. **官方渠道** - GitHub仓库:https://github.com/apache/paimon - 最新文档:https://paimon.apache.org/docs/master/ 2. **实践案例库** - 电商实时数仓构建(含Flink SQL模板) - IoT设备状态管理方案 - 金融交易流水分析场景 建议学习路线:每日投入$2\text{h}$,按"文档精读 → 示例复现 → 项目移植"三阶段推进,8周可达到生产级应用水平。遇到问题优先查阅GitHub Issues历史记录(问题匹配度$\geq 85\%$),其次通过dev邮件列表提问。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值