数据湖技术 Iceberg 和 Hudi 的比较
Iceberg 和 Hudi 应用对比
功能对比
功能上简单的对比来看,Hudi 的功能相对更完善,整体比较接近。
Iceberg 应用场景
Iceberg 更适合的场景
多种引擎并发访问一张表,统一存储。
Iceberg 对引擎提供统一的 base 接口,可扩展性更佳,避免由于不同引擎接口实现不一致导致的数据读写不一致问题。实现存储层的流批一体访问,保证事务完整。统一的接口使得扩展到新的计算引擎或者文件系统都非常的方便快速。
OLAP 分析场景。
Iceberg 支持主流的列式存储 parquet 和 orc,针对流式和批式都默认有稀疏索引支持(min-max)、bloomfilter,支持简单聚合计算的下推能力。通过层层下推过滤,能够大量减少读取的数据量,相比 Hive 只支持分区裁剪,查询分析效率更高。
表分区频繁变更。
随着业务和数据流量的变化,分区策略需要进行调整,支持 DDL 语句动态调整分区规则,比如按周分区调整为按天分区,不需要大量重新导入数据。
同时分区变更不会带来 SQL 脚本的变更,不需要在大量修改 SQL 任务脚本上投入成本。因为 Iceberg 支持隐藏分区的能力,在 SQL 查询任务中不需要指定分区规则。
这里的例子创建的是 hour(order_ts)级别分区,查询 order_ts=DATE‘2021-01-26’时,根据 order_ts 自动计算出数据所在的分区。
学习成本低,更适合业务分析人员使用。
Iceberg 提供给用户的配置参数 100 个左右,常用的 10 个左右,Hudi 提供的参数超过 1000 个,学习成本很高,使用体验上 Iceberg 更好。
数据回溯、历史数据处理。
Iceberg 都支持灵活的快照管理和时间旅行,可以回溯到更早期的数据快照,使开发人员能够访问和还原早期版本的数据以进行审核、回滚或重新计算。
时间旅行有以下使用案例:
在数据被污染时,可以回溯到之前版本,然后重新修正数据。
在数据不断变更的情况,可以基于某一快照数据重复计算,比如机器学习或调试。
替代 Hive 表
Iceberg 的诞生初衷就是为了优化 Hive 存在的问题,比如不支持行级更新,不支持 data skipping,不支持分区演进等。但是 Iceberg 对 hive metastore 支持较好,可以将 Hive 在不迁移数据文件的情况下直接转换为 Iceberg 表,成本很低。
Iceberg 不适合的场景
不适合大流量表的流式 upsert 数据。
Iceberg upsert 模式采用前置删除的方式,在插入一条数据之前先插入一条 delete 数据,删除历史中的记录,实现数据主键的唯一性。带来的问题是会产生大量的 delete 文件和数据,在数据流量较大的情况下,查询性能较差,需要提供较多的资源合并处理。同时写入速度相比 insert 模式会变慢。
不适合秒级响应延迟的准实时场景。
Flink+Iceberg 作为一般实时入湖的的方案,Flink 每次 checkpoint 都会产生多个文件,包括数据文件和元数据文件。如果时间延迟设置很低,会产生大量小文件,对存储的压力较大。所以一般适合分钟级别的延迟。
不适合存储维表数据。
Iceberg 表主要支持列式存储格式,不适合 kv 行式存储,所以维表存储在 Iceberg 表中,在流表 Join 时性能较差。
更新数据的 CDC 捕获。
Iceberg 支持 append 数据的 CDC 流式读取捕获,但是对于行级更新的数据流,还不支持流式读取。
Hudi 应用场景
Hudi 更适合的场景
更新方式有多种,更灵活。
upsert 场景支持相对更好,hudi 的 log 可以追加,文件数量更少(但是 S3 存储不支持)。
数据回溯、历史数据处理。
作为数据湖表格式的基本功能,Hudi 和 Iceberg 一样支持灵活的历史版本回溯。
功能比较丰富完善,对运维更友好。
Hudi 提供了丰富的表服务,功能更完善。但是这些服务在离线执行的情况下,会阻塞流数据写入或丢失数据,运维服务和流数据任务之间还没有实现真正并发。
Hudi 不适合的场景
不适合多种引擎并发访问的场景。
比如 spark 和 flink 共同使用的场景,由于接口的不统一,早期存在数据丢失的情况,目前主要是离线合并和 flink 实时任务会有冲突问题,影响数据的准确性。
不容易上手。
Hudi 提供的参数配置太多,学习成本很高,不同的计算引擎都有一系列对应的配置,需要有一定的调优经验。
查询分析性能要求较高的实时场景。
MDT 索引只对 ro(读优化)表或 base 文件起作用,一般使用于离线 COW 表,对 log 文件不支持。所以在实时更新的场景下,MDT 索引对 MOR 表支持不好,查询性能不佳。
大流量表实时的 upsert 数据。
Flink + Hudi 对于 upsert 场景的支持虽然相对较好,但是在大流量的 upsert 数据场景下,Flink 的 State 状态数据会越来越多,直接影响写入速度。
更新数据的 CDC 捕获。
此功能虽然已发布,但是属于实验功能,不支持上生产,不支持 MOR 表。
总结
Iceberg 和 Hudi 都支持行级更新的能力,但是在 upsert 流数据的场景下,或多或少都存在一些性能问题,不适合大流量表 upsert 数据,建议采用批处理的方式 Merge 数据。
Iceberg 和 Hudi 在能力上越来越接近,但是定位不同。Iceberg 定位成为数据湖格式的标准接口,更重视兼容性和可扩展性,在基础架构上投入更多,所以从社区活跃度和功能迭代速度看,不如 Hudi,Hudi 定位成为一个综合的数据湖平台,功能更丰富,迭代更快,但是架构上劣势会造成版本的不稳定,功能可移植性较差。
Iceberg 在查询分析上能力相对较好,但是大量更新实时数据时产生的文件可能会比较多,造成性能较差。Hudi 则更适合大量数据更新的场景,在查询分析的场景优化力度不够。
Iceberg 和 Hudi 都支持较好的数据回溯能力。
Iceberg 在分区变更和隐藏分区上支持相对较好。
Iceberg 和 Hudi 对于实时场景下的 CDC 数据流式读取,支持较弱或不支持,都不满足上生产构建实时数仓的条件,所以基于 Iceberg 或 Hudi 构建实时数仓的方案目前还不够成熟。
版权声明: 本文为 InfoQ 作者【漫长的白日梦】的原创文章。
原文链接:【http://xie.infoq.cn/article/e6a848141d6b82751f328da63】。文章转载请联系作者。
评论