大数据组件(四)快速入门实时数据湖存储系统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等参考: 大数据组件(四)快速入门实时数据…...
vue3父子组件props传值,defineprops怎么用?(组合式)
目录 1.基础用法 2.使用解构赋值的方式定义props 3.使用toRefs的方式解构props (1).通过ref响应式变量,修改对象本身不会触发响应式 1.基础用法 父组件通过在子组件上绑定子组件中定义的props(:props“”)传递数据给子组件 <!-- 父组件…...
Linux /etc/fstab文件详解:自动挂载配置指南(中英双语)
Linux /etc/fstab 文件详解:自动挂载配置指南 在 Linux 系统中,/etc/fstab(File System Table)是一个至关重要的配置文件,它用于定义系统开机时自动挂载的文件系统。如果你想让磁盘分区、远程存储(如 NFS&…...
Test the complete case
Test the complete case python写的一段 由pytest测试框架/allure报告框架/parameters数据驱动组成的完整案例代码 目录结构 project/ ├── test_cases/ │ ├── __init__.py │ └── test_math_operations.py # 测试用例 ├── test_data/ │ └── math_dat…...
装win10系统提示“windows无法安装到这个磁盘,选中的磁盘采用GPT分区形式”解决方法
问题描述 我们在u盘安装原版win10 iso镜像时,发现在选择硬盘时提示了“windows无法安装到这个磁盘,选中的磁盘采用GPT分区形式”,直接导致了无法继续安装下去。出现这种情况要怎么解决呢? 原因分析: 当您在安装Windows操作系统…...
【pytest-jira】自动化用例结合jira初版集成思路
【pytest】编写自动化测试用例命名规范README 【python】连接Jira获取token以及jira对象 【python】解析自动化脚本文件并按照测试周期存储记录 【python】向Jira推送自动化用例执行成功 【python】向Jira测试计划下,附件中增加html测试报告 以下内容主要是介绍jira…...
PHP 会话(Session)实现用户登陆功能
Cookie是一种在客户端和服务器之间传递数据的机制。它是由服务器发送给客户端的小型文本文件,保存在客户端的浏览器中。每当浏览器向同一服务器发送请求时,它会自动将相关的Cookie信息包含在请求中,以便服务器可以使用这些信息来提供个性化的…...
大模型安全问题详解(攻击技术、红队测试与安全漏洞)
文章目录 大模型攻击技术提示注入攻击(Prompt Injection)数据投毒攻击(Data Poisoning)模型克隆攻击(Model Cloning)拒绝服务攻击(DoS)和拒绝钱包攻击(DoW)插…...
【愚公系列】《鸿蒙原生应用开发从零基础到多实战》002-TypeScript 类型系统详解
标题详情作者简介愚公搬代码头衔华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主&…...
C# 将非托管Dll嵌入exe中(一种实现方法)
一、环境准备 电脑系统:Windows 10 专业版 20H2 IDE:Microsoft Visual Studio Professional 2022 (64 位) - Current 版本 17.11.4 其他: 二、测试目的 将基于C++创建DLL库,封装到C#生成的exe中。 一般C++创建的库,在C#中使用,都是采用DllImport导入的,且要求库处…...
c sharp 特性详解
文章目录 一、特性基础用法二、常见的内置特性三、自定义特性四、通过反射读取特性五、实际应用场景六、练习 一、特性基础用法 什么是特性? 特性是一种继承System.Attribute类,用于标记代码元素 特性的语法: [AttributeName(Parameter1, P…...
Langchain vs. LlamaIndex:哪个在集成MongoDB并分析资产负债表时效果更好?
Langchain vs. LlamaIndex:哪个在集成MongoDB并分析资产负债表时效果更好? 随着大语言模型(LLM)在实际应用中的普及,许多开发者开始寻求能够帮助他们更高效地开发基于语言模型的应用框架。在众多框架中,La…...
MySQL日常维护工具------备份
MySQL日常维护工具-备份 一、MySQL字符集 (一)字符集介绍 字符(Character)是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。字符集(Character set)是多个字符的集合,字符集种类较多,每个字符集…...
硬核技术组合!用 DeepSeek R1、Ollama、Docker、RAGFlow 打造专属本地知识库
文章目录 一、引言二、安装Ollama部署DeepSeekR1三、安装Docker四、安装使用RAGFlow4.1 系统架构4.2 部署流程4.3 使用RAGFlow4.4 在RAGFlow中新增模型4.5 创建知识库4.6 创建私人助理使用RGA 一、引言 本地部署DeepSeek R1 Ollama RAGFlow构建个人知识库,通过将…...
[VSCode]彻底卸载和重装,并搭建Java开发环境
VSCode彻底卸载 由于当初是朋友帮忙装的,所以准备卸载,自己装一遍 从控制面板找到 vscode 将其卸载。 此时仅仅是删除了应用软件 删除安装插件 在图示路径中找到 .vscode 文件夹,将其删除,即可彻底清除安装的插件 C:\Users\user\.vscode …...
Scrum方法论指导下的Deepseek R1医疗AI部署开发
一、引言 1.1 研究背景与意义 在当今数智化时代,软件开发方法论对于项目的成功实施起着举足轻重的作用。Scrum 作为一种广泛应用的敏捷开发方法论,以其迭代式开发、快速反馈和高效协作的特点,在软件开发领域占据了重要地位。自 20 世纪 90 …...
政安晨的AI大模型训练实践 九 - 熟悉LLaMA Factory的详细参数含义-基本概念理解一下
政安晨的个人主页:政安晨 欢迎 👍点赞✍评论⭐收藏 希望政安晨的博客能够对您有所裨益,如有不足之处,欢迎在评论区提出指正! 小伙伴铁子们,上手先熟悉起来训练工具的每一个参数,很重要。 参照我…...
保姆级教程 | Office-Word中图目录制作及不显示图注引文的方法
背景 由于毕业论文的格式修改需要(没错,我终于要拿下PhD了。差不多四个月没更新,主要是①根据处理完的数据完成小论文撰写;②找工作...③完成学位论文的撰写。因而对建模和数据处理的需求不高,对有些时隔久远的博文具…...
Linux lsblk 命令详解:查看磁盘和分区信息 (中英双语)
Linux lsblk 命令详解:查看磁盘和分区信息 在 Linux 系统中,管理磁盘设备和分区是日常运维工作的重要部分。而 lsblk 命令是一个强大的工具,它用于列出系统中的块设备(block devices)信息,可以帮助我们快速…...
使用API有效率地管理Dynadot域名,为域名部署DNS安全拓展(DNSSEC)
关于Dynadot Dynadot是通过ICANN认证的域名注册商,自2002年成立以来,服务于全球108个国家和地区的客户,为数以万计的客户提供简洁,优惠,安全的域名注册以及管理服务。 Dynadot平台操作教程索引(包括域名邮…...
前后端项目部署服务器(传统部署和Docker部署)
内外网 开发环境连外网(8.140.26.187),测试/生产环境连内网(172.20.59.17) 内外网地址不同,但指定的库是同一个 内网IP地址范围包括: 10.0.0.0 到 10.255.255.255172.16.0.0 到 172.31.2551…...
深入HBase——核心组件
引入 通过上一篇对HBase核心算法和数据结构的梳理,我们对于其底层设计有了更多理解。现在我们从引入篇里面提到的HBase架构出发,去看看其中不同组件是如何设计与实现。 核心组件 首先,需要提到的就是HBase架构中会依赖到的Zookeeper和HDFS。…...
虚拟机从零实现机器人控制
1. 系统安装 因Docker不适合需要图形界面的开发,因此使用虚拟机VMware方便可视化界面方式查看效果,相关软件可以从官网下载,这里有一整套免费安装文件百度网盘地址: 2. ROS安装 Ubuntu 22.04:https://docs.ros.org…...
最新本地部署 DeepSeekR1 蒸馏\满血量化版 + WebOpenUI 完整教程(Ubuntu\Linux系统\Ollama)
测试机为6133CPU(40Cores)256G D44*4090D 24G 一种方法是部署蒸馏版Distill模型。一种是部署Huggingface上unsloth的量化版模型 Ollama及模型安装 1.下载并安装ollama curl -fsSL https://ollama.com/install.sh | sh如果下载不动可以试试挂梯子或者再试几次 挂代理代码&…...
Linux基本指令(三)+ 权限
文章目录 基本指令grep打包和压缩zip/unzipLinux和windows压缩包互传tar(重要)Linux和Linux压缩包互传 bcuname -r常用的热键关机外壳程序 知识点打包和压缩 Linux中的权限用户权限 基本指令 grep 1. grep可以过滤文本行 done用于标记循环的结束&#x…...
kafka-集群缩容
一. 简述: 当业务增加时,服务瓶颈,我们需要进行扩容。当业务量下降时,为成本考虑。自然也会涉及到缩容。假设集群有 15 台机器,预计缩到 10 台机器,那么需要做 5 次缩容操作,每次将一个节点下线…...
【nextJs】官网demo学习
最近在看nextjs官方的demo,把一些值得记录的记下来,方便查询; 1.连接数据库 1.1需要把代码传到远程仓库: 执行下面的命令: // 把#后面内容写入readme文件中 echo "# nextjs-dashboard" >> README.…...
在nodejs中使用ElasticSearch(一)安装,使用
使用docker安装ElasticSearch和Kibana 1)创建相应的data文件夹和子文件夹用来持久化ElasticSearch和kibana数据 2)提前创建好elasticsearch配置文件 data/elasticsearch/config/elasticsearch.yml文件 # Elasticsearch Configuration # # NOTE: Elas…...
图的最短路径:Dijkstra算法和Bellman-Ford算法(C++)
上文中我们了解了拓扑排序, 本节我们来学习最短路径的算法. 在图论中, 最短路径问题是指在一个加权图中找到两个节点之间的权重和最小的路径. 最短路径问题是一个基础且重要的主题. 它不仅在理论上具有挑战性, 而且在实际应用中也非常广泛, 比如交通导航, 社交网络分析等. 本…...
【WebGL】fbo双pass案例
双pass渲染案例(离线渲染一个三角面,然后渲染到一个占满屏幕的矩阵上) 离线渲染如何需要开启深度测试的话,需要额外操作,这里不展开 <!DOCTYPE html> <html lang"en"><head><meta ch…...
【机器学习】CNN与Transformer的表面区别与本质区别
仅供参考 表面区别 1. 结构和原理: CNN:主要通过卷积层来提取特征,这些层通过滑动窗口(卷积核)捕捉局部特征,并通过池化层(如最大池化)来降低特征的空间维度。CNN非常适合处理具有网格状拓扑结构的数据,如图像。Transformer:基于自注意力(Self-Attention)机制,能…...
C++:pthread的使用
pthread 简介 pthread 是 POSIX 线程(POSIX Threads)的简称,它是 POSIX 标准中定义的线程接口规范。pthread 库提供了一系列函数,用于创建、销毁、同步和管理线程。在类 Unix 系统(如 Linux、macOS)中&…...
Docker 容器安装 Dify的两种方法
若 Windows 已安装 Docker,可借助 Docker 容器来安装 Dify: 一、方法一 1. 拉取 Dify 镜像 打开 PowerShell 或命令提示符(CMD),运行以下命令从 Docker Hub 拉取 Dify 的镜像(Docker Hub中找到该命令行&…...
nodejs:express + js-mdict 作为后端,vue 3 + vite 作为前端,在线查询英汉词典
向 doubao.com/chat/ 提问: node.js js-mdict 作为后端,vue 3 vite 作为前端,编写在线查询英汉词典 后端部分(express js-mdict ) 1. 项目结构 首先,创建一个项目目录,结构如下࿱…...
mysql之事务深度解析与实战应用:保障数据一致性的基石
文章目录 MySQL 事务深度解析与实战应用:保障数据一致性的基石一、事务核心概念与原理1.1 事务的本质与意义1.2 事务的 ACID 特性1.2.1 原子性 (Atomicity)1.2.2 一致性 (Consistency)1.2.3 隔离性 (Isolation)1.2.4 持久性 (Durability) 1.3 事务隔离级别与并发问题…...
einops测试
文章目录 1. einops2. code3. pytorch 1. einops einops 主要是通过爱因斯坦标记法来处理张量矩阵的库,让矩阵处理上非常简单。 conda : conda install conda-forge::einopspython: 2. code import torch import torch.nn as nn import torch.nn.functional as…...
华为云deepseek大模型平台:deepseek满血版
华为云硅基流动使用Chatbox接入DeepSeek-R1满血版671B 1、注册: 华为云deepseek大模型平台注册:https://cloud.siliconflow.cn/i/aDmz6aVN 说明:填写邀请码的话邀请和被邀请的账号都会获得2000 万 Tokens;2个帐号间不会与其他关联…...
Elasticsearch Open Inference API 增加了对 Jina AI 嵌入和 Rerank 模型的支持
作者:Hemant Malik 及 Joan Fontanals Martnez 探索如何使用 Elasticsearch Open Inference API 访问 Jina AI 模型。 我们在 Jina AI 的朋友们将 Jina AI 的嵌入模型和重新排名产品的原生集成添加到 Elasticsearch 开放推理 API 中。这包括对行业领先的多语言文本嵌…...
在PHP Web开发中,实现异步处理有几种常见方式的优缺点,以及最佳实践推荐方法
1. 消息队列 使用消息队列(如RabbitMQ、Beanstalkd、Redis)将任务放入队列,由后台进程异步处理。 优点: 任务持久化,系统崩溃后任务不丢失。 支持分布式处理,扩展性强。 实现步骤: 安装消息…...
如何设计app测试用例
功能测试 测试方法:等价类划分法、边界值法、场景法、因果图法。优先级设定:核心业务功能设为高优先级。需求覆盖 正向场景、反向场景、关联接口串场景 与后端开发确认测试用例是否全面覆盖后端逻辑。和产品确认用例是否覆盖本次需求,以及是否…...
《炒股养家心法.pdf》 kimi总结
《炒股养家心法.pdf》这篇文章详细阐述了一位超级游资炒股养家的心得与技巧,展示了其从40万到10亿的股市传奇。以下是文章中炒股技巧和心得的详细总结: 1.核心理念 市场情绪的理解:炒股养家强调,股市的本质是群体博弈,…...
DVWA 靶场
DVWA 靶场的通关 刚建立和使用 输入 http://dvwa:8898/setup.php //进入用户名 密码 dvwa 你自己设计的想要进入数据库 点击creat 用户名 密码 admin passwordAttack type Sniper模式 在Sniper模式下,Payload字典用于逐个替换请求中标记的位置。例如&#x…...
【C语言】(一)数据在计算机中的存储与表示
目录 一、存储单位(比特/字节) 二、数制/进制(二/八/十/十六) 三、码制(原码/反码/补码/移码) 四、二进制表示小数 (一)定点数 (二)浮点数 十进制转化…...
大语言模型微调的公开JSON数据
大语言模型微调的公开JSON数据 以下是一些可用于大语言模型微调的公开JSON数据及地址: EmoLLM数据集 介绍:EmoLLM是一系列能够支持理解用户、帮助用户心理健康辅导链路的心理健康大模型,其开源了数据集、微调方法、训练方法及脚本等。数据集按用处分为general和role-play两种…...
solidity之Foundry安装配置(一)
一门面向合约的高级编程语言,主要用来编写以太坊只能合约。 Solidity受C语言,Python和js影响,但为编译成为以太坊虚拟机字节码在EVM上执行,很多特性和限制都和EVM相关。 Solidity 是静态类型语言,支持继承、库、自定义…...
【个人开源】——从零开始在高通手机上部署sd(二)
代码:https://github.com/chenjun2hao/qualcomm.ai 推理耗时统计 单位/ms 硬件qnncpu_clipqnncpu_unetqnncpu_vaehtp_cliphtp_unethtp_vae骁龙8 gen124716.994133440.39723.215411.097696.327 1. 下载依赖 下载opencv_x64.tar,提取码: rrbp下载opencv_aarch64.t…...
【精调】LLaMA-Factory 快速开始4 自定义个一个sharegpt数据集并训练
数据格式说明 LLaMA Factory:微调LLaMA3模型实现角色扮演 数据集 参考 开源模型应用落地-DeepSeek-R1-Distill-Qwen-7B-LoRA微调-LLaMA-Factory-单机单卡-V100(一) 大神给出的数据集的讲解:注册 如...
【Java】单例模式
单例模式 所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。 单例模式包含懒汉式和饿汉式,运行有且仅有一个实例化对象,只会…...
REACT--组件通信
组件之间如何进行通信? 组件通信 组件的通信主要借助props传递值 分为整体接收、解构接收 整体接收 import PropTypes from prop-types;//子组件 function Welcome(props){return (<div>hello Welcome,{props.count},{props.msg}</div>) }// 对 We…...
第16届蓝桥杯模拟赛3 python组个人题解
第16届蓝桥杯模拟赛3 python组 思路和答案不保证正确 1.填空 如果一个数 p 是个质数,同时又是整数 a 的约数,则 p 称为 a 的一个质因数。 请问, 2024 的最大的质因数是多少? 因为是填空题,所以直接枚举2023~2 &am…...