由于公司业务需要,需要实时同步pgsql数据,我们选择使用flink-cdc方式进行

架构图:

前提步骤:

1,更改配置文件postgresql.conf

# 更改wal日志方式为logicalwal_level = logical            # minimal, replica, or logical
# 更改solts最大数量(默认值为10),flink-cdc默认一张表占用一个slotsmax_replication_slots = 20 # max number of replication slots
# 更改wal发送最大进程数(默认值为10),这个值和上面的solts设置一样max_wal_senders = 20 # max number of walsender processes# 中断那些停止活动超过指定毫秒数的复制连接,可以适当设置大一点(默认60s)wal_sender_timeout = 180s # in milliseconds; 0 disable  

更改配置文件postgresql.conf完成,需要重启pg服务生效,所以一般是在业务低峰期更改

2,新建用户并且给用户复制流权限

-- pg新建用户CREATE USER user WITH PASSWORD 'pwd';
-- 给用户复制流权限ALTER ROLE user replication;
-- 给用户登录数据库权限grant CONNECT ON DATABASE test to user;
-- 把当前库public下所有表查询权限赋给用户GRANT SELECT ON ALL TABLES IN SCHEMA public TO user;

3,发布表

-- 设置发布为true
update pg_publication set puballtables=true where pubname is not null;
-- 把所有表进行发布
CREATE PUBLICATION dbz_publication FOR ALL TABLES;
-- 查询哪些表已经发布
select * from pg_publication_tables;

4,更改表的复制标识包含更新和删除的值

-- 更改复制标识包含更新和删除之前值
ALTER TABLE test0425 REPLICA IDENTITY FULL;
-- 查看复制标识(为f标识说明设置成功)
select relreplident from pg_class where relname='test0425';

OK,到这一步,设置已经完全可以啦,上面步骤都是必须的

5,下面开始上代码:,

maven依赖

        <dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-scala_2.11</artifactId>
<version>1.13.0</version>
</dependency> <!-- https://mvnrepository.com/artifact/org.apache.flink/flink-streaming-scala -->
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-streaming-scala_2.11</artifactId>
<version>1.13.0</version>
</dependency> <dependency>
<groupId>com.alibaba.ververica</groupId>
<artifactId>flink-connector-postgres-cdc</artifactId>
<version>1.1.0</version>
</dependency>

java代码

package flinkTest.connect;

import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.table.api.EnvironmentSettings;
import org.apache.flink.table.api.TableResult;
import org.apache.flink.table.api.bridge.java.StreamTableEnvironment; public class PgsqlToMysqlTest {
public static void main(String[] args) {
//设置flink表环境变量
EnvironmentSettings fsSettings = EnvironmentSettings.newInstance()
.useBlinkPlanner()
.inStreamingMode()
.build(); //获取flink流环境变量
StreamExecutionEnvironment exeEnv = StreamExecutionEnvironment.getExecutionEnvironment();
exeEnv.setParallelism(1); //表执行环境
StreamTableEnvironment tableEnv = StreamTableEnvironment.create(exeEnv, fsSettings); //拼接souceDLL
String sourceDDL =
"CREATE TABLE pgsql_source (\n" +
" id int,\n" +
" name STRING,\n" +
" py_code STRING,\n" +
" seq_no int,\n" +
" description STRING\n" +
") WITH (\n" +
" 'connector' = 'postgres-cdc',\n" +
" 'hostname' = '***',\n" +
" 'port' = '5432',\n" +
" 'username' = '***',\n" +
" 'password' = '***',\n" +
" 'database-name' = '***',\n" +
" 'schema-name' = 'public',\n" +
" 'decoding.plugin.name' = 'pgoutput',\n" +
" 'debezium.slot.name' = '***',\n" +
" 'table-name' = '***'\n" +
")"; String sinkDDL =
"CREATE TABLE mysql_sink (\n" +
" id int,\n" +
" name STRING,\n" +
" py_code STRING,\n" +
" seq_no int,\n" +
" description STRING,\n" +
" PRIMARY KEY (id) NOT ENFORCED\n" +
") WITH (\n" +
" 'connector' = 'jdbc',\n" +
" 'url' = 'jdbc:mysql://ip:3306/DB?rewriteBatchedStatements=true&useUnicode=true&characterEncoding=UTF-8',\n" +
" 'username' = '***',\n" +
" 'password' = '***',\n" +
" 'table-name' = '***'\n" +
")"; String transformSQL =
"INSERT INTO mysql_sink " +
"SELECT id,name,py_code,seq_no,description " +
"FROM pgsql_source"; //执行source表ddl
tableEnv.executeSql(sourceDDL);
//执行sink表ddl
tableEnv.executeSql(sinkDDL);
//执行逻辑sql语句
TableResult tableResult = tableEnv.executeSql(transformSQL); }
}

表机构奉上:

