TiDB系列之:使用Flink TiDB CDC Connector采集数据

TiDB系列之:使用Flink TiDB CDC Connector采集数据

  • 一、依赖项
  • 二、Maven依赖
  • 三、SQL Client JAR
  • 四、如何创建 TiDB CDC 表
  • 五、连接器选项
  • 六、可用元数据
  • 七、特征
    • 一次性处理
    • 启动阅读位置
    • 多线程读取
    • DataStream Source
  • 八、数据类型映射

TiDB CDC 连接器允许从 TiDB 数据库读取快照数据和增量数据。本文档介绍如何设置 TiDB CDC 连接器以对 TiDB 数据库运行 SQL 查询。

  • TiDB系列之:使用TiCDC增量同步TiDB数据库数据
  • TiDB系列之:TiCDC同步数据到Kafka集群使用Debezium数据格式
  • TiDB系列之:TiCDC同步TiDB数据库数据到Kafka集群Topic

一、依赖项

为了设置 TiDB CDC 连接器,下表提供了使用构建自动化工具(例如 Maven 或 SBT)的项目和带有 SQL JAR 包的 SQL Client 的依赖信息。

二、Maven依赖

<dependency>
    <groupId>org.apache.flink</groupId>
    <artifactId>flink-connector-tidb-cdc</artifactId>
    <version>3.0.1</version>
</dependency>

三、SQL Client JAR

下载链接仅适用于稳定版本。

下载 flink-sql-connector-tidb-cdc-3.0.1.jar 并将其放在 /lib/ 下。

四、如何创建 TiDB CDC 表

TiDB CDC 表可以定义如下:

-- checkpoint every 3000 milliseconds                       
Flink SQL> SET 'execution.checkpointing.interval' = '3s';   

-- register a TiDB table 'orders' in Flink SQL
Flink SQL> CREATE TABLE orders (
     order_id INT,
     order_date TIMESTAMP(3),
     customer_name STRING,
     price DECIMAL(10, 5),
     product_id INT,
     order_status BOOLEAN,
     PRIMARY KEY(order_id) NOT ENFORCED
     ) WITH (
     'connector' = 'tidb-cdc',
     'tikv.grpc.timeout_in_ms' = '20000', 
     'pd-addresses' = 'localhost:2379',
     'database-name' = 'mydb',
     'table-name' = 'orders'
);
  
-- read snapshot and binlogs from orders table
Flink SQL> SELECT * FROM orders;

五、连接器选项

参数 是否必须 默认值 类型 描述
connector required (none) String 指定使用什么连接器,这里应该是“tidb-cdc”。
database-name required (none) String 要监控的 TiDB 服务器的数据库名称。
table-name required (none) String 要监控的 TiDB 数据库的表名。
scan.startup.mode optional initial String TiDB CDC Consumer 可选的启动模式,有效枚举为“initial”和“latest-offset”。
pd-addresses required (none) String TiKV 集群的 PD 地址。
tikv.grpc.timeout_in_ms optional (none) Long TiKV GRPC 超时(以毫秒为单位)。
tikv.grpc.scan_timeout_in_ms optional (none) Long TiKV GRPC 扫描超时(以毫秒为单位)。
tikv.batch_get_concurrency optional 20 Integer TiKV GRPC 批量获取并发。
tikv.* optional (none) String 传递 TiDB 客户端的属性。

六、可用元数据

以下格式元数据可以在表定义中公开为只读(虚拟)列。

key DataType 描述
table_name STRING NOT NULL 包含该行的表的名称。
database_name STRING NOT NULL 包含该行的数据库的名称。
op_ts TIMESTAMP_LTZ(3) NOT NULL 它指示在数据库中进行更改的时间。
如果记录是从表的快照而不是binlog中读取的,则该值始终为0。

扩展的 CREATE TABLE 示例演示了公开这些元数据字段的语法:

CREATE TABLE products (
    db_name STRING METADATA FROM 'database_name' VIRTUAL,
    table_name STRING METADATA  FROM 'table_name' VIRTUAL,
    operation_ts TIMESTAMP_LTZ(3) METADATA FROM 'op_ts' VIRTUAL,
    order_id INT,
    order_date TIMESTAMP(0),
    customer_name STRING,
    price DECIMAL(10, 5),
    product_id INT,
    order_status BOOLEAN,
    PRIMARY KEY(order_id) NOT ENFORCED
) WITH (
    'connector' = 'tidb-cdc',
    'tikv.grpc.timeout_in_ms' = '20000',
    'pd-addresses' = 'localhost:2379',
    'database-name' = 'mydb',
    'table-name' = 'orders'
);

七、特征

一次性处理

TiDB CDC 连接器是一个 Flink Source 连接器,它会先读取数据库快照,然后继续读取更改事件,即使发生故障也只处理一次。

