Hudi数据源

云数据库 SelectDB 版支持联邦查询,能够快速集成数据湖、数据库、远端文件等外部数据源,为您提供简便而高效的数据分析体验。本文介绍SelectDB如何使用Catalog集成Hudi数据源,对Hudi数据源进行联邦分析。

前提条件

  • 确保Hudi所在集群所有节点和SelectDB实例的网络处于互通状态。

    • Hudi所在集群所有节点和SelectDB实例处于同一VPC下。

    • 已将Hudi所在集群所有节点IP添加至SelectDB的白名单。具体操作,请参见设置白名单

    • Hudi所在集群存在白名单机制,已将SelectDB实例所在网段IP添加至Hudi所在集群的白名单中。如何获取SelectDB实例的网段IP,请参见如何查看云数据库 SelectDB 版实例所属VPCIP网段?

  • 了解什么是Catalog,以及Catalog的基本操作。具体信息,请参见湖仓一体

注意事项

Hudi表类型不同,SelectDB集成Hudi后,其支持的查询类型不同。

Hudi表类型

支持的查询类型

Copy On Write

Snapshot Queries、 Time Travel

Merge On Read

Snapshot Queries 、Read Optimized Queries 、Time Travel

操作步骤

Hudi能够将数据的元数据信息注册到Hive metastore中,使得Hive可以识别Hudi表并执行查询操作。换句话说,您可以通过Hive来查询由Hudi管理的、支持快速增删改查的数据集。所以SelectDB集成Hudi可通过集成Hive来实现,SelectDB集成Hive的步骤详情,请参见Hive数据源

由于Hudi每次对表的写操作都会产生一个新的快照,SelectDB集成Hudi后,默认情况下,通过SelectDB执行的SELECT * FROM <table_name>的读请求只会读取Hudi最新版本的快照,您可以使用FOR TIME AS OF语句,读取历史版本的数据。示例如下:

说明
  • HudiIceberg不同,其不支持FOR VERSION AS OF语句。

  • 下述语句中时间参数格式,请参见time travel

SELECT * FROM hudi_tbl FOR TIME AS OF "2022-10-07 17:20:37";
SELECT * FROM hudi_tbl FOR TIME AS OF "20221007172037";

列类型映射

Hive Catalog一致,请参见Hive数据源的列类型映射

Skip Merge

Spark在创建Hudi MOR表时,会创建_ro后缀的Read Optimize表。

SelectDB读取Read Optimize表时会跳过log文件的合并。

SelectDB判定一个表是否为Read Optimize表并不是通过_ro后缀,而是通过Hive InputFormat信息。您可以通过SHOW CREATE TABLE命令观察COW/MOR/Read Optimize表的InputFormat是否相同。

此外,SelectDB支持在Catalog Properties添加hoodie相关的配置,配置项兼容Spark Datasource Configs。所以您可以在Catalog Properties中添加hoodie.datasource.merge.type=skip_merge以跳过合并log文件。

查询性能分析

针对Hudi不同类型的表,SelectDB查询的方式不同。其使用Parquet Native Reader读取COW(Copy On Write)表的数据文件,使用Java SDK(通过JNI调用hudi-bundle)读取MOR(Merge On Read)表的数据文件。如果SelectDB性能遇到瓶颈时,需要排除是否是因为集成Hudi,查询Hudi数据导致的,可通过以下步骤排除。

说明

由于Parquet Native Reader性能是本地方法,已经属于最优,所以此处只需排查SelectDBJava SDK的性能。

步骤一:查看SelectDB通过Java SDK读取的文件个数。

您可以通过EXPLAIN命令查看Hudi Scan的执行计划,执行计划中hudiNativeReadSplits表示有多少split文件通过Parquet Native Reader读取,从而得知SelectDB通过Java SDK读取的文件个数。如以下示例中hudiNativeReadSplits的值为717/810,表示Hudi810个文件,SelectDB通过Parquet Native Reader读取的文件个数为717个,通过Java SDK读取的文件个数为810-717=103个。

|0:VHUDI_SCAN_NODE                                                             |
|      table: minbatch_mor_rt                                                  |
|      predicates: `o_orderkey` = 100030752                                    |
|      inputSplitNum=810, totalFileSize=5645053056, scanRanges=810             |
|      partition=80/80                                                         |
|      numNodes=6                                                              |
|      hudiNativeReadSplits=717/810                                            |
步骤二:查看SelectDBJava SDK的性能。

如果selectDB读取Hudi文件大量都是通过Java SDK方式,您可以通过以下命令查看selectDBprofile,分析Java SDK的性能。

SHOW QUERY PROFILE "/"\G;

查询结果中,需重点查看以下参数。更多Profile详情,请参见查询Profile

  • OpenScannerTime:创建并初始化JNI Reader的时间。

  • JavaScanTime:Java SDK读取数据的时间。

  • FillBlockTime:Java数据拷贝为C++数据的时间。

  • GetRecordReaderTime:调用Java SDK并创建Hudi Record Reader的时间。