-- pgsql表结构
CREATE TABLE "public"."test" (
"id" int4 NOT NULL,
"name" varchar(50) COLLATE "pg_catalog"."default" NOT NULL,
"py_code" varchar(50) COLLATE "pg_catalog"."default",
"seq_no" int4 NOT NULL,
"description" varchar(200) COLLATE "pg_catalog"."default",
CONSTRAINT "pk_zd_business_type" PRIMARY KEY ("id")
)
; -- mysql表结构
CREATE TABLE `test` (
`id` int(11) NOT NULL DEFAULT '0' COMMENT 'ID',
`name` varchar(50) DEFAULT NULL COMMENT '名称',
`py_code` varchar(50) DEFAULT NULL COMMENT '助记码',
`seq_no` int(11) DEFAULT NULL COMMENT '排序',
`description` varchar(200) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

6,下面就可以进行操作原表,然后增删改操作

Flink-cdc实时读postgresql的更多相关文章

  1. Fllin(七)【Flink CDC实践】

    目录 FlinkCDC 1.简介 2.依赖 3.flink stream api 4.flink sql 5.自定义反序列化器 6.打包测试 FlinkCDC 1.简介 CDC是Change Data ...

  2. 阿里云体验有奖:使用PolarDB-X与Flink搭建实时数据大屏

    体验简介 场景将提供一台配置了CentOS 8.5操作系统的ECS实例(云服务器).通过本教程的操作带您体验如何使用PolarDB-X与Flink搭建一个实时数据链路,模拟阿里巴巴双十一GMV大屏. ...

  3. 跟我一起读postgresql源码(八)——Executor(查询执行模块之——可优化语句的执行)

    2.可优化语句的执行 可优化语句的共同特点是它们被查询编译器处理后都会生成査询计划树,这一类语句由执行器(Executor)处理.该模块对外提供了三个接口: ExecutorStart.Executo ...

  4. 跟我一起读postgresql源码(十)——Executor(查询执行模块之——Scan节点(下))

    接前文跟我一起读postgresql源码(九)--Executor(查询执行模块之--Scan节点(上)) ,本篇把剩下的七个Scan节点结束掉. T_SubqueryScanState, T_Fun ...

  5. 跟我一起读postgresql源码(二)——Parser(查询分析模块)

    上篇博客简要的介绍了下psql命令行客户端的前台代码.这一次,我们来看看后台的代码吧. 十分不好意思的是,上篇博客我们只说明了前台登陆的代码,没有介绍前台登陆过程中,后台是如何工作的.即:后台接到前台 ...

  6. Flink实战| Flink+Redis实时防刷接口作弊

    随着人口红利的慢慢削减,互联网产品的厮杀愈加激烈,大家开始看好下沉市场的潜力,拼多多,趣头条等厂商通过拉新奖励,购物优惠等政策率先抢占用户,壮大起来.其他各厂商也紧随其后,纷纷推出自己产品的极速版,如 ...

  7. flink 处理实时数据的三重保障

    flink 处理实时数据的三重保障 window+watermark 来处理乱序数据对于 TumblingEventTimeWindows window 的元数据startTime,endTime 和 ...

  8. (二)基于商品属性的相似商品推荐算法——Flink SQL实时计算实现商品的隐式评分

    系列随笔: (总览)基于商品属性的相似商品推荐算法 (一)基于商品属性的相似商品推荐算法--整体框架及处理流程 (二)基于商品属性的相似商品推荐算法--Flink SQL实时计算实现商品的隐式评分 ( ...

  9. 指标统计:基于流计算 Oceanus(Flink) 实现实时 UVPV 统计

    作者:吴云涛,腾讯 CSIG 高级工程师导语 | 最近梳理了一下如何用 Flink 来实现实时的 UV.PV 指标的统计,并和公司内微视部门的同事交流.然后针对该场景做了简化,并发现使用 Flink ...

随机推荐

  1. 当 Go struct 遇上 Mutex

    struct 是我们写 Go 必然会用到的关键字, 不过当 struct 遇上一些比较特殊类型的时候, 你注意过你的程序是否正常吗 ? 一段代码 type URL struct { Ip string ...

  2. (十六)VMware Harbor 复制镜像

    Step 1: 点击复制镜像后 Step 2: 填写复制镜像信息 Step 3:在sx628下,会多出一个镜像

  3. Deployment常用命令

    // 查询详细信息,获取升级速度 kubectl describe deployments // 暂停升级 kubectl rollout pause deployment/deploymentngi ...

  4. 02- HTML网页基础知识与浏览器介绍

    1.认识网页 网页主要由文字,图像和超链接等元素构成.当然,除了这些元素,网页还可以包含音频,视频,以及flask等. 如图所示就是一个网页: 网页是如何形成的呢? 它是由前端人员写的代码,经过浏览器 ...

  5. 【Java】 Java中的浅拷贝和深拷贝

    先抛出结论: 浅拷贝是引用拷贝,A对象拷贝B以后,A对象和B对象指向同一块内存地址,改变A对象的属性值会触发B对象属性的改变,有安全风险 深拷贝是对象拷贝,A对象拷贝B以后,A对象和B对象指向不同的额 ...

  6. hdu4768 非常规的二分

    题意:       n个社团给同学发传单,同学一共有1--2^31这么多,每个社团有三个数A ,B ,C ,只有 满足 A ,A + C ,A + C + C ...A + KC <= B 的学 ...

  7. LA3029最大子矩阵

    题意:       给你一个n*m的矩阵<每个格子不是'F'就是'R'>,让你找一个最大的'F'矩阵,输出他的面积*3. 思路:       比较经典的题目了,现在想起来比较好想,以前的话 ...

  8. Linux内核升级、GRUB2引导故障处理与密码破解

    目录 内核升级 GRUB2内核启动设置 GRUB2引导菜单加密 GRUB2引导故障及修复 救援模式管理 Rhel7破解root密码 内核升级 查看当前内核版本: uname  -r 查看可升级内核:  ...

  9. XCTF-wtf.sh-150

    wtf.sh-150 题目描述 没有描述 解题过程 打开之后是个论坛,有注册和登录功能点 抓包发现,登陆成功后会设置cookie <script>document.cookie = 'US ...

  10. 【easycode】使用说明 & 示例

    语法 ## 是模板的注释,不会生成 # 全局的一些设置 $ 使用库函数或者调用全局定义的内容 常用方法 数据库表信息 ${tableInfo} comment 表备注 name 表名 fullColu ...