Flink ClickHouse 连接器维表源码深度解析

在 Flink ClickHouse Connector 中,维表(Lookup Table)功能允许在流处理过程中实时地从外部数据库(这里是 ClickHouse)中查询数据,用于丰富流中的记录。下面我们将深入分析 ClickHouse 维表相关的源码。

1. 维表支持概述

Flink 提供了 LookupTableSource 接口来支持维表功能,ClickHouseDynamicTableSource 实现了这个接口,从而使得 ClickHouse 可以作为维表使用。

2. ClickHouseDynamicTableSource 类分析

2.1 类定义和接口实现
java 复制代码
public class ClickHouseDynamicTableSource
        implements ScanTableSource,
                LookupTableSource,
                SupportsProjectionPushDown,
                SupportsLimitPushDown,
                SupportsFilterPushDown {

ClickHouseDynamicTableSource 实现了多个接口,其中 LookupTableSource 是实现维表功能的关键接口。

2.2 构造函数
java 复制代码
public ClickHouseDynamicTableSource(
        ClickHouseReadOptions readOptions,
        int lookupMaxRetryTimes,
        @Nullable LookupCache cache,
        Properties properties,
        DataType physicalRowDataType) {
    this.readOptions = readOptions;
    this.connectionProperties = properties;
    this.lookupMaxRetryTimes = lookupMaxRetryTimes;
    this.cache = cache;
    this.physicalRowDataType = physicalRowDataType;
}

构造函数接收多个参数,包括读取选项、最大重试次数、缓存对象、连接属性和物理行数据类型。

2.3 getLookupRuntimeProvider 方法
java 复制代码
@Override
public LookupRuntimeProvider getLookupRuntimeProvider(LookupContext context) {
    // ClickHouse only support non-nested look up keys
    String[] keyNames = new String[context.getKeys().length];
    for (int i = 0; i < keyNames.length; i++) {
        int[] innerKeyArr = context.getKeys()[i];
        Preconditions.checkArgument(
                innerKeyArr.length == 1, "ClickHouse only support non-nested look up keys");
        keyNames[i] = DataType.getFieldNames(physicalRowDataType).get(innerKeyArr[0]);
    }
    final RowType rowType = (RowType) physicalRowDataType.getLogicalType();
    ClickHouseRowDataLookupFunction lookupFunction =
            new ClickHouseRowDataLookupFunction(
                    readOptions,
                    lookupMaxRetryTimes,
                    DataType.getFieldNames(physicalRowDataType).toArray(new String[0]),
                    DataType.getFieldDataTypes(physicalRowDataType).toArray(new DataType[0]),
                    keyNames,
                    rowType);
    if (cache != null) {
        return PartialCachingLookupProvider.of(lookupFunction, cache);
    } else {
        return LookupFunctionProvider.of(lookupFunction);
    }
}
  • 获取维表查询键 :通过 LookupContext 获取维表查询的键,并确保这些键是非嵌套的。
  • 创建 ClickHouseRowDataLookupFunction:该函数用于实际执行从 ClickHouse 中查询维表数据的操作。
  • 缓存支持 :如果配置了缓存(cache 不为 null),则使用 PartialCachingLookupProvider 来提供带有缓存功能的维表查询;否则,直接使用 LookupFunctionProvider 提供基本的维表查询。
2.4 ClickHouseRowDataLookupFunction

这个类是实现维表查询的核心类,它继承自 RichFunction,用于在运行时执行维表查询。虽然代码中没有直接给出该类的详细实现,但可以推测它会使用 ClickHouseReadOptions 中的配置信息,通过 JDBC 连接到 ClickHouse 数据库,并根据查询键执行 SQL 查询。

3. 维表查询的流程

  1. 定义维表 :在 Flink SQL 中,使用 CREATE TABLE 语句定义一个 ClickHouse 表作为维表。
sql 复制代码
CREATE TABLE clickhouse_lookup_table (
    id INT,
    name STRING,
    -- 其他字段
    PRIMARY KEY (id) NOT ENFORCED
) WITH (
    'connector' = 'clickhouse',
    'url' = 'jdbc:ch://127.0.0.1:8123',
    'database-name' = 'tutorial',
    'table-name' = 'lookup_table',
    -- 其他配置
);
  1. 流表与维表关联 :在 SQL 查询中,使用 JOIN 操作将流表与维表关联起来。
sql 复制代码
SELECT s.id, l.name
FROM stream_table s
JOIN clickhouse_lookup_table FOR SYSTEM_TIME AS OF s.proctime() l
ON s.id = l.id;
  1. 运行时查询 :在流处理过程中,Flink 会根据 ClickHouseRowDataLookupFunction 从 ClickHouse 中查询维表数据,并将结果与流数据进行关联。

4. 缓存支持

为了提高维表查询的性能,Flink 支持对维表数据进行缓存。通过配置 LookupOptions 中的相关参数,可以启用部分缓存(PARTIAL)。

java 复制代码
options.add(LookupOptions.CACHE_TYPE, LookupOptions.LookupCacheType.PARTIAL);
options.add(LookupOptions.PARTIAL_CACHE_EXPIRE_AFTER_ACCESS, Duration.ofMinutes(5));
options.add(LookupOptions.PARTIAL_CACHE_EXPIRE_AFTER_WRITE, Duration.ofMinutes(10));
options.add(LookupOptions.PARTIAL_CACHE_MAX_ROWS, 10000L);

getLookupRuntimeProvider 方法中,如果配置了缓存,会使用 PartialCachingLookupProvider 来管理缓存和查询操作。

5. 总结

Flink ClickHouse Connector 的维表支持通过 ClickHouseDynamicTableSource 类和 ClickHouseRowDataLookupFunction 类实现。它允许在流处理过程中实时地从 ClickHouse 中查询数据,并支持缓存功能以提高性能。在使用时,需要在 SQL 中定义维表并进行关联,Flink 会自动处理维表查询和数据关联的逻辑。

相关推荐
派大鑫wink13 分钟前
【Day7】构造方法与 this 关键字:初始化对象的正确姿势
java·开发语言
JIngJaneIL14 分钟前
基于java+ vue办公管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端
超级大只老咪21 分钟前
速通:类,对象,方法(Java)
java
毕设源码-郭学长23 分钟前
【开题答辩全过程】以 基于SpringBoot的企业销售合同管理设计与实现为例,包含答辩的问题和答案
java·spring boot·后端
while(1){yan}23 分钟前
JVM八股文
java·开发语言·jvm·java-ee
jiayong2324 分钟前
Spring AI Alibaba 深度解析(一):框架概述与核心功能
java·人工智能·spring
AAA简单玩转程序设计24 分钟前
Java 异常处理:3 个 “避坑神操作”,告别崩溃式报错
java
徐老总25 分钟前
圆形(Circle)和矩形(Rectangle)两个样例类
java
一只努力的微服务27 分钟前
【Calcite 系列】将 INTERSECT 转换为 EXISTS
java·calcite
向往着的青绿色27 分钟前
编程式事务,更加精细化的控制
java·开发语言·数据库·spring·性能优化·个人开发·设计规范