大数据组件paimon工作小记

flinkcdc从业务库抽取数据到paimon。

一:主键模型:Primary Key Table

1、主键由一组列组成,这些列包含每条记录的唯一值。paimon通过对每个bucket中的主键进行排序来强制执行数据排序,允许用户通过对主键应用过滤条件来实现高性能。主键表是paimon作为流式数据湖的核心,他可以接收上游来自数据库CDC或者flink streaming产生的Changelog,里面包含insert,update,delte的数据,建表关键字是 PRIMARY KEY (字段) NOT ENFORCED

2、主键表的compaction默认在flink sink中自动完成,它会在LSM中生产一个写放大和读放大的基本平衡。但默认的compaction可能会存在阻塞写,针对该弯头可以开启全一步compation,如下配置: 'num-sorted-run.stop-trigger' = '2147483647',

'sort-spill-threshold' = '10',

-- 'changelog-producer.lookup-wait' = 'false' -- 此参数针对'changelog-producer' = 'lookup'

3、paimon支持多作业同时写入,但是并不支持多作业同时 Compaction,所以你可以给写入作业配置 write-only 为 true,避免写入作业进行后台 compaction,然后启动单独的 Dedicated Compaction Job。

-- 注意点:1.comment不能带双引号,只能带单引号
--       2.BIGINT,INT,tinyint 不能带括号,如INT(20)
--       3.不能用datetime,可以改用timestamp(3)
CREATE TABLE paimon_dev.dwd_lbu_fms.dwd_lbu_mbi_bil_income (
ic_id BIGINT COMMENT 'ID',
partition_id INT comment '分区字段',
bs_id INT COMMENT '业务数据ID',
bsn_number varchar(150) COMMENT '业务单号',
customer_id int COMMENT '结算客户ID',
fk_code varchar(60) COMMENT '费用类型',
amount decimal(18, 2)  COMMENT '原币金额',
currency_code varchar(9)  COMMENT '原币币种',
pirce_type varchar(9)  COMMENT '本位币(人民币、美元)',
rate decimal(18, 4)  COMMENT '换算成本位币汇率',
PRIMARY KEY (ic_id,partition_id) NOT ENFORCED
) 
COMMENT 'SS表'
PARTITIONED BY (partition_id)
WITH (
'bucket' = '5', -- default 1
'bucket-key' = 'ic_id', 
'sequence.field' = '__doris_sequence_ts_dt__',
-- 当同时insert两条以上相同主键的数据时,可以按__doris_sequence_ts_dt__时间最大的为最新的合并数据
'full-compaction.delta-commits' = 'full-compaction', -- 完全压缩
'changelog-producer' = 'full-compaction', -- 在compaction后产生完整的changelog 
'changelog-producer.compaction-interval' = '2 min', -- compaction间隔时间
'merge-engine' = 'partial-update', -- 默认deduplicate 
'partial-update.ignore-delete' = 'true', -- 忽略DELETE数据,避免运行报错
'partition.expiration-time' = '7d',--分区的过期间隔。如果分区的生存期超过这个值,它将过期。
'partition.expiration-check-interval' = '1d',--分区过期的检查间隔,默认1h
'partition.timestamp-formatter' = 'yyyyMMdd', -- 分区格式,默认 'yyyy-MM-dd HH:mm:ss' and 'yyyy-MM-dd',多字段分区也可以设置为 '$year-$month-$day $hour:00:00'
'partition.timestamp-pattern' = '$create_on',
-- 主键表的 Compaction 默认在 Flink Sink 中自动完成,它会在LSM中生成一个 写放大与读放大的基本平衡。但默认的后台运行的 Compaction可能会阻塞写,因此可以
-- 开启全异步Compaction,打开后永远不会阻塞 Write 的正常写入
'num-sorted-run.stop-trigger' = '2147483647',
'sort-spill-threshold' = '10',
--'changelog-producer.lookup-wait' = 'false' -- 此参数针对'changelog-producer' = 'lookup'

'write-only' = 'true'-- Paimon 支持多作业同时写入,但是并不支持多作业同时 Compaction,所以你可以给写入作业配置 write-only 为 true,避免写入作业进行后台compaction,然后启动单独的 Dedicated Compaction Job。可以参考【专用压缩】
);

BUCKET

bucket是最小的读写存储单元,每个bucket目录都包含一个LSM树。

存储桶数量过多会导致小文件过多,存储桶数量过少会导致写入性能较差。

(1):固定桶

不支持跨分区更新数据;

固定桶是指bucket>0.一般默认1;

Bucket 个数会影响并发度,影响性能,所以你需要根据表的数据量来合理定义出一个 bucket 个数,一般情况下,建议每个bucket中的数据大小约为 200MB-1GB。

PS:随着数据增加,可能会又调整的场景,通过如下方式:

a.直接重建表,一般推荐

b.也可以保留已经写入的数据,详见文档 Rescale Bucket,https://paimon.apache.org/docs/0.6/maintenance/rescale-bucket/

'bucket' = '5'

'bucket-key' = 'bsn_number' ,一般要加上该参数,不加则默认是按全部的表字段hash去分捅

(2):动态桶

动态桶bucket=-1,

