前面 FLink 的文章中我们已经介绍了说 Flink 已经有很多自带的 Connector。

本文详细介绍了如何使用Flink的Elasticsearch连接器,将Kafka数据读取并存储到ElasticSearch中。包括如何封装自带的Sink,扩展配置及FailureHandler的处理策略,确保数据完整性和处理线上常见问题。

https://www.cnblogs.com/Allen-rg/p/11593528.html

1、《从0到1学习Flink》—— Data Source 介绍

2、《从0到1学习Flink》—— Data Sink 介绍

其中包括了 Source 和 Sink 的,后面我也讲了下如何自定义自己的 Source 和 Sink。

那么今天要做的事情是啥呢?就是介绍一下 Flink 自带的 ElasticSearch Connector,我们今天就用他来做 Sink,将 Kafka 中的数据经过 Flink 处理后然后存储到 ElasticSearch。

准备

安装 ElasticSearch,这里就忽略,自己找我以前的文章,建议安装 ElasticSearch 6.0 版本以上的,毕竟要跟上时代的节奏。

下面就讲解一下生产环境中如何使用 Elasticsearch Sink 以及一些注意点,及其内部实现机制。

 

Elasticsearch Sink

添加依赖

1

2

3

4

5

<dependency>

    <groupId>org.apache.flink</groupId>

    <artifactId>flink-connector-elasticsearch6_${scala.binary.version}</artifactId>

    <version>${flink.version}</version>

</dependency>

  

上面这依赖版本号请自己根据使用的版本对应改变下。

下面所有的代码都没有把 import 引入到这里来,如果需要查看更详细的代码,请查看我的 GitHub 仓库地址:

https://github.com/zhisheng17/flink-learning/tree/master/flink-learning-connectors/flink-learning-connectors-es6

这个 module 含有本文的所有代码实现,当然越写到后面自己可能会做一些抽象,所以如果有代码改变很正常,请直接查看全部项目代码。

ElasticSearchSinkUtil 工具类

这个工具类是自己封装的,getEsAddresses 方法将传入的配置文件 es 地址解析出来,可以是域名方式,也可以是 ip + port 形式。

addSink 方法是利用了 Flink 自带的 ElasticsearchSink 来封装了一层,传入了一些必要的调优参数和 es 配置参数,下面文章还会再讲些其他的配置。

ElasticSearchSinkUtil.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

public class ElasticSearchSinkUtil {

 

    /**

     * es sink

     *

     * @param hosts es hosts

     * @param bulkFlushMaxActions bulk flush size

     * @param parallelism 并行数

     * @param data 数据

     * @param func

     * @param <T>

     */

