案例:实现文章的访问量统计
使用Flink Postgres CDC 进行数据输入,在 Flink SQL CLI 中进行逻辑加工,整个过程使用 SQL ,无需代码。将结果通过JDBC方式输出到MySQL。
postgres数据库环境配置参考文章:Flink PostgreSQL CDC配置和常见问题
-- postgresql
-- 文章记录表
CREATE TABLE t_article (
id SERIAL NOT NULL PRIMARY KEY,
title VARCHAR(100) NOT NULL,
contents VARCHAR(500) NOT NULL,
author VARCHAR(20) NOT NULL,
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
ALTER SEQUENCE public.t_article_id_seq RESTART WITH 1001;
ALTER TABLE public.t_article REPLICA IDENTITY FULL;
-- 初始化数据
INSERT INTO t_article (title,contents,author)
VALUES ('华尔街日报回怼马斯克','知情人士揭露马斯克和谷歌联合创始人谢尔盖·布林之间长达20年的友谊突...','每日邮报'),
('跨省异地就医新规出台','国家医保局、财政部26日发布《关于进一步做好基本医疗保险跨省异地就医直接结算工作的通知》','新华社客户端'),
('扎实推动共同富裕','让人民过上好日子,是“国之大者”。深刻践行以人民为中心的发展思想,既要尽力而为也要量力而行,我们在高质量发展中促进共同富裕的脚步更加笃定。','中国经济网');
-- 文章访问记录表
CREATE TABLE t_article_visit (
id SERIAL NOT NULL PRIMARY KEY,
article_id int4 NOT NULL,
visitor VARCHAR(100) NOT NULL,
visitor_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
ALTER TABLE public.t_article REPLICA IDENTITY FULL;
-- 初始化数据
INSERT INTO "t_article_visit"( "article_id", "visitor") VALUES (1001, 'zhangsan');
INSERT INTO "t_article_visit"( "article_id", "visitor") VALUES (1001, 'lisi');
-- mysql
CREATE TABLE f_article_visit_count (
article_id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
article_title VARCHAR(255) NOT NULL,
visitor_count bigint DEFAULT 0
);
下面以本地模式安装,提前安装好 Java 8 或者 Java 11
$ tar -xzf flink-1.13.6-bin-scala_2.11.tgz
$ cd flink-1.13.6
$ ./bin/start-cluster.sh
$ ./bin/stop-cluster.sh
下载地址
本案例使用 postgres作为数据输入,下载 flink-sql-connector-postgres-cdc-2.2.1.jar
即可
下载地址
注意:也需要额外下载相关数据库的驱动。
./bin/sql-client.sh
-- 设置检查点
SET execution.checkpointing.interval = 3s;
CREATE TABLE t_article (
id INT,
title STRING,
contents STRING,
author STRING,
create_time TIMESTAMP(0),
PRIMARY KEY (id) NOT ENFORCED
) WITH (
'connector' = 'postgres-cdc',
'hostname' = '10.10.1.74',
'port' = '5432',
'username' = 'postgres',
'password' = '123456',
'database-name' = 'test',
'schema-name' = 'public',
'table-name' = 't_article',
'decoding.plugin.name' = 'pgoutput',
'debezium.slot.name' = 'flink_t_article'
);
CREATE TABLE t_article_visit (
id INT,
article_id INT,
visitor STRING,
visitor_time TIMESTAMP(0),
PRIMARY KEY (id) NOT ENFORCED
) WITH (
'connector' = 'postgres-cdc',
'hostname' = '10.10.1.74',
'port' = '5432',
'username' = 'postgres',
'password' = '123456',
'database-name' = 'test',
'schema-name' = 'public',
'table-name' = 't_article_visit',
'decoding.plugin.name' = 'pgoutput',
'debezium.slot.name' = 'flink_t_article_visit'
);
CREATE TABLE f_article_visit_count (
article_id INT,
article_title STRING,
visitor_count BIGINT,
PRIMARY KEY (article_id) NOT ENFORCED
) WITH ('connector' = 'jdbc',
'url' = 'jdbc:mysql://10.10.1.72:3306/test',
'username' = 'root',
'password' = '123456',
'table-name' = 'f_article_visit_count'
);
INSERT INTO f_article_visit_count SELECT
art.id article_id,
art.title article_title,
count( artv.id ) visitor_count
FROM t_article art
INNER JOIN t_article_visit artv ON art.id = artv.article_id
GROUP BY art.id,art.title;
任务发布后,表f_article_visit_count 的初始数据
通过向postgres库中表t_article_visit插入记录,观察mysql库中表f_article_visit_count数据实时变化
INSERT INTO "t_article_visit"( "article_id", "visitor") VALUES (1001, 'wangwu');
INSERT INTO "t_article_visit"( "article_id", "visitor") VALUES (1002, 'libai');