Apache Hudi分区能否优化AWS Redshift Spectrum查询及DDL排查
Redshift Spectrum查询Hudi表的分区优化问题解析
核心结论先行
- 当Hudi分区列设为
a时,where a=3的查询理论上能触发分区裁剪;设为b则完全无法利用分区,只能全表扫描。 - 你的Spectrum无法识别分区,核心问题是DDL没显式定义分区列,也没加载分区元数据。
1. 不同分区列设置的性能差异
- 如果Hudi表用
hoodie.datasource.write.partitionpath.field=a做分区,S3上会生成a=xxx/的目录结构。此时如果Spectrum外部表正确识别了这个分区,查询where a=3就只会扫描a=3对应的目录,性能大幅提升。 - 如果分区列设为
b,查询条件a=3和分区毫无关系,Spectrum只能遍历所有文件,和没分区的表性能一样。
2. Spectrum能不能利用Hudi分区?
可以,但有两个前提:
- Hudi的分区是标准的Hive风格目录(
分区列=值/),这一点Hudi默认就是这么写的,没问题。 - 你的Spectrum外部表必须显式定义分区列,并且加载了分区的元数据。
3. 你的DDL问题修正
你当前的DDL没声明分区列,Spectrum根本不知道S3上的分区目录对应表的哪一列,自然没法做裁剪。修正步骤:
第一步:修改DDL添加分区列
create external table spectrum.test_hudi_users_activity ( -- 这里写所有非分区列的定义,比如b和其他字段 b string, -- 其他列... ) PARTITIONED BY (a string) -- 这里必须加,类型要和Hudi写入的分区列类型一致 ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe' STORED AS INPUTFORMAT 'org.apache.hudi.hadoop.HoodieParquetInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat' LOCATION 's3://xxx';
第二步:加载分区元数据
执行这条命令让Spectrum同步S3上的分区目录:
MSCK REPAIR TABLE spectrum.test_hudi_users_activity;
做完这两步后,再执行select a,b from my_table where a=3,Spectrum就只会扫描a=3对应的分区目录,不会全表扫描了。
另外要注意:Hudi写入时的分区列数据类型,必须和外部表定义的PARTITIONED BY里的类型完全匹配,不然MSCK可能加载不到分区。
内容的提问来源于stack exchange,提问作者Rinze
相关产品推荐
相关产品推荐