    public static <T> void addSink(List<HttpHost> hosts, int bulkFlushMaxActions, int parallelism,

                                   SingleOutputStreamOperator<T> data, ElasticsearchSinkFunction<T> func) {

        ElasticsearchSink.Builder<T> esSinkBuilder = 

你执行了: ```bash jar -tvf flink-sql-connector-kafka-1.17.2.jar | grep "ConnectException" ``` 👉 **没有输出任何结果**,明这个 JAR 中 **确实不包含 `org/apache/kafka/connect/errors/ConnectException.class`** 这很关键! --- ## ✅ 结论先行 > ❌ 你当前使用的 `flink-sql-connector-kafka-1.17.2.jar` 是一个 **"shaded"(重命名)版本但排除了 Kafka Connect 类的构建包** > ⚠️ 它无法支持 `debezium-json` 或 `canal-json` 格式,因为缺少必要的类模型 > ✅ 解决方案:你需要使用 **Flink 官方发行版中自带的完整包**,或手动添加 `flink-json-schema` 支持 --- ## 🔍 深入分析:为什么找不到 `ConnectException`? ### 📦 原因一:官方发布的 `flink-sql-connector-kafka-1.17.2.jar` 是 “minimal” 版本 从 Flink 1.16 开始,Apache 官方为了减少依赖体积,发布到 Maven 的: ``` flink-sql-connector-kafka_2.12-1.17.2.jar ``` 👉 是一个 **精简版(minimal)JAR**,它: - 不包含 `kafka-clients` - 不包含 `debezium-json` / `canal-json` 所需的 Kafka Connect 类 - 只提供接口和工厂类,运行时需要你自己补全依赖 📌 这个 JAR **不能单独用于 CDC + Debezium JSON 场景!** --- ## ✅ 正确解决方案:使用 Flink 发行版中的完整包 你应该去下载 **Flink 官方二进制发行版(Binary Distribution)**,里面包含了完整的、可用于 SQL Client 的 connector 包。 ### ✅ 步骤如下: #### 1. 下载 Flink 1.17.2 官方二进制包 ```bash wget https://archive.apache.org/dist/flink/flink-1.17.2/flink-1.17.2-bin.tgz tar -xzf flink-1.17.2-bin.tgz cd flink-1.17.2 ``` #### 2. 找到目录下的 Kafka Connector 插件目录 ```bash ls -l lib/ # 应该看到类似: # flink-dist-1.17.2.jar # log4j-*.jar # slf4j-*.jar ``` 然后进入插件目录(如果存在): ```bash ls -l ./opt/ # 查看是否有: # flink-sql-connector-kafka-1.17.2.jar ``` 如果没有,去官方下载页面找对应的 **“SQL Connector” 插件包** --- ### ✅ 推荐方式:直接下载带有 Debezium 支持的 Kafka Connector 插件 前往: 🔗 https://flink.apache.org/downloads.html ➡️ 选择 “Flink SQL Connector for Kafka” ➡️ 下载适用于 1.17.2 的版本 或者直链(示例): ```bash wget https://repo.maven.apache.org/maven2/org/apache/flink/flink-sql-connector-kafka/1.17.2/flink-sql-connector-kafka-1.17.2.jar ``` 但这还是那个 minimal 版本 ❌ 所以我们换一种思路👇 --- ## ✅ 终极解决方案:使用 `flink-json-schema` + `kafka-clients` 既然官方 minimal 包不带 Connect 类,我们就 **手动补齐所需依赖** ### ✔️ 需要添加以下 JAR 到 `$FLINK_HOME/lib/`: | JAR | 作用 | 下载地址 | |-----|------|---------| | `flink-json-1.17.2.jar` | 提供 JSON format 基础支持 | [Maven](https://repo.maven.apache.org/maven2/org/apache/flink/flink-json/1.17.2/) | | `kafka-clients-2.8.1.jar` | Kafka 客户端核心库 | [Maven](https://repo.maven.apache.org/maven2/org/apache/kafka/kafka-clients/2.8.1/) | | `debezium-embedded-1.9.7.Final.jar` | 包含完整的 Kafka Connect API 和 Debezium 模型 | [Maven](https://repo.maven.apache.org/maven2/io/debezium/debezium-embedded/1.9.7.Final/) | > 💡 `debezium-embedded` 包含了 `org.apache.kafka.connect.*` 所有类(包括 `ConnectException`) --- ### ✅ 下载命令(推荐) ```bash cd $FLINK_HOME/lib # 1. Flink JSON 支持(必须) wget https://repo.maven.apache.org/maven2/org/apache/flink/flink-json/1.17.2/flink-json-1.17.2.jar # 2. Kafka 客户端(必须) wget https://repo.maven.apache.org/maven2/org/apache/kafka/kafka-clients/2.8.1/kafka-clients-2.8.1.jar # 3. Debezium Embedded(关键!提供 ConnectException) wget https://repo.maven.apache.org/maven2/io/debezium/debezium-embedded/1.9.7.Final/debezium-embedded-1.9.7.Final.jar ``` > ✅ 注意:Debezium 1.9.7.Final 兼容 Kafka 2.8.x 和 Flink 1.17 --- ### ✅ 验证是否包含 ConnectException ```bash jar -tvf debezium-embedded-1.9.7.Final.jar | grep "ConnectException" ``` 输出应为: ``` ... org/apache/kafka/connect/errors/ConnectException.class ``` ✅ 成功找到! --- ## ✅ 启动并测试 重启 SQL Client: ```bash $FLINK_HOME/bin/sql-client.sh ``` 执行你的 DDL: ```sql CREATE TABLE mysql_cdc ( id INT, name STRING, PRIMARY KEY (id) NOT ENFORCED ) WITH ( 'connector' = 'mysql-cdc', 'hostname' = 'localhost', 'database-name' = 'testdb', 'table-name' = 'users', 'username' = 'root', 'password' = '123456', 'format' = 'debezium-json' ); ``` 现在应该不会再报 `ClassNotFoundException`! --- ## 🧩 替代方案:使用 `json` 而非 `debezium-json` 如果你不想引入这么多 JAR,可以考虑改用轻量级格式: ```sql 'format' = 'json' ``` 但注意: - `json` 格式只能解析普通 JSON,不能解析 Debezium 的复杂结构(如 `before`, `after`, `op`, `ts_ms` 等字段) - 所以仅适用于简单场景 --- ## ✅ 总结:你现在该怎么办? | 步骤 | 操作 | |------|------| | 1 | 删除无效的 `flink-connector-kafka` 和旧的 `flink-sql-connector-kafka` | | 2 | 添加三个关键 JAR:<br>`flink-json-1.17.2.jar`<br>`kafka-clients-2.8.1.jar`<br>`debezium-embedded-1.9.7.Final.jar` | | 3 | 验证 `debezium-embedded` 是否包含 `ConnectException` | | 4 | 重启 SQL Client | | 5 | 测试 DDL 创建表 | ✅ 完成后,问题将彻底解决。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值