配置Hive读取Hudi表
在数据湖场景中,Hudi(Hadoop Upserts Deletes and Incrementals)作为流式数据湖存储格式,支持高效的数据更新和增量查询。业务系统通过Spark或Flink将数据写入Hudi表后,可能需要使用Hive进行复杂的数据分析查询。然而,Hudi表的数据格式与Hive原生表格式不同,直接在Hive中查询Hudi表会遇到兼容性问题。如何将Hudi表的数据映射为Hive可查询的外部表,并支持实时视图、读优化视图和增量视图等多种查询模式?MRS Hive提供Hudi表映射功能,可以将Hudi源表映射为Hive外部表,支持多种视图查询模式,满足不同的数据分析需求。
本文介绍如何配置Hive读取Hudi表。
Hudi表对应的Hive外部表介绍
Hudi源表对应一份HDFS的数据,通过Spark组件、Flink组件或者Hudi客户端,可以将Hudi表的数据映射为Hive外部表,基于该外部表,Hive可以进行实时视图查询、读优化视图查询以及增量视图查询。
- Hudi源表类型为Copy On Write时,可以映射为Hive的一张外部表,该表可以提供实时视图查询以及增量视图查询。
- Hudi源表类型为Merge On Read时,可以映射为Hive的两张外部表(ro表和rt表),ro表提供读优化视图查询,rt表提供实时视图查询以及增量视图查询。
约束与限制
创建Hudi表对应的Hive外部表
可在spark-shell或spark-sql中创建Hudi表并插入数据,具体操作请参见使用Spark Shell创建Hudi表或使用Spark SQL操作Hudi表。
Hudi表数据在入湖的时候一般会同步到Hive外部表,此时在Beeline中可以直接查询到对应的Hive外部表,如果没有同步到Hive外部表,则可以通过Hudi客户端工具手动同步,具体步骤可参考将Hudi表数据同步到Hive。
查询Hudi表对应的Hive外部表
使用Hive对Hudi表进行增量查询前,需要设置表1的3个参数,这3个参数是表级别的参数,每个Hudi源表都对应3个参数,其中hudisourcetablename表示Hudi源表的表名(需注意不是Hive外部表的表名),需根据实际情况进行修改。
MRS 3.6.0-LTS及之后版本,使用Tez引擎执行Hive查询Hudi表任务时,如果报错“java.lang.UnsupportedOperationException: Not expecting to handle any events”,则可以在Hive客户端执行以下命令关闭动态分区裁剪功能后,再重新执行查询命令。
set hive.tez.dynamic.partition.pruning=false;
| 参数 | 参数说明 | 默认值 |
|---|---|---|
| hoodie.hudisourcetablename.consume.mode | Hudi表的查询模式。
| 无 |
| hoodie.hudisourcetablename.consume.start.timestamp | Hudi表增量查询的起始时间。
| 无 |
| hoodie.hudisourcetablename.consume.max.commits | Hudi表增量查询基于“hoodie.hudisourcetablename.consume.start.timestamp”之后commit的次数。
| 无 |
Hudi表查询操作如下:
- 以Hive客户端安装用户登录安装客户端的节点。
- 执行以下命令,切换到客户端安装目录,配置环境变量并认证用户。
切换到客户端安装目录:
cd 客户端安装目录加载环境变量
source bigdata_env
认证用户,如果集群未启用Kerberos认证(普通模式),请跳过该操作:
kinit Hive业务用户 - 执行以下命令登录Hive客户端。
beeline
- Hudi表查询。
- Copy On Write类型Hudi表查询
例如cow类型的Hudi源表的表名为hudicow,映射为Hive外部表的表名为hudicow。
- cow表实时视图查询:
select * from hudicow;
- cow表增量查询,需要根据Hudi源表的表名设置3个增量查询参数,且增量查询语句的where子句必须包含“`_hoodie_commit_time`>'xxx'”,其中的xxx为“hoodie.hudisourcetablename.consume.start.timestamp”增量参数的值。
设置Hudi表的查询模式为“INCREMENTAL”:
set hoodie.hudicow.consume.mode= INCREMENTAL;
设置Hudi表增量查询的提交次数:
set hoodie.hudicow.consume.max.commits=3;
设置Hudi表增量查询的起始时间:
set hoodie.hudicow.consume.start.timestamp= 20200427114546;
执行cow表增量查询:
select count(*) from hudicow where `_hoodie_commit_time`>'20200427114546';
- cow表实时视图查询:
- Merge On Read类型Hudi表的查询
例如mor类型的Hudi源表的表名为hudimor,映射为两张Hive外部表hudimor_ro(ro表)和hudimor_rt(rt表)。
- ro表提供读优化视图查询:
select * from hudicow_ro;
- rt的实时视图查询:
select * from hudicow_rt;
- rt表的增量查询,需要根据Hudi源表的表名设置3个增量查询参数,且增量查询语句的where子句必须包含“`_hoodie_commit_time`>'xxx'”,其中的xxx为“hoodie.hudisourcetablename.consume.start.timestamp”增量参数的值。
设置Hudi表的查询模式:
- 设置Hudi表为增量查询:
set hoodie.hudimor.consume.mode=INCREMENTAL;
- 设置Hudi表为其他查询模式:
set hoodie.hudisourcetablename.consume.mode=SNAPSHOT;
设置Hudi表增量查询的提交次数:
set hoodie.hudimor.consume.max.commits=-1;
设置Hudi表增量查询的起始时间:
set hoodie.hudimor.consume.start.timestamp=20210207144611;
执行rt表查询操作:
select * from hudimor_rt where `_hoodie_commit_time`>'20210207144611';
- 设置Hudi表为增量查询:
- ro表提供读优化视图查询:
- Copy On Write类型Hudi表查询
验证操作:
执行查询后,检查返回结果:
- 实时视图查询应返回最新的数据状态。
- 读优化视图查询应返回已合并的基础数据。
- 增量查询应返回指定时间范围内的变更数据。
查询Hudi的Schema演进表对应的Hive外部表
如果该Hudi表为Schema演进表(表的字段执行过修改),则在Hive客户端查询该表时还需额外设置一个参数:
set hive.exec.schema.evolution=true;
该参数设置为“true”后,Hive会自动适应Hudi表的Schema变化,确保查询结果基于最新的表结构,以提供准确和一致的查询结果。
例如以cow表实时视图的查询举例,其他各个视图的查询都要额外添加该参数:
设置“hive.exec.schema.evolution”为“true”:
set hive.exec.schema.evolution=true;
查询Hive外部表:
select * from hudicow; 常见问题
- 查询Hudi表报错“Table not found”
Hudi表数据未同步到Hive外部表,或Hive外部表名称不正确。
请确认Hudi表数据已同步到Hive外部表。如果未同步,请参考将Hudi表数据同步到Hive手动同步。检查Hive外部表名称是否正确。
- 增量查询返回空结果
增量查询参数设置不正确,或指定的起始时间范围内没有数据变更。
请检查consume.mode、consume.start.timestamp、consume.max.commits三个参数是否正确设置。确认起始时间在Hudi表的数据变更时间范围内。where子句中的_hoodie_commit_time值必须与consume.start.timestamp参数值一致。
- MOR表查询性能较差
MOR表的rt表在查询时需要合并基础文件和日志文件,查询开销较大。
如果对数据实时性要求不高,建议使用ro表进行读优化视图查询,性能更好。或者定期触发compaction操作,将日志文件合并到基础文件中。
相关文档
- 了解Hive数据操作,请参考Hive客户端使用实践。
- 了解如何创建Hive用户并绑定角色,请参考创建Hive用户并绑定角色。
- 了解Hive常见问题,请参考Hive常见问题。