Flink ClickHouse 连接器全面指南
项目介绍
Flink ClickHouse Connector 是 Apache Flink 与 ClickHouse 数据库之间的高效数据交换组件。该项目基于 ClickHouse JDBC 驱动开发,支持 Flink SQL 连接器、ClickHouse 目录(Catalog)功能,能够读写主键数据、映射和数组等复杂数据类型到 ClickHouse。
核心特性
连接器选项配置
| 选项 | 必需 | 默认值 | 类型 | 描述 |
|---|---|---|---|---|
| url | 是 | 无 | String | ClickHouse JDBC URL 格式:jdbc:(ch\|clickhouse)[:<protocol>]://endpoint1[,endpoint2,...][/<database>][?param1=value1¶m2=value2] |
| username | 可选 | 无 | String | 用户名,与密码必须同时指定 |
| password | 可选 | 无 | String | ClickHouse 密码 |
| database-name | 可选 | default | String | ClickHouse 数据库名称 |
| table-name | 是 | 无 | String | ClickHouse 表名 |
| use-local | 可选 | false | Boolean | 对于分布式表引擎,直接读写本地表 |
数据接收器(Sink)配置
| 选项 | 默认值 | 描述 |
|---|---|---|
| sink.batch-size | 1000 | 最大刷新大小,超过此值将刷新数据 |
| sink.flush-interval | 1s | 异步线程刷新数据的间隔时间 |
| sink.max-retries | 3 | 写入数据库失败时的最大重试次数 |
| sink.update-strategy | update | 更新策略:update(更新)、insert(插入)、discard(丢弃) |
| sink.partition-strategy | balanced | 分区策略:balanced(轮询)、hash(哈希分区)、shuffle(随机) |
| sink.partition-key | 无 | 哈希分区使用的分区键 |
数据类型映射
| Flink 类型 | ClickHouse 类型 |
|---|---|
| CHAR | String |
| VARCHAR | String / IP / UUID |
| STRING | String / Enum |
| BOOLEAN | UInt8 |
| BYTES | FixedString |
| DECIMAL | Decimal / Int128 / Int256 / UInt64 / UInt128 / UInt256 |
| ARRAY | Array |
| MAP | Map |
快速开始
环境准备
确保已安装 Apache Flink 并运行 ClickHouse 服务。项目暂未发布到 Maven 中央仓库,需要先部署到本地仓库:
# 克隆项目
git clone https://gitcode.com/gh_mirrors/fl/flink-connector-clickhouse
# 进入项目目录
cd flink-connector-clickhouse
# 安装到本地仓库
mvn clean install -DskipTests
Maven 依赖
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-connector-clickhouse</artifactId>
<version>1.16.0-SNAPSHOT</version>
</dependency>
创建和读写表示例
-- 在 Flink SQL 中注册 ClickHouse 表
CREATE TABLE t_user (
`user_id` BIGINT,
`user_type` INTEGER,
`language` STRING,
`country` STRING,
`gender` STRING,
`score` DOUBLE,
`list` ARRAY<STRING>,
`map` Map<STRING, BIGINT>,
PRIMARY KEY (`user_id`) NOT ENFORCED
) WITH (
'connector' = 'clickhouse',
'url' = 'jdbc:ch://127.0.0.1:8123',
'database-name' = 'tutorial',
'table-name' = 'users',
'sink.batch-size' = '500',
'sink.flush-interval' = '1000',
'sink.max-retries' = '3'
);
-- 从 ClickHouse 读取数据
SELECT user_id, user_type from t_user;
-- 将数据写入 ClickHouse 表
INSERT INTO t_user
SELECT cast(`user_id` as BIGINT), `user_type`, `lang`, `country`, `gender`, `score`,
ARRAY['CODER', 'SPORTSMAN'],
CAST(MAP['BABA', cast(10 as BIGINT), 'NIO', cast(8 as BIGINT)] AS MAP<STRING, BIGINT>)
FROM T;
使用 ClickHouse Catalog
Java 示例
TableEnvironment tEnv = TableEnvironment.create(setting);
Map<String, String> props = new HashMap<>();
props.put(ClickHouseConfig.DATABASE_NAME, "default");
props.put(ClickHouseConfig.URL, "jdbc:ch://127.0.0.1:8123");
props.put(ClickHouseConfig.USERNAME, "username");
props.put(ClickHouseConfig.PASSWORD, "password");
props.put(ClickHouseConfig.SINK_FLUSH_INTERVAL, "30s");
Catalog cHcatalog = new ClickHouseCatalog("clickhouse", props);
tEnv.registerCatalog("clickhouse", cHcatalog);
tEnv.useCatalog("clickhouse");
tEnv.executeSql("insert into `clickhouse`.`default`.`t_table` select...");
SQL 示例
CREATE CATALOG clickhouse WITH (
'type' = 'clickhouse',
'url' = 'jdbc:ch://127.0.0.1:8123',
'username' = 'username',
'password' = 'password',
'database-name' = 'default'
);
USE CATALOG clickhouse;
SELECT user_id, user_type FROM `default`.`t_user` limit 10;
INSERT INTO `default`.`t_user` SELECT ...;
架构设计
核心组件
项目采用模块化设计,主要包含以下核心组件:
- ClickHouseDynamicTableFactory - 表工厂类,负责创建源表和接收器表
- ClickHouseDynamicTableSink - 数据接收器实现
- ClickHouseDynamicTableSource - 数据源实现
- ClickHouseCatalog - Catalog 实现,用于表管理和元数据操作
- ClickHouseConnectionProvider - 连接管理组件
执行器架构
项目提供了多种执行器来处理不同的数据操作场景:
- ClickHouseBatchExecutor - 批处理执行器
- ClickHouseUpsertExecutor - Upsert 操作执行器
- AbstractClickHouseOutputFormat - 输出格式基类
- ClickHouseBatchOutputFormat - 批处理输出格式
注意事项
更新/删除数据考虑
- 分布式表限制:分布式表不支持更新/删除语句,如需使用更新/删除功能,请确保写入本地表或将
use-local设置为 true - 主键要求:数据通过主键进行更新和删除,在使用分区表时需要注意这一点
- 版本兼容性:从版本 1.16 开始,考虑了分片权重,这可能影响数据分布到哪个分片
性能优化建议
- 批处理大小:根据数据量调整
sink.batch-size参数,通常设置为 1000-5000 - 刷新间隔:根据实时性要求设置
sink.flush-interval,平衡延迟和吞吐量 - 重试机制:合理配置
sink.max-retries以提高数据写入的可靠性 - 分区策略:根据数据特征选择合适的分区策略(balanced、hash、shuffle)
应用场景
实时数据分析
利用 Flink 的流处理能力和 ClickHouse 的列式存储优势,构建实时数据分析管道:
- 用户行为分析
- 实时指标计算
- 日志处理和分析
数据集成
作为数据集成组件,连接不同的数据源和目标:
- Kafka 到 ClickHouse 的数据管道
- 数据库变更捕获(CDC)到 ClickHouse
- 实时数据仓库构建
监控和告警
结合监控系统实现实时监控和告警:
- 业务指标监控
- 系统性能监控
- 异常检测和告警
开发指南
代码结构
项目采用标准的 Maven 多模块结构:
flink-connector-clickhouse/
├── flink-connector-clickhouse/ # 主模块
│ └── src/main/java/org/apache/flink/connector/clickhouse/
│ ├── ClickHouseDynamicTableFactory.java
│ ├── ClickHouseDynamicTableSink.java
│ ├── ClickHouseDynamicTableSource.java
│ ├── catalog/ # Catalog 实现
│ ├── config/ # 配置类
│ ├── internal/ # 内部实现
│ └── util/ # 工具类
├── flink-connector-clickhouse-e2e-test/ # 端到端测试
└── flink-sql-connector-clickhouse/ # SQL 连接器
扩展开发
如需扩展功能,可以参考现有实现:
- 添加新的数据源:继承
AbstractClickHouseInputFormat - 添加新的输出格式:继承
AbstractClickHouseOutputFormat - 自定义分区策略:实现
ClickHousePartitioner接口 - 支持新的数据类型:在
DataTypeUtil中添加类型映射
故障排除
常见问题
- 连接失败:检查 ClickHouse 服务状态和网络连接
- 认证错误:验证用户名和密码配置
- 数据类型不匹配:检查 Flink 和 ClickHouse 数据类型映射
- 性能问题:调整批处理大小和刷新间隔参数
日志调试
启用详细日志记录有助于问题诊断:
# 在 log4j.properties 中配置
log4j.logger.org.apache.flink.connector.clickhouse=DEBUG
未来发展
项目目前仍在积极开发中,未来的发展方向包括:
- 完善单元测试覆盖
- 支持更多 ClickHouse 特性
- 优化性能和大规模部署
- 贡献到 Apache Flink 主项目
通过本指南,您可以快速上手使用 Flink ClickHouse Connector,构建高效的实时数据处理管道。项目提供了丰富的配置选项和灵活的架构设计,能够满足各种复杂的数据集成和分析需求。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