启动阅读位置

配置选项 scan.startup.mode 指定 TiDB CDC Consumer 的启动模式。有效的枚举是:

  • initial(默认):拍摄捕获表的结构和数据的快照;如果您想从捕获的表中获取数据的完整表示,则很有用。
  • latest-offset:仅对捕获的表的结构进行快照;如果只需要获取从现在开始发生的更改,则很有用。

多线程读取

TiDB CDC 源可以并行读取工作,因为有多个任务可以接收更改事件。

DataStream Source

TiDB CDC 连接器也可以是 DataStream 源。您可以创建一个 SourceFunction,如下所示:

import org.apache.flink.api.common.typeinfo.BasicTypeInfo;
import org.apache.flink.api.common.typeinfo.TypeInformation;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.functions.source.SourceFunction;
import org.apache.flink.util.Collector;

import org.apache.flink.cdc.connectors.tidb.TDBSourceOptions;
import org.apache.flink.cdc.connectors.tidb.TiDBSource;
import org.apache.flink.cdc.connectors.tidb.TiKVChangeEventDeserializationSchema;
import org.apache.flink.cdc.connectors.tidb.TiKVSnapshotEventDeserializationSchema;
import org.tikv.kvproto.Cdcpb;
import org.tikv.kvproto.Kvrpcpb;

import java.util.HashMap;

public class TiDBSourceExample {

    public static void main(String[] args) throws Exception {

        SourceFunction<String> tidbSource =
            TiDBSource.<String>builder()
                .database("mydb") // set captured database
                .tableName("products") // set captured table
                .tiConf(
                    TDBSourceOptions.getTiConfiguration(
                        "localhost:2399", new HashMap<>()))
                .snapshotEventDeserializer(
                    new TiKVSnapshotEventDeserializationSchema<String>() {
                        @Override
                        public void deserialize(
                            Kvrpcpb.KvPair record, Collector<String> out)
                            throws Exception {
                            out.collect(record.toString());
                        }

                        @Override
                        public TypeInformation<String> getProducedType() {
                            return BasicTypeInfo.STRING_TYPE_INFO;
                        }
                    })
                .changeEventDeserializer(
                    new TiKVChangeEventDeserializationSchema<String>() {
                        @Override
                        public void deserialize(
                            Cdcpb.Event.Row record, Collector<String> out)
                            throws Exception {
                            out.collect(record.toString());
                        }

                        @Override
                        public TypeInformation<String> getProducedType() {
                            return BasicTypeInfo.STRING_TYPE_INFO;
                        }
                    })
                .build();

        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        // enable checkpoint
        env.enableCheckpointing(3000);
        env.addSource(tidbSource).print().setParallelism(1);

        env.execute("Print TiDB Snapshot + Binlog");
    }
}

八、数据类型映射

TiDB type Flink SQL type NOTE
TINYINT TINYINT
SMALLINT、TINYINT UNSIGNED SMALLINT
INT、MEDIUMINT、SMALLINT UNSIGNED INT
BIGINT、INT UNSIGNED BIGINT
BIGINT UNSIGNED DECIMAL(20, 0)
FLOAT FLOAT
REAL、DOUBLE DOUBLE
NUMERIC(p, s) DECIMAL(p, s) where p <= 38 DECIMAL(p, s)
NUMERIC(p, s) DECIMAL(p, s) where 38 < p <= 65 STRING 在 TiDB 中 DECIMAL 数据类型的精度最高为 65,但在 Flink 中 DECIMAL 的精度限制为 38。因此,如果定义精度大于 38 的十进制列,则应将其映射到 STRING 以避免精度损失。
BOOLEAN、TINYINT(1)、BIT(1) BOOLEAN
DATE DATE
TIME [§] TIME [§]
TIMESTAMP [§] TIMESTAMP_LTZ [§]
DATETIME [§] TIMESTAMP [§]
CHAR(n) CHAR(n)
VARCHAR(n) VARCHAR(n)
BIT(n) BINARY(⌈n/8⌉)
BINARY(n) BINARY(n)
TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT STRING
TINYBLOB、BLOB、MEDIUMBLOB、LONGBLOB BYTES 目前,TiDB 中的 BLOB 数据类型仅支持长度不大于 2,147,483,647(2 ** 31 - 1) 的 Blob。
YEAR INT
ENUM STRING
JSON STRING JSON 数据类型在 Flink 中会被转换为 JSON 格式的 STRING。
SET ARRAY 由于 TiDB 中的 SET 数据类型是一个字符串对象,可以有零个或多个值,因此它应该始终映射到字符串数组

你可能感兴趣的:(日常分享专栏,TiDB系列,使用Flink,TiDB,CDC,Connector采集数据)