双流实时同步
本文提供Flink双流实时同步场景的实施思路、配置示例和验证方式,可作为实际项目配置参考。
案例
将
公司表作为维表,关联订单表,完善订单信息后,过滤掉阿里云的订单,结果同步到订单详情表中。
-- 公司表
create table source_business
(
id varchar(100) not null primary key,
name varchar(100) not null
);
-- 订单表
create table source_order
(
id varchar(100) not null primary key,
name varchar(100) not null,
business_id varchar(100) not null,
price double not null
);
-- 订单详情表
create table target_business_order
(
order_id varchar(100) not null primary key,
name varchar(100) not null,
business_name varchar(100) not null,
price double not null
);
维表关联写法(Lookup Join)
使用Flink SQL语法
FOR SYSTEM_TIME AS OF
CREATE TABLE source_business
(
id STRING,
name STRING
) WITH (
'connector' = 'jdbc',
'url' = 'jdbc:mysql://localhost:30306/isxcode_db?useSSL=false&allowPublicKeyRetrieval=true',
'driver' = 'com.mysql.cj.jdbc.Driver',
'table-name' = 'source_business',
'username' = 'root',
'password' = 'root123'
);
CREATE TABLE source_order
(
id STRING,
name STRING,
business_id STRING,
price DOUBLE,
order_time as proctime()
) WITH (
'connector' = 'mysql-cdc',
'hostname' = 'localhost',
'port' = '30306',
'username' = 'root',
'password' = 'root123',
'database-name' = 'isxcode_db',
'table-name' = 'source_order',
'scan.incremental.snapshot.enabled' = 'false',
'server-time-zone' = 'UTC',
'scan.startup.mode' = 'latest-offset'
);
CREATE TABLE target_business_order
(
order_id STRING,
name STRING,
business_name STRING,
price DOUBLE,
PRIMARY KEY (order_id) NOT ENFORCED
) WITH (
'connector' = 'jdbc',
'url' = 'jdbc:mysql://localhost:30306/isxcode_db?useSSL=false&allowPublicKeyRetrieval=true',
'driver' = 'com.mysql.cj.jdbc.Driver',
'table-name' = 'target_business_order',
'username' = 'root',
'password' = 'root123'
);
INSERT INTO target_business_order
SELECT
o.id AS order_id,
o.name,
b.name,
o.price
FROM source_order as o
LEFT JOIN source_business FOR SYSTEM_TIME AS OF o.order_time as b
ON o.business_id = b.id where b.name <> '阿里云';
普通Join写法
FULL OUTER JOIN
外部链接,插入任意一条数据都会缓存 前提,每张表中至少存在一条数据,否则数据不合法,无法缓存 比如:source_business表为空,source_order表插入再多的数据也都是不合法的 当source_business插入一条数据后,source_order再插入的数据都会合法
CREATE TABLE source_business
(
id STRING,
name STRING
) WITH (
'connector' = 'mysql-cdc',
'hostname' = 'localhost',
'port' = '30306',
'username' = 'root',
'password' = 'root123',
'database-name' = 'isxcode_db',
'table-name' = 'source_business',
'scan.incremental.snapshot.enabled' = 'false',
'server-time-zone' = 'UTC',
'scan.startup.mode' = 'latest-offset'
);
CREATE TABLE source_order
(
id STRING,
name STRING,
business_id STRING,
price DOUBLE
) WITH (
'connector' = 'mysql-cdc',
'hostname' = 'localhost',
'port' = '30306',
'username' = 'root',
'password' = 'root123',
'database-name' = 'isxcode_db',
'table-name' = 'source_order',
'scan.incremental.snapshot.enabled' = 'false',
'server-time-zone' = 'UTC',
'scan.startup.mode' = 'latest-offset'
);
CREATE TABLE target_business_order
(
order_id STRING,
name STRING,
business_name STRING,
price DOUBLE
) WITH (
'connector' = 'print'
);
INSERT INTO target_business_order(order_id, name, business_name, price)
select o.id, o.name, b.name, o.price
from source_order o FULL OUTER join source_business b on o.business_id = b.id;
INNER JOIN
内链接,当数据同时插入,数据匹配上才会合法,并缓存数据,否则数据无法缓存
INSERT INTO target_business_order(order_id, name, business_name, price)
select o.id, o.name, b.name, o.price
from source_order o INNER JOIN source_business b on o.business_id = b.id;
RIGHT JOIN
右链接,source_business有几条缓存几条,source_order匹配几条缓存几条
INSERT INTO target_business_order(order_id, name, business_name, price)
select o.id, o.name, b.name, o.price
from source_order o RIGHT JOIN source_business b on o.business_id = b.id;
LEFT JOIN
左链接,source_order有几条缓存几条,source_business匹配几条缓存几条
INSERT INTO target_business_order(order_id, name, business_name, price)
select o.id, o.name, b.name, o.price
from source_order o LEFT JOIN source_business b on o.business_id = b.id;
时间间隔Join写法
间隔链接,一段时间内的数据匹配
CREATE TABLE source_business
(
id STRING,
name STRING,
rtime AS CURRENT_TIMESTAMP
) WITH (
'connector' = 'mysql-cdc',
'hostname' = 'localhost',
'port' = '30306',
'username' = 'root',
'password' = 'root123',
'database-name' = 'isxcode_db',
'table-name' = 'source_business',
'scan.incremental.snapshot.enabled' = 'false',
'server-time-zone' = 'UTC',
'scan.startup.mode' = 'latest-offset'
);
CREATE TABLE source_order
(
id STRING,
name STRING,
business_id STRING,
price DOUBLE,
order_time AS CURRENT_TIMESTAMP
) WITH (
'connector' = 'mysql-cdc',
'hostname' = 'localhost',
'port' = '30306',
'username' = 'root',
'password' = 'root123',
'database-name' = 'isxcode_db',
'table-name' = 'source_order',
'scan.incremental.snapshot.enabled' = 'false',
'server-time-zone' = 'UTC',
'scan.startup.mode' = 'latest-offset'
);
CREATE TABLE target_business_order
(
order_id STRING,
name STRING,
business_name STRING,
price DOUBLE
) WITH (
'connector' = 'print'
);
INSERT INTO target_business_order(order_id, name, business_name, price)
select o.id, o.name, b.name, o.price
from source_order o,
source_business b
where o.business_id = b.id
AND o.order_time BETWEEN rtime - INTERVAL '10' SECOND AND rtime + INTERVAL '10' SECOND
