Apache Paimon的Merge into

Paimon通过提供action jar 包的方式来支持诸多复杂功能,其中很重要的一个功能就是merge into,通过该方式可以实现行级别的更新操作

Action jar

pamon-flink-action 是 paimon 的 flink action jar 包,内部封装了很多高级功能,包括merge into、compact、delete、drop_partition 等

下载地址:Index of /groups/snapshots/org/apache/paimon/paimon-flink-action
从apache的快照仓库结合自身的flink和paimon的版本选择即可。在启动了flink集群后,就可以通过flink run 的方式来执行任务

<FLINK_HOME>/bin/flink run \
 /path/to/paimon-flink-action-0.8.2.jar \
 <action>
 <args>

Merge into 使用

Paimon利用mege into可以实现类似于upsert的行级别更新,此外paimon的action工具包中还定义了诸多复杂的功能,使我们对要合并的两张表做一下更复杂的计算操作

Merge into使用前提
  1. Paimon表必须设有主键
  2. 目前merge into 只支持flink batch批处理模式
  3. merge into 操作是不会产生update before记录的,因此对于change-log-producer不建议设置成input
语法参数

merge_into 操作使用“upsert”语义而不是“update”,这意味着如果行存在,则执行更新,否则执行插入。例如,对于非主键表,您可以更新每一列,但对于主键表,如果您想更新主键,则必须插入一个新行,该行的主键与表中的行不同。在这种情况下,“upsert”很有用。merge into的语法可以理解为下面语句。

MERGE INTO target-table
  USING source_table | source-expr AS source-alias
  ON merge-condition  
  WHEN MATCHED [AND matched-condition]
    THEN UPDATE SET xxx
  WHEN MATCHED [AND matched-condition]
    THEN DELETE
  WHEN NOT MATCHED [AND not_matched_condition]
    THEN INSERT VALUES (xxx)
  WHEN NOT MATCHED BY SOURCE [AND not-matched-by-source-condition]
    THEN UPDATE SET xxx
  WHEN NOT MATCHED BY SOURCE [AND not-matched-by-source-condition]
    THEN DELETE

可以分为五部分来理解:如何连接、目标表连接上的要干啥、目标表连接不上的要干啥、来源表连接上的要干啥、来源表连接不上的要干啥。flink提交merge into的官网命令如下

<FLINK_HOME>/bin/flink run \
    /path/to/paimon-flink-action-0.8.2.jar \
    merge_into \
    --warehouse <warehouse-path> \
    --database <database-name> \
    --table <target-table> \
    [--target_as <target-table-alias>] \
    --source_table <source_table-name> \
    [--source_sql <sql> ...]\
    --on <merge-condition> \
    --merge_actions <matched-upsert,matched-delete,not-matched-insert,not-matched-by-source-upsert,not-matched-by-source-delete> \
    --matched_upsert_condition <matched-condition> \
    --matched_upsert_set <upsert-changes> \
    --matched_delete_condition <matched-condition> \
    --not_matched_insert_condition <not-matched-condition> \
    --not_matched_insert_values <insert-values> \
    --not_matched_by_source_upsert_condition <not-matched-by-source-condition> \
    --not_matched_by_source_upsert_set <not-matched-upsert-changes> \
    --not_matched_by_source_delete_condition <not-matched-by-source-condition> \
    [--catalog_conf <paimon-catalog-conf> [--catalog_conf <paimon-catalog-conf> ...]]
  • warehouse、database、table:分别对应目标表的catalog地址、数据库和表名
  • source sql:如果没有source表,可以使用sql的方式在提交命令里使用SQL构建source表,如:
