Hudi Clustering

HudiClustering通过并发写入小文件提升性能,通过异步或同步合并优化查询。文章详细介绍了配置选项、执行机制、同步异步模式和计划策略,包括SparkSizeBased策略和排序列的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

核心概念

Hudi Clustering对于在数据写入和读取提供一套相对完善的解决方案。它的核心思想就是: 在数据写入时,运行并发写入多个小文件,从而提升写入的性能;同时通过一个异步(也可以配置同步,但不推荐)进程或者周期性调度来执行小文件合并成大文件在这个过程中hudi还考虑到对数据按照特定的列进行重排序,这样在解决小文件问题的同时还优化了查询性能,可谓是“两全其美”。对于Clustering的手法其实是一种比较通用的优化数据重新布局的手段。其中在Hive/Spark SQL中都有类似的操作cluster by,只是在hudi中更加追求完美,多了一项合并小文件工作。关于cluster的几个配置参数:

配置项默认值说明
hoodie.clustering.inlinefalse
hoodie.clustering.schedule.inlinefalse
hoodie.clustering.async.enabledfalse
hoodie.clustering.inline.max.commits4
hoodie.clustering.async.max.commits4
hoodie.clustering.plan.strategy.small.file.limit314572800 ( 300MB )只有小于该值的文件才会被视为小文件,从而参与到 Clustering 中。
hoodie.clustering.plan.strategy.target.file.max.bytes1073741824 ( 1GB )限制 Clustering 生成的文件大小,默认是 1GB。合并后的最大文件不会超过该值。
hoodie.clustering.plan.strategy.sort.columns--针对哪个列重新进行排序。对于该字段过滤条件的查询有很大性能提高。

计划与执行

Clustering 的执行机制和compaction的机制类似,都是分为Schedule和execute两个阶段。计划的阶段主要是规划哪些文件参与Clusetring,然后生成一个计划Clusetring Plan保存到Timeline,Timeline中的Instant会有一个replacecommit的值,状态是REQUESTED ;执行阶段主要工作是读取Timeline中的计划,执行完毕,最后将replace commit改为COMPLETED状态。

同步与异步

和compaction一样。Clustering运行模式分为:同步、异步、半异步(为本文的一种叫法,在hudi官网没有体现。)他们之前的差异主要体现在从提交到计划到执行的的三个阶段的推进上。

同步模式(Inline schedule, Inline execute)

同步模式可概括为:立即计划,立即执行(Inline Schedule,Inline Execute)。在该模式下,当累积的提交(Commit)次数到达一个阈值时,会立即触发 Clustering 的计划与执行(计划和执行是连在一起的),而这个阈值是由配置项 hoodie.clustering.inline.max.commits 控制的,默认值是 4,即:默认情况下,每提交 4 次就(有可能)会触发并执行一次 Clustering。锁定同步模式的配置是:

配置项参数
hoodie.clustering.inlinetrue
hoodie.clustering.schedule.inlinefalse
hoodie.clustering.async.enabledFalse

异步模式(offline)

异步模式可概括为:另行计划,另行执行(Offline Schedule,Offline Execute)。在该模式下,任何提交都不会直接触发和执行 Clustering,除非使用支持异步 Clustering 的 Writer,否则用户需要自己保证有一个独立的进程或线程负责定期执行 Clustering 操作。在异步模式下,由于发起计划和提交之间没有必然的协同关系,所以在发起计划时,Timeline 中可能尚未积累到足够数量的提交,或者提交数量已经超过了规定阈值,如果是前者,不会产生计划计划,如果是后者,计划计划会将所有累积的提交涵盖进来,在这一点上,Clustering 和 Compaction 的处理方式是一致的。锁定异步模式的配置是:

配置项设定值
hoodie.clustering.inlinefalse
hoodie.clustering.schedule.inlinefalse
hoodie.clustering.async.enabledtrue

半异步(Inline Schedule,Offline Execute)

半异步模式可概括为:立即计划,另行执行(Inline Schedule,Offline Execute),即:计划会伴随提交自动触发,但执行还是通过前面介绍的三种异步方式之一去完成。简单总结一下半异步的设计思想:它在每次提交时都会尝试生成计划,如果此前已经生成了计划且尚未执行,则放弃计划,等待其被执行,当异步进程或线程完成执行作业时,紧接着的下一次提交会立即生成新的计划,这样,整个 Clustering 的“节奏”就由异步的执行程序来掌控了。锁定半异步模式的配置是:

配置项设定值
hoodie.clustering.inlineFalse
hoodie.clustering.schedule.inlinetrue
hoodie.clustering.async.enabledfalse

计划策略

