云数据库 SelectDB 版支持联邦查询,能够快速集成数据湖、数据库、远端文件等外部数据源,为您提供简便而高效的数据分析体验。本文介绍SelectDB如何使用Catalog集成Hudi数据源,对Hudi数据源进行联邦分析。
前提条件
确保Hudi所在集群所有节点和SelectDB实例的网络处于互通状态。
Hudi所在集群所有节点和SelectDB实例处于同一VPC下。
已将Hudi所在集群所有节点IP添加至SelectDB的白名单。具体操作,请参见设置白名单。
若Hudi所在集群存在白名单机制,已将SelectDB实例所在网段IP添加至Hudi所在集群的白名单中。如何获取SelectDB实例的网段IP,请参见如何查看云数据库 SelectDB 版实例所属VPC的IP网段?。
了解什么是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
语句,读取历史版本的数据。示例如下:
Hudi与Iceberg不同,其不支持
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
性能是本地方法,已经属于最优,所以此处只需排查SelectDB中Java SDK的性能。
步骤一:查看SelectDB通过Java SDK读取的文件个数。
您可以通过EXPLAIN命令查看Hudi Scan的执行计划,执行计划中hudiNativeReadSplits
表示有多少split文件通过Parquet Native Reader读取,从而得知SelectDB通过Java SDK读取的文件个数。如以下示例中hudiNativeReadSplits
的值为717/810
,表示Hudi有810个文件,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 |
步骤二:查看SelectDB中Java SDK的性能。
如果selectDB读取Hudi文件大量都是通过Java SDK方式,您可以通过以下命令查看selectDB的profile,分析Java SDK的性能。
SHOW QUERY PROFILE "/"\G;
查询结果中,需重点查看以下参数。更多Profile详情,请参见查询Profile。
OpenScannerTime
:创建并初始化JNI Reader的时间。JavaScanTime
:Java SDK读取数据的时间。FillBlockTime
:Java数据拷贝为C++数据的时间。GetRecordReaderTime
:调用Java SDK并创建Hudi Record Reader的时间。