bin/flink run \
/opt/model/paimon-flink-action-0.8-20240709.052248-82.jar \
merge-into \
--warehouse hdfs://node001:8020/paimon/fs \
--database default \
--table ws_t \
--source-sql "CREATE CATALOG fs2 WITH ('type'='paimon','warehouse' ='hdfs://node001:8020/paimon/fs2')" \
--source-sql "CREATE DATABASE IF NOT EXISTS fs2.test" \
--source-sql "CREATE TEMPORARY VIEW fs2.test.ws2 AS SELECT id+10 as id,ts,vc FROM ws1" \
--source-table fs2.test.ws2 \
--on " ws_t.id = ws2.id " \
--merge-actions not-matched-insert \
--not-matched-insert-values "*"
  • on:两张表进行合并的连接条件
  • merge_actions:合并时要执行的操作列表,可以传多个操作,操作之间使用逗号隔开,目前支持五种
    1. matched-upsert:目标表匹配上的执行upsert。
    2. matched-delete:目标表匹配上的执行删除。
    3. not-matched-insert:source表没匹配上的插入到目标表。
    4. not-matched-by-source-upsert:目标表没匹配上的执行upsert。
    5. not-matched-by-source-delete:目标表没匹配上的执行删除 。
  • matched_upsert_condition <matched-condition> :目标表匹配上的数据执行upsert要满足的condition。
  • matched_upsert_set <upsert-changes> :目标表匹配上的数据执行upsert的set语句。
  • matched_delete_condition <matched-condition>:目标表匹配上的数据执行delete要满足的condition。
  • not_matched_insert_condition <not-matched-condition> :目标表匹配上的数据执行insert要满足的condition。
  • not_matched_insert_values <insert-values> :目标表匹配上的数据执行insert的具体值,直接插入可以写 "*"。
  • not_matched_by_source_upsert_condition <not-matched-by-source-condition> :目标表没有匹配上的数据执行upsert要满足的condition。
  • not_matched_by_source_upsert_set <not-matched-upsert-changes> :目标表没有匹配上的数据执行upsert的set语句。
  • not_matched_by_source_delete_condition <not-matched-by-source-condition> :目标表没有匹配上的数据执行delete要满足的condition。

这里把condition这个东西理解成where就可以了:where(condititon) 匹配或者匹配上的数据 满足什么条件则set(具体操作)

实际案例

创建测试ws1和ws_t

create table ws1 (
  id int,
  ts bigint,
  vc int,
  primary key (id) not ENFORCED
);

insert into ws1 values (1,1,1),(2,2,2),(3,3,3);


create table ws_t (
  id int,
  ts bigint,
  vc int,
  primary key (id) not ENFORCED
);

insert into ws_t values (2,2,2),(3,3,3),(4,4,4),(5,5,5);
  1. 需求一:ws_t 与 ws1 匹配 将 ws_t 中 ts > 2 的 vc 改为 10 ,ts<=2 的删除
bin/flink run \
/opt/model/paimon-flink-action-0.8-20240709.052248-82.jar \
merge-into \
--warehouse hdfs://node001:8020/paimon/fs \
--database default \
--table ws_t \
--source-table default.ws1 \
--on "ws_t.id = ws1.id" \
--merge-actions matched-upsert,matched-delete \
--matched-upsert-condition "ws_t.ts > 2" \
--matched-upsert-set "vc = 10" \
--matched-delete-condition "ws_t.ts <= 2"
  1. 需求二:ws_t 和 wsl 匹配 id 匹配上的将 ws_t 中 vc + 10 ws1 没匹配上的插入ws_t 中
bin/flink run \
/opt/model/paimon-flink-action-0.8-20240709.052248-82.jar \
merge-into \
--warehouse hdfs://node001:8020/paimon/fs \
--database default \
--table ws_t \
--source-table default.ws1 \
--on "ws_t.id = ws1.id" \
--merge-actions matched-upsert,not-matched-insert \
--matched-upsert-set " vc = ws_t.vc + 10 " \
--not-matched-insert-values "*"
  1. sql-souce案例:构造ws2表,将ws1的id+10后和ws_t进行匹配,并将source匹配不上的写入ws_t中
bin/flink run \
/opt/model/paimon-flink-action-0.8-20240709.052248-82.jar \
merge-into \
--warehouse hdfs://node001:8020/paimon/fs \
--database default \
--table ws_t \
--source-sql "CREATE CATALOG fs2 WITH ('type'='paimon','warehouse' ='hdfs://node001:8020/paimon/fs2')" \
--source-sql "CREATE DATABASE IF NOT EXISTS fs2.test" \
--source-sql "CREATE TEMPORARY VIEW fs2.test.ws2 AS SELECT id+10 as id,ts,vc FROM ws1" \
--source-table fs2.test.ws2 \
--on " ws_t.id = ws2.id " \
--merge-actions not-matched-insert \
--not-matched-insert-values "*"

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值