Clustering 在排期和执行上都有可插拔的策略,以及在执行期间如何应对数据更新也有相应的更新策略,执行策略和更新策略较为简单,使用默认配置即可,本文不再赘述,详情可参考官方文档。本文着重介绍一下排期策略。Hudi 有三种 Clustering 排期策略可供选择:

  • SparkSizeBasedClusteringPlanStrategy:该策略为默认的排期策略,它会筛选出符合条件的小文件(就是看文件大小,小于 clustering.plan.strategy.small.file.limit 规定值的文件就是小文件),然后将选出的小文件分成多个 Group,Group 的数量和大小都是可配置的,划分 Group 的目的是提升 Clustering 的并行度。注意:该策略将会扫描全部分区。

  • SparkRecentDaysClusteringPlanStrategy:该策略会在此前 N 天的分区内查找小文件,对于使用日期作分区,且数据增量是可预期的数据表来说,这种策略是非常适合的。如果在这种情况下使用默认排期策略,就会扫描全部分区,给系统带来没有必要的负载。

  • SparkSelectedPartitionsClusteringPlanStrategy:该策略允许我们针对特定的分区进行 Clustering,这可能会应用在运维或某些具有独特业务特征的数据表上。

排序列

hoodie.clustering.plan.strategy.sort.columns 用于指定在 Clustering 过程中针对哪个列重新进行排序,这也是前文重点解释的 Clustering 能提升数据读取性能的关键。该列的选择对提升查询效率非常重要,通常会选择查询频率最高的条件列。尽管该配置项支持多列,但如果配置了两个或更多列的话,对于那些排在第一列后面的列来说,以它们为条件的查询并不能从中获得太多收益,这和在 HBase 中拼接列值到 Rowkey 中以提升检索性能是一样的。不过,Hudi 提供了以 z-order 和 hilbert 为代表的空间填充曲线技术用于解决多列排序问题。

关闭小文件检查

关闭parquet小文件检查;将hoodie.parquet.small.file.limit置为0。这样做hudi将会把所有的文件认为是大文件。任何数据在写入的时候都不在发生copy-on-write的copy的操作。而是直接写入新的文件,这样减少了写入操作的负担。所以产生的小文件就是Clustering就要去解决的事情。

同步Clustering

参数配置

配置项默认值设定值
hoodie.clustering.inlinefalseTrue
hoodie.clustering.schedule.inlinefalsefalse
hoodie.clustering.async.enabledFalseFalse
hoodie.clustering.async.enabled42
hoodie.clustering.async.enabled314572800 ( 300MB )314572800 ( 300MB )
hoodie.clustering.async.enabled1073741824 ( 1GB )1073741824 ( 1GB )
hoodie.parquet.small.file.limit104857600 ( 100MB )0

建表语句

create table small_file_hudi_cow (
  id int,
  name string,
  age int,
  city STRING,
  date_str STRING
) using hudi
tblproperties (
  type = 'cow',
  primaryKey = 'id',
  preCombineField = 'id',
  'hoodie.clustering.inline' = true,
  'hoodie.clustering.schedule.inline' = false,
  'hoodie.clustering.async.enabled' = false,
  'hoodie.clustering.inline.max.commits' = 2,
  'hoodie.clustering.plan.strategy.small.file.limit' = 314572800,
  'hoodie.clustering.plan.strategy.target.file.max.bytes' = 1073741824,
  'hoodie.parquet.small.file.limit' = '0'
)
partitioned by (date_str);

执行计划

步骤操作文件系统导入或者更新操作
1insertbase fileINSERT INTO small_file_hudi_cow SELECT id, name, age, city, event_date FROM sample_data_partitioned where event_date='2023-11-02';
2updatebase fileINSERT INTO small_file_hudi_cow SELECT id, name, age, city, event_date FROM sample_data_partitioned where event_date='2023-11-02';
3updateclustering +base fileINSERT INTO small_file_hudi_cow SELECT id, name, age, city, event_date FROM sample_data_partitioned where event_date='2023-11-02';

第一步:insert

Hudi 将其写入到一个 Parquet 文件中,第一组 File Group 随之产生。其文件信息及时间线如下:

第二步:

由于全量更新第一次的所有数据文件,更新后添加对应的一组 file 信息。其文件信息及时间线如下:

第三步:

在做一次全量的数据更新,同时设置了clustering 模式的最大提交次数为2,所以此次提交触发clustering 机制。自动发起了名为 replacecommit 提交,然后预计合并后的数据进行更新的commit 信息。其文件信息及时间线如下:

