前言
书接上回搞了个flink-sql同步数据之后我已经不满足于简单的同步了。作为一个不会java的数分小白,我想用pyflink实现pyflink数据同步,这样我就能在其中加些自己想要的逻辑,以满足后续各种奇葩需求。话不多说开搞。
***************前置条件******************
在操作mysql的时候,你的jar包需要有flink-sql-connector-mysql-cdc-2.4.1.jar,mysql-connector-java-8.0.26.jar 。使用的时候根据你自己数据库版本和flink版本自行判断版本。
下载地址:https://mvnrepository.com/artifact/com.ververica
1.mysql 同步 batch版本
batch版本使用jdbc引擎,批量的将表中的数据抽取,供分析使用。
in_batch_mode 的使用场景
批处理模式:适用于一次性处理有限的数据集。数据源通常是静态的,例如文件、数据库表等。
应用场景:
数据仓库中的历史数据加载。
定期批量处理日志文件或报表生成。
一次性数据迁移或转换任务
需要注意的是对于线上的业务表,第一次试水的时候并行度别搞太大,batch也设置一下。小心被飞机票了。以下代码仅供参考
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
from pyflink.table import TableEnvironment, EnvironmentSettings, TableDescriptor, Schema, DataTypes, FormatDescriptor
# 创建批处理模式的 TableEnvironment
t_env = TableEnvironment.create(EnvironmentSettings.in_batch_mode())
# 设置每次从源表读取的数据行数
t_env.get_config().get_configuration().set_integer("table.exec.source.batch.size", 1000)
# 设置检查点之间的间隔
t_env.get_config().get_configuration().set_integer("table.exec.source.batch.checkpoint-interval", 1000)
# 设置默认并行度
t_env.get_config().get_configuration().set_integer("table.exec.resource.default-parallelism", 2)
# 添加 Flink 的 JAR 文件
jars = []
import os
for file in os.listdir('/opt/flink-1.18.1/lib'):
if file.endswith('.jar'):
jars.append('/opt/flink-1.18.1/lib/'+file)
str_jars = ';'.join(['file://' + jar for jar in jars]) # 这里把下载的jar包都加载了
t_env.get_config().get_configuration().set_string("pipeline.jars", str_jars)
# 创建 MySQL 源表
t_env.execute_sql(f"""CREATE TABLE mysql_products (id INT,
name STRING,
description STRING,
PRIMARY KEY (id) NOT ENFORCED
)
WITH (
'connector' = 'jdbc',
'url' = 'jdbc:mysql://10.10.25.109:3306/test_feng',
'username' = 'root',
'password' = 'Aa111111',
'table-name'='products',
'scan.fetch-size' = '1000' -- 设置每次从数据库读取的行数
);
"""
)
# 查看数据
tab = t_env.from_path('mysql_products')
pandas_df = tab.limit(10).to_pandas()
print(pandas_df)
2.mysql-cdc版本
********前置条件*******
mysql开启了log_bin,详情参考上个文章。依赖的jar包:flink-connector-mysql-cdc-2.4.2.jar
in_streaming_mode 是用于创建 Flink 的流处理模式 TableEnvironment。流处理模式适用于需要实时处理数据的场景,例如实时数据集成、实时分析、实时监控等。
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
from pyflink.table import TableEnvironment, EnvironmentSettings
t_env = TableEnvironment.create(EnvironmentSettings.in_streaming_mode())
jars = []
import os
for file in os.listdir('/opt/flink-1.18.1/lib'):
if file.endswith('.jar'):
jars.append('/opt/flink-1.18.1/lib/'+file)
str_jars = ';'.join(['file://' + jar for jar in jars])
t_env.get_config().get_configuration().set_string("pipeline.jars", str_jars)
# 创建 MySQL CDC 表
t_env.execute_sql("""
CREATE TABLE mysql_products (
id INT,
name STRING,
description STRING,
PRIMARY KEY (id) NOT ENFORCED
) WITH (
'connector' = 'mysql-cdc',
'hostname' = '1x.1x.xxx.1xxx',
'port' = '3306',
'username' = 'root',
'password' = 'xxxxx',
'database-name' = 'test_feng',
'table-name' = 'products',
'scan.incremental.snapshot.enabled' = 'true',
'scan.incremental.snapshot.chunk.size' = '8096',
'scan.snapshot.fetch.size' = '1024',
'scan.startup.mode' = 'timestamp',
'scan.startup.timestamp-millis' = '1672531200000'
)
""")
# 查询表
tab = t_env.from_path('mysql_products')
tab.execute().print()
# 'scan.startup.mode' = 'timestamp', -- 从特定时间戳开始读取
# 'scan.startup.timestamp-millis' = '1672531200000', --2023-01-01 00:00:00
# 'scan.incremental.snapshot.enabled' = 'true', -- 启用增量快照
# 'scan.incremental.snapshot.chunk.size' = '8096', -- 增量快照块大小
# 'scan.snapshot.fetch.size' = '1024', -- 快照读取批量大小
需要注意的是'scan.incremental.snapshot.enabled' = 'true' 参数在启用时需要手动去刷新数据库权限。
GRANT REPLICATION SLAVE, RELOAD ON *.* TO 'root'@'%' IDENTIFIED BY 'your_password';
FLUSH PRIVILEGES;
3.postgresql 数据库读取
从postgresql使用jdbc的方式和msql基本没差别。依赖的jar包:postgresql-42.7.4.jar, flink-connector-postgres-cdc-2.4.2.jar。根据自己数据库及flink版本按需下载。
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
from pyflink.table import TableEnvironment, EnvironmentSettings, TableDescriptor, Schema, DataTypes, FormatDescriptor
# 创建 TableEnvironment
t_env = TableEnvironment.create(EnvironmentSettings.in_batch_mode())
jars = []
import os
for file in os.listdir('/opt/flink-1.18.1/lib'):
if file.endswith('.jar'):
jars.append('/opt/flink-1.18.1/lib/'+file)
str_jars = ';'.join(['file://' + jar for jar in jars])
t_env.get_config().get_configuration().set_string("pipeline.jars", str_jars)
# 设置每次从源表读取的数据行数
t_env.get_config().get_configuration().set_integer("table.exec.source.batch.size", 1000)
# 设置检查点之间的间隔
t_env.get_config().get_configuration().set_integer("table.exec.source.batch.checkpoint-interval", 1000)
# 设置默认并行度
t_env.get_config().get_configuration().set_integer("table.exec.resource.default-parallelism", 4)
t_env.execute_sql(f"""CREATE TABLE postgres_products (id INT,
name STRING,
description STRING,
PRIMARY KEY (id) NOT ENFORCED
)
WITH (
'connector' = 'jdbc',
'url' = 'jdbc:postgresql://xxx.1x.xxx.xx0:5432/test_feng',
'username' = 'postgres',
'password' = 'xxxx',
'scan.fetch-size' = '1000',
'table-name'='products');
"""
)
# 查看数据
tab = t_env.from_path('postgres_products')
pandas_df = tab.limit(10).to_pandas()
print(pandas_df)
4. postgresql-cdc读取
依赖的jar包:flink-connector-postgres-cdc-2.4.2.jar
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
from pyflink.table import TableEnvironment, EnvironmentSettings
t_env = TableEnvironment.create(EnvironmentSettings.in_streaming_mode())
jars = []
import os
for file in os.listdir("/opt/flink-1.18.1/lib/"):
if file.endswith('.jar'):
jars.append('/opt/flink-1.18.1/lib/'+file)
str_jars = ';'.join(['file://' + jar for jar in jars])
t_env.get_config().get_configuration().set_string("pipeline.jars", str_jars)
# 创建 MySQL CDC 表
t_env.execute_sql("""CREATE TABLE postgres_products (id INT,name STRING,description STRING,PRIMARY KEY (id) NOT ENFORCED
) WITH (
'connector' = 'postgres-cdc',
'hostname' = '1x.1x.xx.1xx',
'port' = '5432','username' = 'postgres',
'password' = 'xxxx','database-name' = 'test_feng',
'table-name' = 'products','schema-name' = 'public',
'slot.name'='flink_slot1',
'decoding.plugin.name'='pgoutput',
'scan.incremental.snapshot.enabled'='true',
'scan.startup.mode'='latest-offset',
'scan.snapshot.fetch-size'='1000'
)
""")
# 查询表
tab = t_env.from_path('postgres_products')
tab.execute().print()
# 'scan.snapshot.fetch-size'='1000' --每次读取的数据量
# 'scan.startup.mode'='initial'
# 。initial 模式会从头开始全量扫描,而 latest-offset 模式会从最新的偏移量开始读取增量数据
以上就是我使用pyflink对这两个数据库做的抽取探索,有什么不对的地方,或者问题欢迎留言指正。我们一起进步