聊聊流式数据湖Paimon(四)
Partial Update
数据打宽
通过不同的流写不同的字段,打宽了数据的维度,填充了数据内容;如下所示:
--FlinkSQL参数设置
set
`table.dynamic-table-options.enabled` = `true`;
SET
`env.state.backend` = `rocksdb`;
SET
`execution.checkpointing.interval` = `60000`;
SET
`execution.checkpointing.tolerable-failed-checkpoints` = `3`;
SET
`execution.checkpointing.min-pause` = `60000`;
--创建Paimon catalog
CREATE CATALOG paimon WITH (
'type' = 'paimon',
'metastore' = 'hive',
'uri' = 'thrift://localhost:9083',
'warehouse' = 'hdfs://paimon',
'table.type' = 'EXTERNAL'
);
--创建Partial update结果表
CREATE TABLE if not EXISTS paimon.dw.order_detail (
`order_id` string,
`product_type` string,
`plat_name` string,
`ref_id` bigint,
`start_city_name` string,
`end_city_name` string,
`create_time` timestamp(3),
`update_time` timestamp(3),
`dispatch_time` timestamp(3),
`decision_time` timestamp(3),
`finish_time` timestamp(3),
`order_status` int,
`binlog_time` bigint,
PRIMARY KEY (order_id) NOT ENFORCED
) WITH (
'bucket' = '20',
-- 指定20个bucket
'bucket-key' = 'order_id',
-- 记录排序字段
'sequence.field' = 'binlog_time',
-- 选择 full-compaction ,在compaction后产生完整的changelog
'changelog-producer' = 'full-compaction',
-- compaction 间隔时间
'changelog-producer.compaction-interval' = '2 min',
'merge-engine' = 'partial-update',
-- 忽略DELETE数据,避免运行报错
'partial-update.ignore-delete' = 'true'
);
INSERT INTO
paimon.dw.order_detail
-- order_info表提供主要字段
SELECT
order_id,
product_type,
plat_name,
ref_id,
cast(null as string) as start_city_name,
cast(null as string) as end_city_name,
create_time,
update_time,
dispatch_time,
decision_time,
finish_time,
order_status,
binlog_time
FROM
paimon.ods.order_info
/*+ OPTIONS ('scan.mode'='latest') */
union
all
-- order_address表提供城市字段
SELECT
order_id,
cast(null as string) as product_type,
cast(null as string) as plat_name,
cast(null as bigint) as ref_id,
start_city_name,
end_city_name,
cast(null as timestamp(3)) as create_time,
cast(null as timestamp(3)) as update_time,
cast(null as timestamp(3)) as dispatch_time,
cast(null as timestamp(3)) as decision_time,
cast(null as timestamp(3)) as finish_time,
cast(null as int) as order_status,
binlog_time
FROM
paimon.ods.order_address
/*+ OPTIONS ('scan.mode'='latest') */
;
完整的Changlog
Paimon中的表被多流填充数据且打宽维度后,支持流读、批读的方式提供完整的Changelog给下游。
Sequence-Group
配置:'fields.G.sequence-group'='A,B'
由字段G
控制是否更新字段A, B
;总得来说,G
的值如果为null或比更新值大将不更新A,B
;如下单测
public void testSequenceGroup() {
sql(
"CREATE TABLE SG ("
+ "k INT, a INT, b INT, g_1 INT, c INT, d INT, g_2 INT, PRIMARY KEY (k) NOT ENFORCED)"
+ " WITH ("
+ "'merge-engine'='partial-update', "
+ "'fields.g_1.sequence-group'='a,b', "
+ "'fields.g_2.sequence-group'='c,d');");
sql("INSERT INTO SG VALUES (1, 1, 1, 1, 1, 1, 1)");
// g_2 should not be updated
sql("INSERT INTO SG VALUES (1, 2, 2, 2, 2, 2, CAST(NULL AS INT))");
// select *
assertThat(sql("SELECT * FROM SG")).containsExactlyInAnyOrder(Row.of(1, 2, 2, 2, 1, 1, 1));
// projection
assertThat(sql("SELECT c, d FROM SG")).containsExactlyInAnyOrder(Row.of(1, 1));
// g_1 should not be updated
sql("INSERT INTO SG VALUES (1, 3, 3, 1, 3, 3, 3)");
assertThat(sql("SELECT * FROM SG")).containsExactlyInAnyOrder(Row.of(1, 2, 2, 2, 3, 3, 3));
// d should be updated by null
sql("INSERT INTO SG VALUES (1, 3, 3, 3, 2, 2, CAST(NULL AS INT))");
sql("INSERT INTO SG VALUES (1, 4, 4, 4, 2, 2, CAST(NULL AS INT))");
sql("INSERT INTO SG VALUES (1, 5, 5, 3, 5, CAST(NULL AS INT), 4)");
assertThat(sql("SELECT a, b FROM SG")).containsExactlyInAnyOrder(Row.of(4, 4));
assertThat(sql("SELECT c, d FROM SG")).containsExactlyInAnyOrder(Row.of(5, null));
}
其作用是:
- 在多个数据流更新期间的无序问题。每个数据流都定义自己的序列组。
- 真正的部分更新,而不仅仅是非空值的更新。
- 接受删除记录来撤销部分列。
Changelog-Producer
Paimon通过Changelog-Producer支持生成changelog,并支持下游以流读、批读的形式读取changelog。
Changelog的生成有多种方式,input、lookup、full-compaction;其生成代价是由低到高。
None
不查找旧值,不额外写Changelog;但会下游任务中通过ChangelogNormalize算子补足Changelog。
Input
不查找旧值,额外写Changelog;适用与CDC的数据源。
Lookup
查找旧值,额外写Changelog;如果不是CDC数据源,需要通过LookupCompaction查找旧值,即在 compaction 的过程中, 会去向高层查找本次新增 key 的旧值, 如果没有查找到, 那么本次的就是新增 key, 如果有查找到, 那么就生成完整的 UB 和 UA 消息。
Full-Compaction
查找旧值,额外写Changelog;在 full compact 的过程中, 其实数据都会被写到最高层, 所以所有 value 的变化都是可以推演出来的.
数据一致性
数据版本
通过Flink的checkpoint机制,生成Snapshot并标记版本,即,一个Snapshot对应数据的一个版本。
比如 Job-A 基于 Table-A 的 Snapshot-20 产出了 Table-B 的 Snapshot-11。Job-B 基于 Table-A 的Snapshot-20产出了 Table-C 的 Snapshot-15。那么 Job-C 的查询就应该基于 Table-B 的 Snapshot-11 和 Table-C 的 Snapshot-15 进行计算,明确了数据版本,从而实现计算的一致性。
生成的snapshot-xx,就是数据的版本号。
数据对齐
将 Checkpoint 插入到两个 Snapshot 的数据之间。如果当前的 Snapshot 还没有完全被消费,这个 Checkpoint 的触发会被推迟,从而实现按照 Snapshot 对数据进行划分和对齐。
实现分为两个部分。
- 在提交阶段,需要去血缘关系表中查询上下游表的一致性版本,并且基于查询结果给对应的上游表设置起始的消费位置。
- 在运行阶段,按照消费的 Snapshot 来协调 Checkpoint,在 Flink 的 Checkpoint Coordinator 向 Source 发出 Checkpoint 的请求时,会强制要求将 Checkpoint 插入到两个 Snapshot 的数据之间。如果当前的 Snapshot 还没有完全被消费,这个 Checkpoint 的触发会被推迟,从而实现按照 Snapshot 对数据进行划分和处理。
数据血缘
概念
数据从产生到消费的整个流转过程中所经历的各种转换、处理和流动的轨迹。数据血缘提供了数据的来源、去向以及中间处理过程的透明度,帮助用户理解数据如何在系统中被处理和移动,以及数据是如何从原始状态转化为最终的可消费形态。
实现
在checkpoint的提交时将数据的血缘关系写入到System Table,记录血缘关系。
聊聊流式数据湖Paimon(四)的更多相关文章
- Apache Hudi 0.9.0版本重磅发布!更强大的流式数据湖平台
1. 重点特性 1.1 Spark SQL支持 0.9.0 添加了对使用 Spark SQL 的 DDL/DML 的支持,朝着使所有角色(非工程师.分析师等)更容易访问和操作 Hudi 迈出了一大步. ...
- 字节跳动流式数据集成基于Flink Checkpoint两阶段提交的实践和优化
背景 字节跳动开发套件数据集成团队(DTS ,Data Transmission Service)在字节跳动内基于 Flink 实现了流批一体的数据集成服务.其中一个典型场景是 Kafka/ByteM ...
- FunDA(2)- Streaming Data Operation:流式数据操作
在上一集的讨论里我们介绍并实现了强类型返回结果行.使用强类型主要的目的是当我们把后端数据库SQL批次操作搬到内存里转变成数据流式按行操作时能更方便.准确.高效地选定数据字段.在上集讨论示范里我们用集合 ...
- 流式数据分析模型kafka+storm
http://www.cnblogs.com/panfeng412/archive/2012/07/29/storm-stream-model-analysis-and-discussion.html ...
- 基于Apache Hudi构建数据湖的典型应用场景介绍
1. 传统数据湖存在的问题与挑战 传统数据湖解决方案中,常用Hive来构建T+1级别的数据仓库,通过HDFS存储实现海量数据的存储与水平扩容,通过Hive实现元数据的管理以及数据操作的SQL化.虽然能 ...
- Robinhood基于Apache Hudi的下一代数据湖实践
1. 摘要 Robinhood 的使命是使所有人的金融民主化. Robinhood 内部不同级别的持续数据分析和数据驱动决策是实现这一使命的基础. 我们有各种数据源--OLTP 数据库.事件流和各种第 ...
- 翻译-In-Stream Big Data Processing 流式大数据处理
相当长一段时间以来,大数据社区已经普遍认识到了批量数据处理的不足.很多应用都对实时查询和流式处理产生了迫切需求.最近几年,在这个理念的推动下,催生出了一系列解决方案,Twitter Storm,Yah ...
- 流式处理的新贵 Kafka Stream - Kafka设计解析(七)
原创文章,转载请务必将下面这段话置于文章开头处. 本文转发自技术世界,原文链接 http://www.jasongj.com/kafka/kafka_stream/ Kafka Stream背景 Ka ...
- 流式处理新秀Flink原理与实践
随着大数据技术在各行各业的广泛应用,要求能对海量数据进行实时处理的需求越来越多,同时数据处理的业务逻辑也越来越复杂,传统的批处理方式和早期的流式处理框架也越来越难以在延迟性.吞吐量.容错能力以及使用便 ...
- 分布式流式计算平台——S4
本文是作者在充分阅读和理解Yahoo!最新发布的技术论文<S4:Distributed Stream Computing Platform>的基础上,所做出的知识分享. S4是Yahoo! ...
随机推荐
- react移动端上拉加载更多组件
在开发移动端react项目中,遇到了上拉加载更多数据的分页功能,自己封装了一个组件,供大家参考,写的不好还请多多指教! import React, {Component} from 'react'; ...
- 「codeforces - 1481F」AB Tree
link. 理一下逻辑,主要讲一下我做题时的疑惑和其它题解没提到的细节. 首先容易看到,一个必然不劣的贪心策略是把尽量靠近根的层铺成同样的字符.也许会有疑惑,字符串是否本质不同的判定每个位置地位相等. ...
- WebKit Insie: Active 样式表
WebKit Inside: CSS 样式表的匹配时机介绍了当 HTML 页面有不同 CSS 样式表引入时,CSS 样式表开始匹配的时机.后续文章继续介绍 CSS 样式表的匹配过程,但是在匹配之前,首 ...
- Arduino入门教程
Arduino入门教程 Arduino是一款简单易学的开源电子原型平台,包含硬件(各种型号的Arduino板)和软件(Arduino IDE).它通过各种各样的传感器来感知环境,再通过控制 ...
- go defer简介
思考 开始之前,先考虑下下面的代码的执行结果: package main import "fmt" func test() int { i := 0 defer func() { ...
- windows系统和IE的兼容性问题
IE浏览器用户正在逐步减少,但是以前的基数较大,为了解决win和ie的版本混乱问题,特记录一下: 一.从操作系统角度出发: XP最高支持到IE8,XP支持ie6,ie7,ie8 WIN7自带 ...
- tunm, 一种对标JSON的二进制数据协议
Tunm simple binary proto 一种对标JSON的二进制数据协议 支持的数据类型 基本支持的类型 "u8", "i8", "u16& ...
- 虹科案例 | 石油天然气行业CFD高性能计算解决方案
公司简介 DNV GL 是全球领先的能源.石油和海事行业风险管理及资产绩效提升的软件供应商,主要为客户提供全面的风险管理和各类评估认证服务,认证涉及信息通信技术.汽车及航空天.食品与饮料.医疗等方面. ...
- 使用 mt19937 生成区间随机数
#include <cstdio> #include <random> #include <ctime> using namespace std; int main ...
- 数据类型python
type()语句的用法 运行结果