Hudi剖析|详解ApacheHudi如何节约宝贵的存储空间
1. 介绍
对于旧版本的数据 Hudi
需要将其删除以节约宝贵的存储空间, Clean
操作有两种策略: KEEP_LATEST_FILE_VERSIONS
(保留最新的文件版本)和 KEEP_LATEST_COMMITS
(保留最新的提交),不同的策略会有不同的行为, Clean
阶段被分为生成 HoodieCleanerPlan
和执行 HoodieCleanerPlan
,下面分析 Clean
的具体实现。
2. 分析
在每次 commit
时,会判断是否开启自动 clean
来执行 clean
操作,或者由用户手动触发 clean
操作。
2.1 生成HoodieCleanerPlan
对于在 commit
时执行的 clean
操作,其核心入口为 HoodieCleanClient#clean
,核心代码如下
需要先处理未完成的 clean
,然后再通过 scheduleClean
方法生成 HoodieCleanerPlan
,其核心代码如下
会继续调用 HoodieCopyOnWriteTable#scheduleClean
生成 HoodieCleanerPlan
,核心代码如下
对于 HoodieCleanerPlan
的生成,首先会找出最早需要保留的 instant
,然后获取对应所有的分区路径。
2.1.1 获取待Clean的所有分区
获取所有待clean分区路径的核心代码如下
可以看到,如果开启了增量 clean
并且当前 instant
不为空,同时策略为 KEEP_LATEST_COMMITS
时,则会先取上次已完成的 clean
,然后过滤出从上次已完成 clean
的 instant
时间到当前clean中需要保留的最早的 instant
时间,并获取对应的分区路径;否则直接返回所有的分区路径。
在获取了所有待 clean
的分区路径后,还需要调用 HoodieCleanHelper#getDeletePaths
获取所有待删除的文件路径。
2.1.2 获取待删除文件
获取待删除文件的核心代码如下
可以看到,根据策略的不同调用不同方法来获取分区下待删除的所有文件。
对于 KEEP_LATEST_COMMITS
策略而言, getFilesToCleanKeepingLatestCommits
核心代码如下
可以看到,找出待删除的文件需要会经过一系列判断,如不能删除 savepoint
文件,不能删除小于最早需要保留的 instant
的时间文件(因为该文件可能还是会被使用),不能删除待压缩的文件。仅删除那些小于最早需要保留的 instant
的文件,并且如果是 MOR
类型,那么可以将日志文件一并删除。
对于 KEEP_LATEST_FILE_VERSIONS
策略而言, getFilesToCleanKeepingLatestVersions
获取待删除文件的核心代码如下
可以看到,对于 savepoint
的文件也不能删除,也不能删除待压缩的文件。仅删除那些不需要继续保留的版本的文件,如果是 MOR
类型,那么可以将日志文件一并删除。
2.2 执行HoodieCleanerPlan
在生成 HoodieCleanerPlan
后,会将其序列化并保存至元数据目录,然后开始执行,其核心在 HoodieCleanClient#runClean
,其核心代码如下
这块代码的核心逻辑非常简单,首先反序列出 HoodieCleanerPlan
,然后再开始执行删除操作,实际删除文件操作由 deleteFilesFunc
处理,然后返回 Clean
的统计信息。
3. 总结
对于 Clean
操作, Hudi
提供了两种策略:基于文件版本和基于提交保留数。并且将 Clean
分为生成 HoodieCleanerPlan
和执行 HoodieCleanerPlan
两个阶段,两阶段并不直接关联.在生成 HoodieCleanerPlan
时会找出所有符合指定策略的待删除文件,并且为了避免每次全分区处理,Hudi还提供了增量 Clean
配置项,即仅仅只处理从上次 Clean
后影响的分区,然后将 HoodieCleanerPlan
序列化至元数据(.aux)目录,在执行阶段会从元数据目录中反序列化后执行删除文件操作。