<think>好的,用户想了解Apache Hudi的语法文档和示例。首先,我需要回顾一下Hudi的核心概念和操作类型。Hudi主要支持两种表类型:Copy-on-Write(COW)和Merge-on-Read(MOR)。COW在写入时合并数据,适合读多写少的场景;而MOR则优化了写入性能,适合频繁写入的情况。 接下来,用户可能需要知道如何通过不同的工具(比如Spark SQL、Flink或Hive)来操作Hudi表。根据引用[4]和[5],Hudi已经与Spark SQL集成,用户可以使用SQL语句进行表的创建、插入、更新等操作。例如,创建COW表时,需要指定主键、预合并字段以及表类型。 然后,用户可能关心具体的语法示例。比如,如何创建表,如何进行插入、更新、删除操作,还有时间旅行查询和增量查询这些高级功能。引用[5]提到,Hudi支持增量查询,可以读取某个提交之后的变更数据,这对于流处理场景非常有用。 另外,用户可能需要了解如何与其他大数据组件集成,比如Presto或Hive,以便查询Hudi表。引用[4]中提到,将Hudi的jar包放入Presto的插件目录后,就可以通过Hive连接器查询Hudi表,这需要配置Hive Metastore的地址。 同时,需要注意Hudi的不同版本可能有语法差异,用户需要根据自己使用的版本来参考对应的文档。例如,Hudi 0.10.0之后对Spark SQL的支持更加完善,而之前的版本可能需要使用DataFrame API。 最后,用户的问题可能涉及到实际应用中的问题,比如性能优化或与其他系统的整合。根据引用[1]和[2],Hudi与Doris的结合可以提升查询和分析效率,这可能为用户提供更多的应用场景参考。 总结来说,我需要整理Hudi的核心语法和操作示例,涵盖表创建、数据操作、查询以及与其他工具的集成,同时引用相关的社区资料来支持回答的可靠性。</think>### Apache Hudi 语法文档及示例 Apache Hudi 是一种支持高效数据更新、删除和增量处理的数据湖存储格式,其核心语法主要围绕**表类型**、**操作类型**和**数据管理功能**展开。以下是 Hudi 核心语法及示例: --- #### 1. **表类型** Hudi 支持两种表类型,需在建表时通过 `type` 参数指定: - **Copy-on-Write (COW)**:写入时合并,适合读多写少场景。 - **Merge-on-Read (MOR)**:写入时追加日志,读取时合并,适合写多读少场景。 **示例:创建 COW 表(Spark SQL)** ```sql CREATE TABLE hudi_cow_table ( id INT, name STRING, value DOUBLE, ts BIGINT ) USING HUDI TBLPROPERTIES ( type = 'cow', primaryKey = 'id', preCombineField = 'ts' ); ``` --- #### 2. **数据操作** ##### **插入数据** ```sql INSERT INTO hudi_cow_table VALUES (1, 'A', 10.5, 1672502400000), (2, 'B', 20.3, 1672502400001); ``` ##### **更新数据** ```sql UPDATE hudi_cow_table SET value = 15.0 WHERE id = 1; ``` ##### **删除数据** ```sql DELETE FROM hudi_cow_table WHERE id = 2; ``` --- #### 3. **增量查询** 通过 `hoodie.read.timeline.mode` 参数指定增量范围: ```sql SELECT * FROM hudi_cow_table TIMESTAMP AS OF '2023-01-01 00:00:00'; -- 时间旅行查询 ``` ```scala // 增量读取(Spark DataFrame) spark.read .format("hudi") .option("hoodie.datasource.query.type", "incremental") .option("hoodie.datasource.read.begin.instanttime", "20230101000000") .load("/path/to/hudi_table"); ``` --- #### 4. **与 Hive/Presto 集成** Hudi 表可通过 Hive Metastore 直接查询: 1. **Hive 中同步表**: ```sql MSCK REPAIR TABLE hudi_cow_table; ``` 2. **Presto 查询**(需配置 Hive Connector): ```sql SELECT * FROM hive.default.hudi_cow_table; ``` --- #### 5. **高级功能** - **Clustering(文件优化)**: ```sql CALL run_clustering(table => 'hudi_cow_table'); ``` - **Compaction(MOR 表专用)**: ```sql CALL run_compaction(table => 'hudi_mor_table'); ``` --- ### 相关文档参考 1. **Hudi 与 Spark SQL 集成**:支持通过 SQL 直接操作 Hudi 表,简化数据管理流程[^5]。 2. **Hudi 与 Presto/Hive 集成**:通过 Hive Metastore 实现跨引擎查询,适用于湖仓一体架构[^4][^2]。 3. **增量处理**:Hudi 的增量查询功能可高效处理流式数据变更,结合 Flink 或 Spark Streaming 使用[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值