数据如果是已经存在主键,将会落入旧的存储桶中,新的主键将落入新的存储桶。存储桶和主键的分布取决于数据到达的顺序。Paimon 会维护一个索引,以确定哪个主键对应于哪个桶。Paimon 会自动扩展bucket的数量。有两个参数你需要关心:

  1. 'dynamic-bucket.target-row-num':控制一个桶的目标数据量。
  2. 'dynamic-bucket.assigner-parallelism':控制初始化bucket的数量。
    普通动态桶(不跨分区)
    定义:更新不跨分区(没有分区,或者主键包含所有分区字段)
    性能:
    a.一般来说,没有性能损失,但会有一些额外的内存消耗,一个分区中的1亿个条目会多占用1 GB的内存,不再活动的分区不会占用内存。
    b.对于更新率较低的表,建议使用此模式以显著提高易用性。

Merge Engines

当Paimon接收器接收到两个或多个具有相同主键的记录时,它会将它们合并为一个记录,以保持主键的唯一性。通过指定合并引擎表属性,用户可以选择如何将记录合并在一起。

一般默认Deduplicate,即'merge-engine' = 'deduplicate '

(1)Deduplicate:宽表模型

'merge-engine' = 'deduplicate '

Paimon将只保留最新的记录,并丢弃具有相同主键的其他记录。

具体来说,如果最新的记录是DELETE记录,则具有相同主键的所有记录都将被删除。

(2)Partial Update:宽表模型

'merge-engine' = 'partial-update'

可以部分更新列,但是null没法覆盖原来有值的列

PS:

a.对于流式查询,部分更新合并引擎必须与查找或完全压缩变更日志生成器一起使用。(也支持'input'变更日志生成器,但仅返回输入记录。)即需要'changelog-producer' = 'full-compaction','changelog-producer.compaction-interval' = '2 min'把这个两个参数加上

b.默认情况下,部分更新不能接受删除记录,您可以选择以下解决方案之一:

配置"部分更新。忽略删除"以忽略删除记录。'partial-update.ignore-delete' = 'true'

配置"序列组"以收回部分列。'sequence.field' = 'binlog_time'

CREATE TABLE if not EXISTS paimon.dw.order_detail  
(  
`order_id` string   
,`product_type` string   
,`binlog_time` bigint  
,PRIMARY KEY (order_id) NOT ENFORCED  
)   
WITH (  
  'bucket' = '20', -- 指定20个bucket  
  'bucket-key' = 'order_id',  
  'sequence.field' = 'binlog_time', -- 记录排序字段  
  'changelog-producer' = 'full-compaction',  -- 选择 full-compaction ,在compaction后产生完整的changelog  
  'changelog-producer.compaction-interval' = '2 min', -- compaction 间隔时间  
  'merge-engine' = 'partial-update',  
  'partial-update.ignore-delete' = 'true' -- 忽略DELETE数据,避免运行报错  
);

部分更新聚合:

'fields.amount.sequence-group' = '聚合字段名称',

'fields.聚合字段名称.aggregate-function' = '聚合类型,例如sum',

(3)Aggregation:聚合模型

除主键以外的列都可以指定一个聚合函数,相同主键的数据就可以按照列字段指定的聚合函数进行相应的预聚合,如果不指定则默认为 last-non-null-value ,空值不会覆盖。Agg 表引擎也需要结合 Lookup 或者 full-compaction 的 Changelog Producer 一起使用,需要注意的是除了 SUM 函数,其他的 Agg 函数都不支持 Retraction,为了避免接收到 DELETE 和 UPDATEBEFORE 消息报错,需要通过给指定字段配置 'fields.${field_name}.ignore-retract'='true' 忽略。

CREATE TABLE MyTable (
product_id BIGINT
,price DOUBLE
,sales BIGINT
,PRIMARY KEY (product_id) NOT ENFORCED)
 WITH ('merge-engine' = 'aggregation',
 'changelog-producer' = 'full-compaction',  -- 选择 full-compaction ,在compaction后产生完整的changelog  
 'changelog-producer.compaction-interval' = '2 min', -- compaction 间隔时间  
 'fields.price.aggregate-function' = 'max',
 'fields.sales.aggregate-function' = 'sum');

Partitions:分区

注意:分区字段必须是主键字段的子集

相关推荐
Ai 编码助手1 小时前
MySQL中distinct与group by之间的性能进行比较
数据库·mysql
Json_181790144801 小时前
An In-depth Look into the 1688 Product Details Data API Interface
大数据·json
陈燚_重生之又为程序员1 小时前
基于梧桐数据库的实时数据分析解决方案
数据库·数据挖掘·数据分析
caridle1 小时前
教程:使用 InterBase Express 访问数据库(五):TIBTransaction
java·数据库·express
白云如幻1 小时前
MySQL排序查询
数据库·mysql
萧鼎1 小时前
Python并发编程库:Asyncio的异步编程实战
开发语言·数据库·python·异步
^velpro^1 小时前
数据库连接池的创建
java·开发语言·数据库
荒川之神1 小时前
ORACLE _11G_R2_ASM 常用命令
数据库·oracle
IT培训中心-竺老师2 小时前
Oracle 23AI创建示例库
数据库·oracle
小白学大数据2 小时前
JavaScript重定向对网络爬虫的影响及处理
开发语言·javascript·数据库·爬虫