简介: MaxCompute 新增 Transaction Table2.0(下文简称事务表 2.0)表类型在 2023 年 6 月 27 日开始邀测,反对基于事务表 2.0 实现近实时的增全量一体的数据存储、计算解决方案。
作者: 石玉阳 人力家 高级数据研发工程师
业务简介
人力家是由阿里钉钉和人力窝独特投资成立,帮忙客户进入人力资源数字化,依附产品技术创新驱动策略的互联网公司。公司次要提供包含人事管理、薪酬治理、社保治理、增值服务在内的人力资源 SaaS 服务,减速对人力资源畛域赋能,实现人力资源新工作形式。目前已服务电子商务、批发服务等畛域的多行业客户。
人力家是一家典型的守业公司,目前处于一个竞争强烈的市场环境中,公司具备多产品性质,每个产品的数据具备独立性,同时为了配合外部 CRM 数据需要,更好地把数据整合,对于数仓团队来说是一个不小的挑战,对于数仓团队要求的是稳,准,及时响应。须要数仓团队既要满足外部的数据需要,也须要在计算的老本上实现优化。
业务痛点
在应用阿里云大数据计算服务 MaxCompute 过程中发现随着存量数据减少,增量数据去重老本越来越大,具体分析发现有如下 4 个起因
增量数据量级少
公司尽管是多产品,但每天新增的用户数据和历史变动的数据量绝对于历史全量数据的量级(GB)比拟下处于较小的数据量级(MB)。
历史数据二次计算
对于增量数据去重,每天利用昨日历史全量 + 今日新增数据开窗去重计算,但历史全量数据须要更新的数据局部其实很少,每次都须要把历史数据拉进去进行开窗去重计算,这无疑一笔比拟大的计算成本。
开窗去重计算成本大
应用 row_number 函数开窗去重获得业务主键的最新数据须要把昨日历史数据 + 今日数据合并计算,用户表有亿级别大小,但为了数据去重节俭存储老本和后续的建模运算,这部分老本是偏大的,其实大部分历史数据没有更新,实质上是不须要再次参加运算解决,每天一次的用户表去重单条 SQL 预估费用达到 4.63 元(按量付费)。
全量拉取老本大
如果每天全量拉取业务库数据,数据量是亿级别,但其实更新的数据量级少,对于业务端的 db 压力大,重大影响业务端 db 性能。
Transaction Table2.0 数据去重改良
MaxCompute 新增 Transaction Table2.0(下文简称事务表 2.0)表类型在 2023 年 6 月 27 日开始邀测,MaxCompute 反对基于事务表 2.0 实现近实时的增全量一体的数据存储、计算解决方案。人力家数仓研发团队开始第一工夫理解其个性和性能,人力家数仓团队发现其个性主键模型能够用来进行数据去重,缩小开窗计算成本问题,次要实现形式如下。
- 每日增量用户根底信息开窗去重;
- 因为主键表的主键不能为空,须要过滤出业务主键为空的数据;
- 把每日增量数据开窗去重后的数据间接 insert into 主键表,零碎会主动进行依照业务主键进行去重计算。
具体改良实际措施
整体比照
去重 SQL 执行工夫(单位 s) | 去重 SQL 预估老本(单位元) | |
---|---|---|
一般表 | 151 | 4.63 |
Transaction Table2.0 | 72 | 0.06 |
老本和计算工夫比照
1、建表语句和插入更新语句
更新语句
2、老本和计算
分区表去重运行预估老本:
预估费用,不能作为理论计费规范,仅供参考,理论费用请以账单为准。
主键表去重运行预估老本:
预估费用,不能作为理论计费规范,仅供参考,理论费用请以账单为准。
分区表计算工夫和资源
事务表 2.0 主键表计算工夫和资源
通过上述比照,用户表每天的计算 SQL 老本从 4.63 元降落到 0.06 元,计算工夫缩短一半,reduce_num 明显增加,map 端缩小,reduce 端的数据量显著变多。
合并小文件
事务表 2.0 反对近实时增量写入和 timetravel 查问个性,在数据频繁写入的场景中,必然会引入大量的小文件,须要设计正当高效的合并策略来对小文件进行合并以及数据去重,解决大量小文件读写 IO 低效以及缓解存储系统的压力,但也要防止频繁 Compact 引发重大的写放大和抵触失败。
目前次要反对两种数据合并形式:
- Clustering:只是把 Commit 的 DeltaFile 合并成一个大文件,不扭转数据内容。零碎外部会依据新增的文件大小、文件数量等因素周期性地执行,不须要用户手动操作。次要解决小文件 IO 读写效率和稳定性问题。
- Compaction:会把所有的数据文件依照肯定策略进行 Merge 操作,生成一批新的 BaseFile,雷同 PK 的数据行只存储最新的状态,不蕴含任何历史状态,也不会蕴含任何零碎列信息,因而 BaseFile 自身不反对 timetravel 操作,次要用于晋升查问效率。反对用户依据业务场景被动触发,也反对通过设置表属性由零碎周期性主动触发。
综上面对主键外表对增量数据时,并不会马上对其进行小文件合并,这样会有大量的小文件产生,小文件会占有大量的存储空间且不利于数据查问速度,针对以上状况,咱们能够在 insert into 后减少手动合并下主键表的小文件或者也可通过配置表属性依照工夫频率、Commit 次数等维度主动触发 Compaction 机制,或期待零碎进行的 Clustering 合并。如果是每日的新增仅一次的数据更新,这里更举荐应用零碎的 Clustering 机制。
留神点:
desc extend table_name 显示进去的 file_num 和 size 是蕴含回收站数据的,目前没方法精确显示,能够清空回收站数据或者 Compaction 察看日志结尾的 filenum 数量。
数据时空旅行查问和历史数据修复
对于事务表 2.0 类型的表,MaxCompute 反对查问回溯到源表某个历史工夫或者版本进行历史 Snapshot 查问(TimeTravel 查问),也反对指定源表某个历史工夫区间或者版本区间进行历史增量查问(Incremental 查问), 须要设置 acid.data.retain.hours 才能够应用 TimeTravel 查问和 Incremental 查问。
数据时空旅行查问
1、基于 TimeTravel 查问截止到指定工夫(例如 datetime 格局的字符串常量)的所有历史数据(须要设置)
select * from mf_tt2 timestamp as of '2023-06-26 09:33:00' where dd='01' and hh='01';
查问历史数据和版本号
show history for table mf_tt2 partition(dd='01',hh='01');
查问截止到指定 version 常量的所有历史数据
select * from mf_tt2 version as of 2 where dd='01' and hh='01';
2、基于 Incremental 查问指定工夫(例如 datetime 格局的字符串常量)区间的历史增量数据,常量值须要依据具体操作的工夫来配置
select * from mf_tt2 timestamp between '2023-06-26 09:31:40' and '2023-06-26 09:32:00' where dd= '01' and hh='01';
查问指定 version 区间的历史增量数据
select * from mf_tt2 version between 2 and 3 where dd ='01' and hh = '01';
数据修复
基于 TimeTravel 查问截止到指定工夫的全量数据间接 insert into 一张长期表,清空以后事务表 2.0 主键表数据,把长期表数据 insert into 以后事务表 2.0 主键表。
注意事项及将来布局
动静硬删数据
对于历史数据没方法硬删除(这部分须要依赖 flink-cdc),目前能够通过软删实现,或者通过一段时间的历史数据积攒,拿出所有历史数据进行过滤从新整体插入主键表;这里提一点就是 flink-cdc+flink-sql 反对 delete 实时硬删数据,然而单表的 flink-cdc 工作比拟重,多个表须要不同的 server-id,对于业务零碎源头断的 db 压力大,不是很举荐,期待后续的 cdas 整库同步。
存储空间减少
事务表 2.0 主键模型数据存储空间相比于分区表开窗后的数据占有的存储空间大一点,次要是开窗后的数据分布更平均,数据压缩比更大,然而绝对于 sql 每次的每天一次的计算成本,存储空间所占有的每日费用处于较低的费用级(可疏忽)。
flink-cdc
配合 flink-cdc 间接能够间接实现准实时数据同步,进步数据新鲜度。
整库同步
期待阿里云实时计算 Flink 的 cdas 语法指标端整合 MaxCompute 端做到整库同步和 ddl 变更。
物化视图
利用物化视图 +flink-cdc 组合形式能够做到