大数据组件(四)快速入门实时数据湖存储系统Apache Paimon(2)
Paimon的下载及安装,并且了解了主键表的引擎以及changelog-producer的含义参考:
- 大数据组件(四)快速入门实时数据湖存储系统Apache Paimon(1)
利用Paimon表做lookup join,集成mysql cdc等参考:
- 大数据组件(四)快速入门实时数据湖存储系统Apache Paimon(2)
利用Paimon的Tag兼容Hive,Branch管理等参考:
- 大数据组件(四)快速入门实时数据湖存储系统Apache Paimon(3)
大数据组件(四)快速入门实时数据湖存储系统Apache Paimon(2)
今天,我们继续快速了解下最近比较火的Apache Paimon:
- 官方文档:https://paimon.apache.org/docs/1.0/
- 推荐阅读:当流计算邂逅数据湖:Paimon 的前生今世
1 利用Paimon做维表join
- 在流式处理中,Lookup Join用来从另一个表(Paimon)中“查字典”来补充流的信息。一个表需要有时间标记(处理时间属性),另一个表需要支持快速查找(查找源连接器)
- Paimon在Flink中支持对带有主键的表和追加表进行Lookup Join操作
1.1 常规Lookup
SET 'execution.runtime-mode' = 'streaming';-- 1、用户维表
CREATE TABLE customers (id INT PRIMARY KEY NOT ENFORCED,name STRING comment '姓名',country STRING comment '城市',zip STRING comment '邮编'
) WITH ('connector' = 'paimon'
);-- 插入维表数据
INSERT INTO customers VALUES(1,'tom','伦敦','123'),(2,'hank','纽约','456'),(3,'小明','北京','789');-- 2、模拟订单表(数据流)
drop TEMPORARY TABLE orders_info;
CREATE TEMPORARY TABLE orders_info (order_id INT,total INT,customer_id INT,proc_time AS PROCTIME()
) WITH ('connector' = 'datagen', 'rows-per-second'='1', 'fields.order_id.kind'='sequence', 'fields.order_id.start'='1', 'fields.order_id.end'='1000000', 'fields.total.kind'='random', 'fields.total.min'='1', 'fields.total.max'='1000', 'fields.customer_id.kind'='random', 'fields.customer_id.min'='1', 'fields.customer_id.max'='3'
);-- 3、维表join
SELECT o.order_id, o.total, c.country, c.zip
FROM orders_info AS o
JOIN customers
FOR SYSTEM_TIME AS OF o.proc_time AS c
ON o.customer_id = c.id;-- 可以看到下面的结果
+----+----------+----------+-------------+---------+
| op | order_id | total | country | zip |
+----+----------+----------+-------------+---------+
| +I | 1 | 179 | 纽约 | 456 |
| +I | 2 | 31 | 北京 | 789 |
| +I | 3 | 148 | 北京 | 789 |
| +I | 4 | 774 | 北京 | 789 |
1.2 同步重试Lookup
- 如果用户维表(查找表)的数据未准备好,导致订单表(主表)的记录无法完成连接,你可以考虑使用Flink的延迟重试策略进行查找。
- 这个功能仅适用于Flink 1.16及以上的版本。
- 下面sql的提示(hints)设置了重试策略:
'table'='c'
: 指定了应用查找重试策略的目标表的别名,在这个例子中是customers表,其别名为c。'retry-predicate'='lookup_miss'
: 定义了触发重试的条件。这里的条件是lookup_miss,意味着如果在查找过程中没有找到对应的数据(即查找缺失),就会触发重试机制。'retry-strategy'='fixed_delay'
: 设置了重试的策略为固定延迟,即每次重试之间会有固定的等待时间。'fixed-delay'='1s'
: 当采用固定延迟重试策略时,这里设定了每次重试前等待的时间长度为1秒。'max-attempts'='600'
: 设定最大重试次数为600次。结合上面的fixed-delay设置,这意味着系统会每隔1秒尝试一次数据查找,最多尝试600次。
-- enrich each order with customer information
SELECT /*+ LOOKUP('table'='c', 'retry-predicate'='lookup_miss', 'retry-strategy'='fixed_delay', 'fixed-delay'='1s', 'max-attempts'='600') */o.order_id, o.total, c.country, c.zip
FROM orders AS o
JOIN customers
FOR SYSTEM_TIME AS OF o.proc_time AS c
ON o.customer_id = c.id;
1.3 异步重试Lookup
- 在同步重试机制下,如果处理某一条记录时遇到了问题(例如查找失败),系统会按照设定的重试策略反复尝试直到成功或者达到最大重试次数。在这期间,这条记录后面的其他记录即使没有问题也无法被处理,因为整个处理流程被阻塞了。这会导致数据处理的整体效率低下,甚至可能造成作业延迟或超时。
- 使用异步加上allow_unordered,可以在某些记录在查找时缺失也不会再阻塞其他记录。
- 下面sql配置项解释:
'output-mode'='allow_unordered'
: 设置输出模式允许无序,意味着当查找失败时不会阻塞其他记录的处理,适合于不需要严格顺序的场景。'lookup.async'='true'
: 启用异步查找,提高效率,避免因等待某个查找结果而阻塞其它查找操作。'lookup.async-thread-number'='16'
: 设置用于异步查找的线程数为16,这可以加速查找过程,特别是在高并发情况下。
- 注意:
如果主表(orders)是CDC流,allow_unordered会被Flink SQL忽略(只支持追加流)
,流作业可能会被阻塞。可以尝试使用Paimon的audit_log系统表功能来绕过这个问题(将CDC流转为追加流)。
SELECT /*+ LOOKUP('table'='c', 'retry-predicate'='lookup_miss', 'output-mode'='allow_unordered', 'retry-strategy'='fixed_delay', 'fixed-delay'='1s', 'max-attempts'='600') */o.order_id, o.total, c.country, c.zip
FROM orders AS o
JOIN customers /*+ OPTIONS('lookup.async'='true', 'lookup.async-thread-number'='16') */
FOR SYSTEM_TIME AS OF o.proc_time AS c
ON o.customer_id = c.id;
1.4 max_pt功能
-
在传统的数据仓库中,每个分区通常维护最新的完整数据,因此这种分区表只需要连接最新的分区即可。Paimon特别为此场景开发了max_pt功能。
-
通过max_pt,Lookup节点能够自动刷新并查询最新分区的数据,确保所使用的客户信息始终是最新的,而不需要手动干预来确定或切换到最新的数据分区。
-
这种方法特别适用于需要频繁更新和查询最新数据的场景,可以大大提高数据处理的效率和准确性。
-- 1、分区用户维表
drop table if exists customers;
CREATE TABLE customers (id INT,name STRING,country STRING,zip STRING,dt STRING,PRIMARY KEY (id, dt) NOT ENFORCED
) PARTITIONED BY (dt);-- 插入数据(维表关联时候,只查找'2025-02-19'分区数据)
INSERT INTO customers VALUES
(1, 'Alice', 'USA', '10001', '2025-02-18'),
(2, 'Bob', 'UK', '20002', '2025-02-18'),
(3, 'Charlie', 'Germany', '30003', '2025-02-18'),
(1, 'Alice', 'USA', '10002', '2025-02-19'), -- 更新了 Alice 的邮编
(4, 'David', 'France', '40004', '2025-02-19');-- 2、订单信息表(解析kafka数据)
CREATE TEMPORARY TABLE orders (order_id BIGINT,customer_id INT,total DECIMAL(10, 2),proc_time AS PROCTIME()
) WITH ('connector' = 'kafka','topic' = 'orders_topic','properties.bootstrap.servers' = 'localhost:9092','format' = 'json','properties.group.id' = 'testordersGroup','scan.startup.mode' = 'earliest-offset','json.fail-on-missing-field' = 'false','json.ignore-parse-errors' = 'true'
);-- 创建topic
/opt/apps/kafka_2.12-2.6.2/bin/kafka-topics.sh --create --topic orders_topic --replication-factor 1 --partitions 1 --bootstrap-server centos01:9092
-- 启动命令行生产者,生产数据
/opt/apps/kafka_2.12-2.6.2/bin/kafka-console-producer.sh --topic orders_topic --bootstrap-server centos01:9092
{"order_id":1001,"customer_id":1,"total":50.0}
{"order_id":1002,"customer_id":2,"total":30.0}
{"order_id":1004,"customer_id":4,"total":20.0}-- 'lookup.dynamic-partition'='max_pt()': 这个选项指示查找节点自动定位并使用最新(最大)的分区。max_pt()函数帮助系统识别最新的分区,确保只查询最新的数据。
-- 'lookup.dynamic-partition.refresh-interval'='1 h': 设置了查找节点刷新最新分区的时间间隔为1小时。这意味着系统会每隔1小时检查一次是否有新的分区可用,并自动更新到最新分区的数据。SELECT o.order_id, o.total, c.country, c.zip
FROM orders AS o
JOIN customers /*+ OPTIONS('lookup.dynamic-partition'='max_pt()', 'lookup.dynamic-partition.refresh-interval'='1 h') */
FOR SYSTEM_TIME AS OF o.proc_time AS c
ON o.customer_id = c.id;+----+----------------------+--------------+--------------------------------+--------------------------------+
| op | order_id | total | country | zip |
+----+----------------------+--------------+--------------------------------+--------------------------------+
| +I | 1001 | 50.00 | USA | 10002 |
| +I | 1004 | 20.00 | France | 40004 |
注
:
-
可以运行一个Flink流式作业来启动针对该paimon维表的查询服务。当QueryService存在时,Flink查找连接(Lookup Join)会优先从该服务获取数据,这将有效提高查询性能。
-
可以通过调用sys.query_service系统函数来实现:
CALL sys.query_service('paimon_db.customers', 4); -- 设置并行度为4
或者通过下面action包开启<FLINK_HOME>/bin/flink run \/path/to/paimon-flink-action-1.0.0.jar \query_service \--warehouse <warehouse-path> \--database <database-name> \--table <table-name> \[--parallelism <parallelism>] \[--catalog_conf <paimon-catalog-conf> [--catalog_conf <paimon-catalog-conf> ...]]
-
查询服务能够在内存中缓存频繁访问的数据,并以高并发的方式提供这些数据,减少了磁盘I/O操作和网络延迟的影响。
2 集成Mysql CDC
-
可以通过 Flink SQL 或者 Flink DataStream API 将 Flink CDC 数据写入 Paimon 中,也可以通过Paimon 提供的 CDC 工具来完成入湖。那这两种方式有什么区别呢?
-
上图是使用 Flink SQL 来完成入湖,简单,但是当源表添加新列后,同步作业不会同步新的列,下游 Paimon 表也不会增加新列。
-
上图是使用 Paimon CDC 工具来同步数据,可以看到,
当源表发生列的新增后,流作业会自动新增列的同步,并传导到下游的 Paimon 表中,完成 Schema Evolution 的同步
。 -
Paimon CDC 工具也提供了整库同步:
- 一个作业同步多张表,以低成本的方式同步大量
小表
- 作业里同时自动进行 Schema Evolution
- 新表将会被自动进行同步,你不用重启作业,全自动完成
- 一个作业同步多张表,以低成本的方式同步大量
-
推荐阅读:Flink + Paimon 数据 CDC 入湖最佳实践
2.1 MySQL一张表同步到Paimon一张表
2.1.1 环境准备
# mysql-cdc相关jar包的下载地址,同时还需要mysql-connector
https://repo.maven.apache.org/maven2/org/apache/flink/flink-connector-mysql-cdc/3.1.1/
https://repo.maven.apache.org/maven2/org/apache/flink/flink-cdc-pipeline-connector-mysql/3.1.1/
https://repo.maven.apache.org/maven2/org/apache/flink/flink-cdc-common/3.1.1/# 在flink的lib目录添加下面的jar包
[root@centos01 lib]# ll /opt/apps/flink-1.16.0/lib/
-rw-r--r--. 1 root root 259756 Feb 19 15:13 flink-cdc-common-3.1.1.jar
-rw-r--r--. 1 root root 21286022 Feb 19 11:40 flink-cdc-pipeline-connector-mysql-3.1.1.jar
-rw-r--r--. 1 root root 388680 Feb 19 10:57 flink-connector-mysql-cdc-3.1.1.jar
-rw-r--r--. 1 root root 2475087 Feb 19 10:58 mysql-connector-java-8.0.27.jar
......# 开启MySQL Binlog并重启MySQL
[root@centos01 ~]# vim /etc/my.cnf
#添加如下配置信息,开启`cdc_db`数据库的Binlog
#数据库id
server-id = 1
##启动binlog,该参数的值会作为binlog的文件名
log-bin=mysql-bin
#binlog类型
binlog_format=row
##启用binlog的数据库,需根据实际情况作出修改
binlog-do-db=cdc_db[root@centos01 ~]# systemctl restart mysqld# 启动hadoop和yarn
[root@centos01 ~]# start-all.sh
# 启动Hive
[root@centos01 ~]# nohup hive --service metastore 2>&1 &
[root@centos01 ~]# nohup hive --service hiveserver2 2>&1 &
# yarn-session模式
# http://centos01:8088/cluster中可以看到Flink session cluster的job ID
[root@centos01 ~]# /opt/apps/flink-1.16.0/bin/yarn-session.sh -d
# 启动Flink的sql-client
[root@centos01 ~]# /opt/apps/flink-1.16.0/bin/sql-client.sh -s yarn-session
- 使用Hive的元数据
Flink SQL> CREATE CATALOG paimon_hive_catalog WITH ('type' = 'paimon','metastore' = 'hive','uri' = 'thrift://centos01:9083'
);Flink SQL> USE CATALOG paimon_hive_catalog;
Flink SQL> create database if not exists paimon_db;
Flink SQL> use paimon_db;# 设置显示模式
Flink SQL> SET 'sql-client.execution.result-mode' = 'tableau';
Flink SQL> SET 'execution.runtime-mode' = 'batch';
2.1.2 案例详解
- 如果指定的Paimon表不存在,将自动创建表。其schema将从所有指定的MySQL表派生;
- 如果Paimon 表已存在,则其schema将与所有指定MySQL表的schema进行比较;
仅支持同步具有主键的MySQL表
;- 也可MySQL多张表同步到Paimon一张表,可以查看官网示例。
-- 准备测试数据
DROP TABLE IF EXISTS `user_info`;
CREATE TABLE `user_info` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',`login_name` varchar(200) DEFAULT NULL COMMENT '用户名称',`name` varchar(200) DEFAULT NULL COMMENT '用户姓名',`phone_num` varchar(200) DEFAULT NULL COMMENT '手机号',`birthday` date DEFAULT NULL COMMENT '用户生日',`gender` varchar(1) DEFAULT NULL COMMENT '性别 M男,F女',`create_time` datetime DEFAULT NULL COMMENT '创建时间',`operate_time` datetime DEFAULT NULL COMMENT '修改时间',PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;-- ----------------------------
-- Records of user_info
-- ----------------------------
INSERT INTO `user_info`(`login_name`, `name`, `phone_num`, `birthday`, `gender`, `create_time`, `operate_time`) VALUES
('zhangsan', '张三', '13800001234', '1990-01-01', 'M', NOW(), NOW()),
('lisi', '李四', '13800005678', '1992-02-02', 'F', NOW(), NOW()),
('wangwu', '王五', '13800009012', '1995-03-03', 'M', NOW(), NOW()),
('zhaoliu', '赵六', '13800003456', '1998-04-04', 'F', NOW(), NOW()),
('sunqi', '孙七', '13800007890', '2000-05-05', 'M', NOW(), NOW());CREATE TABLE `orders` (`order_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '订单编号',`user_id` bigint(20) NOT NULL COMMENT '用户编号',`order_date` datetime DEFAULT NULL COMMENT '订单日期',`total_price` decimal(10,2) DEFAULT NULL COMMENT '订单总价',PRIMARY KEY (`order_id`) USING BTREE,KEY `idx_user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;INSERT INTO `orders`(`user_id`, `order_date`, `total_price`) VALUES
(1001, '2025-02-18 14:32:10', 199.99),
(1002, '2025-02-19 09:15:30', 299.50),
(1001, '2025-02-19 12:47:05', 79.99),
(1003, '2025-02-19 13:00:00', 499.00),
(1004, '2025-02-20 08:20:25', 159.99);
# 按照天进行分区
[root@centos01 ~]# /opt/apps/flink-1.16.0/bin/flink run \/opt/apps/flink-1.16.0/lib/paimon-flink-action-1.0.0.jar \mysql-sync-table \--warehouse hdfs://centos01:8020/user/hive/warehouse \--database paimon_db \--table ods_user_info_cdc \--primary-keys pt,id \# 指定分区键,分区键是通过函数转换而来--partition_keys pt \--computed_column 'pt=date_format(operate_time, yyyyMMdd)' \--mysql-conf hostname=centos01 \--mysql-conf username=root \--mysql-conf password=123456 \--mysql-conf database-name=cdc_db \--mysql-conf table-name='user_info' \--catalog-conf metastore=hive \--catalog-conf uri=thrift://centos01:9083 \--table-conf bucket=2 \--table-conf changelog-producer=input \--table-conf sink.parallelism=2
- 我们可以进行测试了
-- 此时会自动创建paimon表(无需我们手动建表了)
Flink SQL> select * from ods_user_info_cdc;
+----+------------+------+-------------+------------+--------+---------------------+---------------------+----------+
| id | login_name | name | phone_num | birthday | gender | create_time | operate_time | pt |
+----+------------+------+-------------+------------+--------+---------------------+---------------------+----------+
| 3 | wangwu | 王五 | 13800009012 | 1995-03-03 | M | 2025-02-19 17:28:18 | 2025-02-19 17:28:18 | 20250219 |
| 1 | zhangsan | 张三 | 13800001234 | 1990-01-01 | M | 2025-02-19 17:28:18 | 2025-02-19 17:28:18 | 20250219 |
| 2 | lisi | 李四 | 13800005678 | 1992-02-02 | F | 2025-02-19 17:28:18 | 2025-02-19 17:28:18 | 20250219 |
| 4 | zhaoliu | 赵六 | 13800003456 | 1998-04-04 | F | 2025-02-19 17:28:18 | 2025-02-19 17:28:18 | 20250219 |
| 5 | sunqi | 孙七 | 13800007890 | 2000-05-05 | M | 2025-02-19 17:28:18 | 2025-02-19 17:28:18 | 20250219 |
+----+------------+------+-------------+------------+--------+---------------------+---------------------+----------+-- 修改原始表的schema
mysql> ALTER TABLE user_info ADD COLUMN email varchar(255);
mysql> INSERT INTO `user_info`(`login_name`, `name`, `phone_num`, `birthday`, `gender`, `create_time`, `operate_time`, `email`)
values('hank', '汉克', '18600007890', '2000-05-05', 'M', NOW(), NOW(), 'hank@163.com');-- 注意:我们此时在原始sql-client窗口查询,`email`字段并没有加上
Flink SQL> select * from ods_user_info_cdc;
+----+------------+------+-------------+------------+--------+---------------------+---------------------+----------+
| id | login_name | name | phone_num | birthday | gender | create_time | operate_time | pt |
+----+------------+------+-------------+------------+--------+---------------------+---------------------+----------+
| 3 | wangwu | 王五 | 13800009012 | 1995-03-03 | M | 2025-02-19 18:01:18 | 2025-02-19 18:01:18 | 20250219 |
| 1 | zhangsan | 张三 | 13800001234 | 1990-01-01 | M | 2025-02-19 18:01:18 | 2025-02-19 18:01:18 | 20250219 |
| 2 | lisi | 李四 | 13800005678 | 1992-02-02 | F | 2025-02-19 18:01:18 | 2025-02-19 18:01:18 | 20250219 |
| 4 | zhaoliu | 赵六 | 13800003456 | 1998-04-04 | F | 2025-02-19 18:01:18 | 2025-02-19 18:01:18 | 20250219 |
| 5 | sunqi | 孙七 | 13800007890 | 2000-05-05 | M | 2025-02-19 18:01:18 | 2025-02-19 18:01:18 | 20250219 |
| 6 | hank | 汉克 | 18600007890 | 2000-05-05 | M | 2025-02-19 18:01:43 | 2025-02-19 18:01:43 | 20250219 |
+----+------------+------+-------------+------------+--------+---------------------+---------------------+----------+-- 其实,此时的schema已经改变,我们查看hdfs上的schema信息会发现`email`字实际上已经添加
[root@centos01 ~]# hdfs dfs -cat /user/hive/warehouse/paimon_db.db/ods_user_info_cdc/schema/schema-1-- 因此,我们需要另外重新启动一个sql-client窗口进行查询,可以发现是正确的
Flink SQL> select * from ods_user_info_cdc;
+----+------------+------+-------------+------------+--------+---------------------+---------------------+----------+--------------+
| id | login_name | name | phone_num | birthday | gender | create_time | operate_time | pt | email |
+----+------------+------+-------------+------------+--------+---------------------+---------------------+----------+--------------+
| 3 | wangwu | 王五 | 13800009012 | 1995-03-03 | M | 2025-02-19 18:01:18 | 2025-02-19 18:01:18 | 20250219 | <NULL> |
| 1 | zhangsan | 张三 | 13800001234 | 1990-01-01 | M | 2025-02-19 18:01:18 | 2025-02-19 18:01:18 | 20250219 | <NULL> |
| 2 | lisi | 李四 | 13800005678 | 1992-02-02 | F | 2025-02-19 18:01:18 | 2025-02-19 18:01:18 | 20250219 | <NULL> |
| 4 | zhaoliu | 赵六 | 13800003456 | 1998-04-04 | F | 2025-02-19 18:01:18 | 2025-02-19 18:01:18 | 20250219 | <NULL> |
| 5 | sunqi | 孙七 | 13800007890 | 2000-05-05 | M | 2025-02-19 18:01:18 | 2025-02-19 18:01:18 | 20250219 | <NULL> |
| 6 | hank | 汉克 | 18600007890 | 2000-05-05 | M | 2025-02-19 18:01:43 | 2025-02-19 18:01:43 | 20250219 | hank@163.com |
+----+------------+------+-------------+------------+--------+---------------------+---------------------+----------+--------------+
注:
- 上面自动创建的paimon表是分区表,
但是在Hive中不是分区表
-- 报错
0: jdbc:hive2://192.168.42.101:10000> show partitions ods_user_info_cdc ;
Error: Error while processing statement: FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. Table ods_user_info_cdc is not a partitioned table (state=42000,code=1)
- 要想在hive中也是分区表,需要在同步时候设置参数
metastore.partitioned-table=true
# 同步到另一张paimon表,并设置hive分区参数
[root@centos01 ~]# /opt/apps/flink-1.16.0/bin/flink run \/opt/apps/flink-1.16.0/lib/paimon-flink-action-1.0.0.jar \mysql-sync-table \--warehouse hdfs://centos01:8020/user/hive/warehouse \--database paimon_db \--table ods_user_info_partition_cdc \--primary-keys pt,id \--partition_keys pt \--computed_column 'pt=date_format(operate_time, yyyyMMdd)' \--mysql-conf hostname=centos01 \--mysql-conf username=root \--mysql-conf password=123456 \--mysql-conf database-name=cdc_db \--mysql-conf table-name='user_info' \--catalog-conf metastore=hive \--catalog-conf uri=thrift://centos01:9083 \--table-conf bucket=2 \--table-conf changelog-producer=input \--table-conf metastore.partitioned-table=true \--table-conf sink.parallelism=2
- 然后可以从hive中读取相关分区了
0: jdbc:hive2://192.168.42.101:10000> show partitions ods_user_info_partition_cdc ;
+--------------+
| partition |
+--------------+
| pt=20250219 |
+--------------+-- 读取相关分区数据
0: jdbc:hive2://192.168.42.101:10000> select * from ods_user_info_partition_cdc a where pt=20250219;
+-------+---------------+---------+--------------+-------------+-----------+------------------------+------------------------+-----------+---------------+
| a.id | a.login_name | a.name | a.phone_num | a.birthday | a.gender | a.create_time | a.operate_time | a.pt | a.email |
+-------+---------------+---------+--------------+-------------+-----------+------------------------+------------------------+-----------+---------------+
| 1 | zhangsan | 张三 | 13800001234 | 1990-01-01 | M | 2025-02-19 18:01:18.0 | 2025-02-19 18:01:18.0 | 20250219 | NULL |
| 2 | lisi | 李四 | 13800005678 | 1992-02-02 | F | 2025-02-19 18:01:18.0 | 2025-02-19 18:01:18.0 | 20250219 | lisi@qq.com |
| 4 | zhaoliu | 赵六 | 13800003456 | 1998-04-04 | F | 2025-02-19 18:01:18.0 | 2025-02-19 18:01:18.0 | 20250219 | NULL |
| 5 | sunqi | 孙七 | 13800007890 | 2000-05-05 | M | 2025-02-19 18:01:18.0 | 2025-02-19 18:01:18.0 | 20250219 | NULL |
| 6 | hank | 汉克 | 18600007890 | 2000-05-05 | M | 2025-02-19 18:01:43.0 | 2025-02-19 18:01:43.0 | 20250219 | hank@163.com |
| 3 | wangwu | 王五 | 13800009012 | 1995-03-03 | M | 2025-02-19 18:01:18.0 | 2025-02-19 18:01:18.0 | 20250219 | NULL |
+-------+---------------+---------+--------------+-------------+-----------+------------------------+------------------------+-----------+---------------+-- 需要注意的是,如果我们修改数据,原始的hive分区原始数据可能会减少
-- 下面示例,我们修改了两条数据
0: jdbc:hive2://192.168.42.101:10000> select * from ods_user_info_partition_cdc a where pt=20250219;
+-------+---------------+---------+--------------+-------------+-----------+------------------------+------------------------+---------------+-----------+
| a.id | a.login_name | a.name | a.phone_num | a.birthday | a.gender | a.create_time | a.operate_time | a.email | a.pt |
+-------+---------------+---------+--------------+-------------+-----------+------------------------+------------------------+---------------+-----------+
| 2 | lisi | 李四 | 13800005678 | 1992-02-02 | F | 2025-02-19 18:01:18.0 | 2025-02-19 18:01:18.0 | lisi@qq.com | 20250219 |
| 4 | zhaoliu | 赵六 | 13800003456 | 1998-04-04 | F | 2025-02-19 18:01:18.0 | 2025-02-19 18:01:18.0 | NULL | 20250219 |
| 5 | sunqi | 孙七 | 13800007890 | 2000-05-05 | M | 2025-02-19 18:01:18.0 | 2025-02-19 18:01:18.0 | NULL | 20250219 |
| 6 | hank | 汉克 | 18600007890 | 2000-05-05 | M | 2025-02-19 18:01:43.0 | 2025-02-19 18:01:43.0 | hank@163.com | 20250219 |
+-------+---------------+---------+--------------+-------------+-----------+------------------------+------------------------+---------------+-----------+
4 rows selected (0.199 seconds)
0: jdbc:hive2://192.168.42.101:10000> select * from ods_user_info_partition_cdc a where pt=20250220;
+-------+---------------+---------+--------------+-------------+-----------+------------------------+------------------------+-------------+-----------+
| a.id | a.login_name | a.name | a.phone_num | a.birthday | a.gender | a.create_time | a.operate_time | a.email | a.pt |
+-------+---------------+---------+--------------+-------------+-----------+------------------------+------------------------+-------------+-----------+
| 3 | wangwu | 王五 | 13800009012 | 1995-03-03 | M | 2025-02-19 18:01:18.0 | 2025-02-20 12:01:18.0 | ww@163.com | 20250220 |
| 1 | zhangsan | 张三三 | 13800001234 | 1990-01-01 | M | 2025-02-19 18:01:18.0 | 2025-02-20 18:01:18.0 | NULL | 20250220 |
+-------+---------------+---------+--------------+-------------+-----------+------------------------+------------------------+-------------+-----------+
2 rows selected (0.189 seconds)
0: jdbc:hive2://192.168.42.101:10000> select * from ods_user_info_partition_cdc a ;
+-------+---------------+---------+--------------+-------------+-----------+------------------------+------------------------+---------------+-----------+
| a.id | a.login_name | a.name | a.phone_num | a.birthday | a.gender | a.create_time | a.operate_time | a.email | a.pt |
+-------+---------------+---------+--------------+-------------+-----------+------------------------+------------------------+---------------+-----------+
| 2 | lisi | 李四 | 13800005678 | 1992-02-02 | F | 2025-02-19 18:01:18.0 | 2025-02-19 18:01:18.0 | lisi@qq.com | 20250219 |
| 4 | zhaoliu | 赵六 | 13800003456 | 1998-04-04 | F | 2025-02-19 18:01:18.0 | 2025-02-19 18:01:18.0 | NULL | 20250219 |
| 5 | sunqi | 孙七 | 13800007890 | 2000-05-05 | M | 2025-02-19 18:01:18.0 | 2025-02-19 18:01:18.0 | NULL | 20250219 |
| 6 | hank | 汉克 | 18600007890 | 2000-05-05 | M | 2025-02-19 18:01:43.0 | 2025-02-19 18:01:43.0 | hank@163.com | 20250219 |
| 3 | wangwu | 王五 | 13800009012 | 1995-03-03 | M | 2025-02-19 18:01:18.0 | 2025-02-20 12:01:18.0 | ww@163.com | 20250220 |
| 1 | zhangsan | 张三三 | 13800001234 | 1990-01-01 | M | 2025-02-19 18:01:18.0 | 2025-02-20 18:01:18.0 | NULL | 20250220 |
+-------+---------------+---------+--------------+-------------+-----------+------------------------+------------------------+---------------+-----------+
- 当然,我们在建立paimon表的时候,也可以指定参数
'metastore.partitioned-table' = 'true'
Flink SQL> drop table if exists flink_p_demo;
Flink SQL> CREATE TABLE flink_p_demo (dt STRING NOT NULL,name STRING NOT NULL,amount BIGINT,PRIMARY KEY (dt, name) NOT ENFORCED
) PARTITIONED BY (dt)
WITH ('connector' = 'paimon','changelog-producer' = 'lookup','metastore.partitioned-table' = 'true' -- 设置为true
);
Flink SQL> insert into flink_p_demo values ('20240725', 'apple', 3), ('20240726', 'banana', 5);0: jdbc:hive2://192.168.42.101:10000> show partitions flink_p_demo;
+--------------+
| partition |
+--------------+
| dt=20240725 |
| dt=20240726 |
+--------------+
0: jdbc:hive2://192.168.42.101:10000> select * from flink_p_demo a where dt = 20240726;
+---------+-----------+-----------+
| a.name | a.amount | a.dt |
+---------+-----------+-----------+
| banana | 5 | 20240726 |
+---------+-----------+-----------+
2.2 整库同步
- 通过官方提供的paimon-action的jar包可以很方便的将 MySQL、Kafka、Mongo等中的数据实时摄入到Paimon中
- 使用paimon-flink-action,采用mysql-sync-database(整库同步),并通过"–including_tables"参数选择要同步的表
- 这种同步模式有效地节省了大量资源开销,相比每个表启动一个 Flink 任务而言,避免了资源的大量浪费。
[root@centos01 ~]# /opt/apps/flink-1.16.0/bin/flink run \/opt/apps/flink-1.16.0/lib/paimon-flink-action-1.0.0.jar \mysql-sync-database \--warehouse hdfs://centos01:8020/user/hive/warehouse \--database paimon_db \--table-prefix "ods_" \--table-suffix "_mysql_cdc" \--mysql-conf hostname=centos01 \--mysql-conf username=root \--mysql-conf password=123456 \--mysql-conf database-name=cdc_db \--catalog-conf metastore=hive \--catalog-conf uri=thrift://centos01:9083 \--table-conf bucket=2 \--table-conf changelog-producer=input \--table-conf sink.parallelism=2 \--including-tables 'user_info|orders'-- 在一个flink任务中同步多个mysql表
-- 在paimon中会自动创建多张表
Flink SQL> select * from ods_orders_mysql_cdc;
Flink SQL> select * from ods_user_info_mysql_cdc;
相关文章:

大数据组件(四)快速入门实时数据湖存储系统Apache Paimon(2)
Paimon的下载及安装,并且了解了主键表的引擎以及changelog-producer的含义参考: 大数据组件(四)快速入门实时数据湖存储系统Apache Paimon(1) 利用Paimon表做lookup join,集成mysql cdc等参考: 大数据组件(四)快速入门实时数据…...

PLC通讯
PPI通讯 是西门子公司专为s7-200系列plc开发的通讯协议。内置于s7-200 CPU中。PPI协议物理上基于RS-485口,通过屏蔽双绞线就可以实现PPI通讯。PPI协议是一种主-从协议。主站设备发送要求到从站设备,从站设备响应,从站不能主动发出信息。主站…...

前端js进阶,ES6语法,包详细
进阶ES6 作用域的概念加深对js理解 let、const申明的变量,在花括号中会生成块作用域,而var就不会生成块作用域 作用域链本质上就是底层的变量查找机制 作用域链查找的规则是:优先查找当前作用域先把的变量,再依次逐级找父级作用域直到全局…...

Scrum方法论指导下的Deepseek R1医疗AI部署开发
一、引言 1.1 研究背景与意义 在当今数智化时代,软件开发方法论对于项目的成功实施起着举足轻重的作用。Scrum 作为一种广泛应用的敏捷开发方法论,以其迭代式开发、快速反馈和高效协作的特点,在软件开发领域占据了重要地位。自 20 世纪 90 …...
LINUX安装使用Redis
参考 Install Redis on Linux | Docs 安装命令 sudo apt-get install -y lsb-release curl gpgcurl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpgsudo chmod 644 /usr/share/keyrings/redis-archive-keyrin…...

基于java新闻管理系统,推荐一款开源cms内容管理系统ruoyi-fast-cms
一、项目概述 1.1 项目背景 在信息高速流通的当下,新闻媒体行业每天都要处理和传播海量信息。传统的新闻管理模式依赖人工操作,在新闻采集、编辑、发布以及后续管理等环节中,不仅效率低下,而且容易出现人为失误。同时࿰…...
054 redisson
文章目录 使用Redisson演示可重入锁读写锁信号量闭锁获取三级分类redisson分布式锁 package com.xd.cubemall.product.config;import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.config.Config; import org.springframework.context…...

【数据结构】(12) 反射、枚举、lambda 表达式
一、反射 1、反射机制定义及作用 反射是允许程序在运行时检查和操作类、方法、属性等的机制,能够动态地获取信息、调用方法等。换句话说,在编写程序时,不需要知道要操作的类的具体信息,而是在程序运行时获取和使用。 2、反射机制…...
java实现二维码图片生成和编解码
java实现二维码图片生成和编解码 在wutool中,封装了二维码工具类,基于google的zxing库,实现二维码图片生成、编码和解码。 关于wutool wutool是一个java代码片段收集库,针对特定场景提供轻量解决方案,只要按需选择代…...

Java基础常见的面试题(易错!!)
面试题一:为什么 Java 不支持多继承 Java 不支持多继承主要是为避免 “菱形继承问题”(又称 “钻石问题”),即一个子类从多个父类继承到同名方法或属性时,编译器无法确定该调用哪个父类的成员。同时,多继承…...

hugging face---transformers包
一、前言 不同于计算机视觉的百花齐放,不同网络适用不同情况,NLP则由Transformer一统天下。transformer是2017年提出的一种基于自注意力机制的神经网络架构,transformers库是hugging face社区创造的一个py库,通过该库可以实现统一…...

网络安全防护指南:筑牢网络安全防线(510)
一、网络安全的基本概念 (一)网络的定义 网络是指由计算机或者其他信息终端及相关设备组成的按照一定的规则和程序对信息收集、存储、传输、交换、处理的系统。在当今数字化时代,网络已经成为人们生活和工作中不可或缺的一部分。它连接了世…...

微信小程序实现拉卡拉支付
功能需求:拉卡拉支付(通过跳转拉卡拉平台进行支付),他人支付(通过链接进行平台跳转支付) 1.支付操作 //支付 const onCanStartPay async (obj) > {uni.showLoading({mask: true})// 支付接口获取需要传…...
git从本地其他设备上fetch分支
在 Git 中,如果你想从本地其他设备上获取分支,可以通过以下几种方式实现。不过,需要注意的是,Git 本身是分布式版本控制系统,通常我们是从远程仓库(如 GitHub、GitLab 等)拉取分支,而…...

【干货教程】Windows电脑本地部署运行DeepSeek R1大模型(基于Ollama和Chatbox)
文章目录 一、环境准备二、安装Ollama2.1 访问Ollama官方网站2.2 下载适用于Windows的安装包2.3 安装Ollama安装包2.4 指定Ollama安装目录2.5 指定Ollama的大模型的存储目录 三、选择DeepSeek R1模型四、下载并运行DeepSeek R1模型五、常见问题解答六、使用Chatbox进行交互6.1 …...

基于 SSM框架 的 “捷邻小程序” 系统的设计与实现
大家好,今天要和大家聊的是一款基于 SSM框架 的 “捷邻小程序” 系统的设计与实现。项目源码以及部署相关事宜请联系我,文末附上联系方式。 项目简介 基于 SSM框架 的 “捷邻小程序” 系统设计与实现的主要使用者分为 管理员 和 用户,没有授…...

基于Springboot医院预约挂号小程序系统【附源码】
基于Springboot医院预约挂号小程序系统 效果如下: 小程序主页面 帖子页面 医生账号页面 留言内容页面 管理员主页面 用户管理页面 我的挂号页面 医生管理页面 研究背景 随着信息技术的飞速发展和互联网医疗的兴起,传统的医疗服务模式正面临着深刻的变…...

基于AVue的二次封装:快速构建后台管理系统的CRUD方案
基于AVue的二次封装:快速构建后台管理系统的CRUD方案 在开发后台管理系统时,表格是常见的组件之一。然而,使用原生的Element Plus实现CRUD(增删改查)功能往往需要编写大量重复代码,过程繁琐。即使借助类似…...

【含开题报告+文档+PPT+源码】基于springboot加vue 前后端分离的校园新闻审核发布管理系统
开题报告 本研究旨在设计并实现一套基于SpringBoot后端框架结合Vue前端技术的校园新闻发布系统,该系统面向学生用户群体提供了全面的功能服务。学生用户通过身份验证登录后,能够便捷高效地获取校园内的各类新闻资讯,实时了解校内动态。系统不…...
Qt 是一个跨平台的 C++ 应用程序框架
Qt 是一个跨平台的 C++ 应用程序框架,广泛用于开发图形用户界面(GUI)应用程序,也可以用于开发非 GUI 程序,如命令行工具和控制台应用程序。Qt 提供了丰富的类库和工具,支持多种操作系统,包括 Windows、macOS、Linux 等。 主要特点: 跨平台:Qt 支持多种操作系统,开发…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...

LLMs 系列实操科普(1)
写在前面: 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容,原视频时长 ~130 分钟,以实操演示主流的一些 LLMs 的使用,由于涉及到实操,实际上并不适合以文字整理,但还是决定尽量整理一份笔…...

逻辑回归暴力训练预测金融欺诈
简述 「使用逻辑回归暴力预测金融欺诈,并不断增加特征维度持续测试」的做法,体现了一种逐步建模与迭代验证的实验思路,在金融欺诈检测中非常有价值,本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...
小木的算法日记-多叉树的递归/层序遍历
🌲 从二叉树到森林:一文彻底搞懂多叉树遍历的艺术 🚀 引言 你好,未来的算法大神! 在数据结构的世界里,“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的,它…...
面试高频问题
文章目录 🚀 消息队列核心技术揭秘:从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"?性能背后的秘密1.1 顺序写入与零拷贝:性能的双引擎1.2 分区并行:数据的"八车道高速公路"1.3 页缓存与批量处理…...
在golang中如何将已安装的依赖降级处理,比如:将 go-ansible/v2@v2.2.0 更换为 go-ansible/@v1.1.7
在 Go 项目中降级 go-ansible 从 v2.2.0 到 v1.1.7 具体步骤: 第一步: 修改 go.mod 文件 // 原 v2 版本声明 require github.com/apenella/go-ansible/v2 v2.2.0 替换为: // 改为 v…...