路过 Flink CDC 踩到的坑

4,106 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情

当突降需求,又碰到个好玩的玩意(Flink CDC 2.2.*)发布,又那么符合需求的时候,我是那个激动的啊。恨不得马上

冲起来,跑起来,咻一下的搭建玩,把数据同步完。后跟领导说,这个东西是真的厉害啊,一下解决我们的场景啊,是我们的不二之选啊。但是理想的很丰满,现实充满坑。。。

接下来,就看下在使用 flink cdc 的过程中,遇到的一些坑。

注:本文的 Flink 版本 1.14.4 ,Flink CDC 2.2.1

前言

Flink CDC 常用两种方式进行数据的全量+增量一体的数据同步,数据清洗等功能。主要使用方法:

  • 使用 DataStream API 进行任务的逻辑实现
  • 使用 Flink SQL 的方式进行任务的提交

1、使用DataStream API 的坑

在讲遇到的坑之前,我们先来看下如何在 JAVA 中直接使用 DataStream API 进行任务的同步。

  1. 创建 Java 工程,pom 文件引入依赖

    <dependency>
          <groupId>org.apache.flink</groupId>
          <artifactId>flink-shaded-guava</artifactId>
          <version>30.1.1-jre-14.0</version>
        </dependency>
        <dependency>
          <groupId>com.ververica</groupId>
          <artifactId>flink-sql-connector-mysql-cdc</artifactId>
          <version>2.2.1</version>
        </dependency>
    
  2. 编写 DataStream 代码,实现数据 cdc 的获取

package org.myorg.quickstart;
​
import com.ververica.cdc.connectors.mysql.source.MySqlSource;
import com.ververica.cdc.connectors.mysql.table.StartupOptions;
import com.ververica.cdc.debezium.JsonDebeziumDeserializationSchema;
import org.apache.flink.api.common.eventtime.WatermarkStrategy;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import java.util.Properties;
import io.debezium.connector.mysql.MySqlConnectorConfig;
​
public class MysqlSslTest {
​
    public static void main(String[] args) throws Exception {
        MySqlSource<String> mySqlSource = MySqlSource.<String>builder()
            .hostname("192.168.1.212")
            .port(3306)
            .databaseList("TEST") // set captured database
            .tableList("TEST.orders,TEST.products,TEST.shipments,TEST.T_DEMO") // set captured table
            .username("root")
            .password("root")
            .deserializer(new JsonDebeziumDeserializationSchema()) // converts SourceRecord to JSON String
            .startupOptions(StartupOptions.initial())
            .build();
​
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
​
​
        // enable checkpoint
        env.enableCheckpointing(10000);
​
        env
            .fromSource(mySqlSource, WatermarkStrategy.noWatermarks(), "MySQL Source")
            .setParallelism(1)
            .print().setParallelism(1);
​
​
        env.execute("mysql-cdc");
    }
}
​

重点讲下这边踩到的坑:

  • Flink 版本和 CDC 同时引入了 flink-shaded-guava,但是两者之间一个版本18,一个30,存在版本冲突,这时会导致任务启动失败

  • 报错日志 image-20220607233230936.png

  • 解决方式

pom 文件使用 flink-sql-connector-mysql-cdc 而不是引用官方 demo 中的 flink-connector-mysql-cdc。

flink-sql-connector-mysql-cdc本质也是引用了 flink-connector-mysql-cdc; flink-sql-conenctor-mysql-cdc 修复了此项冲突。当出现这个错误是,请记得检查 cdc 的jar包是不是引用错,要用有 sql 的这个jar哦~

2、使用 Flink sql 的碰到问题

  • 背景

    在生产环境中,由于三级等保要求,我们的 mysql 服务都开启的强制的 SSL 检验。

    必须 useSSL 才能连接到 mysql。

  • Flink SQL 中 CDC connector 如何配置使用 SSL 的数据库连接呢?

    • 查看官方文档 image-20220607234203659.png
  • jdbc.properties.useSSL' = 'true' ,看起来很完美,实际上当 mysql 开启一定要 ssl 连接时, 加上此配置是远远不够的。报错如下:

    Error reading MySQL variables: Connections using insecure transport are prohibited while --require_secure_transport=ON.

image-20220607234933640.png

那还缺少啥配置呢?官网没说,那就代码断点调试了。最终发现,需增加 'debezium.database.ssl.mode'='required'

-   当开启 ssl ,并且设置 require_secure_transport=ON 时,完整配置如下

```
 CREATE TABLE DEMO1 (
    ID INT,
    NAME STRING,
    PRIMARY KEY (ID) NOT ENFORCED
  ) WITH (
    'connector' = 'mysql-cdc',
    'hostname' = '192.168.0.212',
    'port' = '3308',
    'username' = 'root',
    'password' = 'root1234',
    'database-name' = 'TEST',
    'table-name' = 'T_DEMO',
    'jdbc.properties.useSSL' = 'true',
    'debezium.database.ssl.mode'='required'
  );
```

总结

以上是最近使用 Flink CDC 碰到的几个问题,后续有问题会在此篇继续补充,少走弯路,zao点xia班。

对于 Flink CDC 目前粗浅的使用来说,我觉得是一款很强大的同步工具,在目前业界的开源【全量+增量】同步工具上找不到更合适的,能满足一些基本的业务场景,比如数据同步,数据清洗,但目前还在火速发展阶段,还是会存在一些问题,要慢慢踩坑。

使用指南

Flink CDC 文档地址