为什么不能使用 datax 直接读写 hive acid 事务表?
1. 前言
从技术发展趋势的角度来看,ACID 事务表提供了多种新特性新功能,是 HIVE 社区推荐的 HIVE 表格式,且在 CDH/CDP/TDH 等大数据平台的主流版本中均已经提供了支持。在次背景下,目前我司大数据相关产品和项目,已经在部分场景下开始了探索使用 HIVE ACID 事务表。在此跟大家分享一个 HIVE ACID 事务表的相关问题,希望对大家有所帮助。
2. 从一个 HIVE SQL 报错聊起
某线上 HIVE SQL 应用,关联查询多个事务表时报错,报错信息如下:
3. “Must use HiveInputFormat to read ACID tables” 报错的底层原因
经排查发现,上述事务表底层的 ORC 文件是使用 datax 直接同步过来的,而事务表对表底层在存储系统中的文件目录层次结构,文件名,以及文件格式,都有一套自己的规范,使用 datax 直接同步文件一般肯定会违反该规范,在后续查询使用时就会出现各种奇怪的问题,所以不能使用 datax 直接同步数据到事务表对应的 hdfs 目录下。
4. HIVE ACID 事务表的技术细节
为了在 HDFS 文件系统特性的基础上提供事务表的 ACID 语义(HDFS 不支持对文件的原地更新,在 APPEND 追加写入文件时也不支持对该文件并发读取时的数据一致性),HIVE 对 ACID 事务表(或表分区)底层的文件,做了类似 deltalake/hudi/iceberg 一样的精细化管理,对底层文件的目录结构,文件名,和文件格式,都有一套自己的规范。
4.1 首先是文件目录层次结构规范
每个表或表分区对应一个 HDFS 目录;
表或表分区目录底层又包含两类子目录,一类是 base 子目录,一类是 delta 子目录;
表或表分区的大部分数据,都以文件形式存储在 base 子目录下;
每次对表或表分区的增删改操作,都对应一个事务,都会创建一个对应的 delta 子目录,并将这些增量操作产生的数据,以文件形式存储在该 delta 子目录下;
读取表或表分区数据时,会合并 base 子目录和 delta 子目录下的所有文件,以呈现完整的数据;
4.2 其次是文件名规范
表底层 BASE 子目录名称类似 base_0000003_v0011148,其中中间部分对应创建该子目录的事务操作的 TransactionId;
表底层 DELTA 子目录名称类似(对应 insert/update 操作): delta_0000001_0000003_ v0011147,其中中间两部分对应创建该子目录的事务操作的最小和最大 TransactionId;(insert/update 操作生成的 delta 文件的最小和最大 TransactionId 是一致的,compaction 操作生成的 delta 文件的最小和最大 TransactionId 分别对应 compaction 的一系列 delta 文件的最小和最大 TransactionId);
表底层 DELTA 子目录名称类似(对应 delete 操作):delete_delta_0000001_0000003_ v0011147,其中中间两部分对应创建该子目录的事务操作的最小和最大 TransactionId;(delete 操作生成的 delete_delta 文件的最小和最大 TransactionId 是一致的,compaction 操作生成的 delta 文件的最小和最大 TransactionId 分别对应 compaction 的一系列 delete_delta 文件的最小和最大 TransactionId);
子目录底层的文件名,类似 bucket_00000 或 bucket_00000_0;(不管表是否分桶,文件名都是该格式;hive2.x 和 hive3.x 新旧版本文件名格式略有不同)
4.3 最后是文件格式规范
ACID 事务表底层的文件,都是以 orc 格式存储的;
ORC 文件包含的字段,除了 ACID 事务表中正常的业务字段,还包含 5 个元数据字段:operation:int,originalTransaction:bigint,bucket:int,rowId:bigint,currentTransaction:bigint
5 总结
正是因为 HIVE 对 ACID 事务表(或表分区)底层文件的目录结构,文件名,和文件格式的上述规范,所以我们不能直接读写操作 ACID 事务表底层的文件,正如我们不能绕过 MYSQL/ORACLE 服务,直接读写 MYSQL/ORACLE 表在底层本地文件系统中的文件一样。
所以周边生态工具,如 spark, datax 等,都不能像以往操作普通 ORC 表一样,直接读取 HIVE ACID 事务表了。
目前 spark 访问 acid 事务表,社区推荐的方案是通过 hwc (hive warehouse connector) 这一插件来实现对 hive acid 表的读写操作,而 datax 目前还没有成熟的方案。
!关注不迷路~ 各种福利、资源定期分享!欢迎小伙伴们扫码添加明哥微信,后台加群交流学习。
版权声明: 本文为 InfoQ 作者【明哥的IT随笔】的原创文章。
原文链接:【http://xie.infoq.cn/article/861cfd837f65faf7c4b8879ea】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论