数据湖Iceberg库表治理之 Orphan文件膨胀?

日常iceberg表的生产过程中,会由于各种原因,导致很多orphan 垃圾文件,大量无效的磁盘占用,如:snap expire未完成、多端写入时由于锁竞争失败、rewrite commit失败导致等等


Orphan文件膨胀现象

描述:

由于生产环境要求单表 批流混合写入,亚秒至分钟级别的数据实效性,同时要满足下游 亚秒级 ad-hoc查询与多维分析,所以在多端、亚秒级频繁数据写入的同时,需要并行进行多方表治理工作,eg:小文件rewrite、snap expire,导致单表的commit操作竞争激烈,fail频繁,进而导致orphan 垃圾文件激增


数据冗余分析


从示意图中,可以看出

  • commit1是正常的数据写入操作,由于异常导致commit1提交失败、未正常生成snapshot,共遗留了了4个orphan datafile
  • commit2重试写入成功,生成一个snapshot1、当前表共 10个datafile,4个orphan files
  • commit3进行了一次rewrite操作,由于异常导致commit3提交失败,未正常生成snapshot,合并生成了一个新文件:datafile3+datafile4,当前表共 11个datafile,5个orphan files
  • commit4重试rewrite成功,新产生一个snapshot2,合并生成了2个新文件:datafile1+datafile2、datafile3+datafile4,当前表共 13个datafile,5个orphan files



数据冗余原理

  • 对于iceberg表结构而言,任何commit操作都会落地成snapshot
  • 在提交datafile、生成metadata的过程中,遇到突发异常,导致部分datafile没有成功挂载snapshot,此类称为orphan files(类似于java gc中的无引用对象,即:垃圾)

ps:Iceberg有事务特性保证,在保证数据的一致性的前提下,为何还会频繁的失败并有现场残留?与其事务隔离特性、不同的commit类型带来的datafile不同操作以及引擎任务或者作业的稳定性都有关系


如何应对orphan 垃圾文件激增?

So,我们需要定时主动 定期的进行orphan datafiles清理

Orphan datafiles清理操作的两种模式

  • 编程api模式

PS:

  • 需要注意orphan datafiles的误识别与删除,带来的数据损失,即:orphan files的清理范围应该绝对避开数据写入或者更新的interval,以避免正在执行的datafiles被误判。除此之外,不同的底层存储介质变更带来的“索引失效”,也会带来orphan files的误判与数据损失。

  • 当前(2021年2月)社区spark api的orphan datafiles收集、分析与删除都是是单并发,执行性能不是很好,需要进行一定的二次开发,增加并发度

  • Procedures模式

Stored procedures are only available when using Iceberg SQL extensions in Spark 3.x.

CALL catalog_name.system.remove_orphan_files(table => 'db.sample', location => 'tablelocation/data')

https://iceberg.apache.org/docs/latest/spark-procedures/#remove_orphan_files

实战优化效果


从示意图可以看出

  • 小文件数最高清理了2/3,由320万级降低至105万级

To be continued

数据湖Iceberg库表治理之 TTL该如何处理?

发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章