写点什么

深度对比 Delta、Iceberg 和 Hudi 三大开源数据湖方案

2020 年 3 月 19 日

深度对比Delta、Iceberg和Hudi三大开源数据湖方案

目前市面上流行的三大开源数据湖方案分别为:Delta、Apache Iceberg 和 Apache Hudi。其中,由于 Apache Spark 在商业化上取得巨大成功,所以由其背后商业公司 Databricks 推出的 Delta 也显得格外亮眼。Apache Hudi 是由 Uber 的工程师为满足其内部数据分析的需求而设计的数据湖项目,它提供的 fast upsert/delete 以及 compaction 等功能可以说是精准命中广大人民群众的痛点,加上项目各成员积极地社区建设,包括技术细节分享、国内社区推广等等,也在逐步地吸引潜在用户的目光。Apache Iceberg 目前看则会显得相对平庸一些,简单说社区关注度暂时比不上 Delta,功能也不如 Hudi 丰富,但却是一个野心勃勃的项目,因为它具有高度抽象和非常优雅的设计,为成为一个通用的数据湖方案奠定了良好基础。


很多用户会想,看着三大项目异彩纷呈,到底应该在什么样的场景下,选择合适的数据湖方案呢?今天我们就来解构数据湖的核心需求,深度对比三大产品,帮助用户更好地针对自身场景来做数据湖方案选型。


首先,我们来逐一分析为何各技术公司要推出他们的开源数据湖解决方案,他们碰到的问题是什么,提出的方案又是如何解决问题的。我们希望客观地分析业务场景,来理性判断到底哪些功能才是客户的痛点和刚需。


Databricks 和 Delta

以 Databricks 推出的 delta 为例,它要解决的核心问题基本上集中在下图:



图片来源:https://www.slideshare.net/databricks/making-apache-spark-better-with-delta-lake


在没有 Delta 数据湖之前,Databricks 的客户一般会采用经典的 Lambda 架构来构建他们的流批处理场景。以用户点击行为分析为例,点击事件经 Kafka 被下游的 Spark Streaming 作业消费,分析处理(业务层面聚合等)后得到一个实时的分析结果,这个实时结果只是当前时间所看到的一个状态,无法反应时间轴上的所有点击事件。所以为了保存全量点击行为,Kafka 还会被另外一个 Spark Batch 作业分析处理,导入到文件系统上(一般就是 parquet 格式写 HDFS 或者 S3,可以认为这个文件系统是一个简配版的数据湖),供下游的 Batch 作业做全量的数据分析以及 AI 处理等。


这套方案其实存在很多问题 :


第一、批量导入到文件系统的数据一般都缺乏全局的严格 schema 规范,下游的 Spark 作业做分析时碰到格式混乱的数据会很麻烦,每一个分析作业都要过滤处理错乱缺失的数据,成本较大;


第二、数据写入文件系统这个过程没有 ACID 保证,用户可能读到导入中间状态的数据。所以上层的批处理作业为了躲开这个坑,只能调度避开数据导入时间段,可以想象这对业务方是多么不友好;同时也无法保证多次导入的快照版本,例如业务方想读最近 5 次导入的数据版本,其实是做不到的。


第三、用户无法高效 upsert/delete 历史数据,parquet 文件一旦写入 HDFS 文件,要想改数据,就只能全量重新写一份的数据,成本很高。事实上,这种需求是广泛存在的,例如由于程序问题,导致错误地写入一些数据到文件系统,现在业务方想要把这些数据纠正过来;线上的 MySQL binlog 不断地导入 update/delete 增量更新到下游数据湖中;某些数据审查规范要求做强制数据删除,例如欧洲出台的 GDPR 隐私保护等等。


第四、频繁地数据导入会在文件系统上产生大量的小文件,导致文件系统不堪重负,尤其是 HDFS 这种对文件数有限制的文件系统。


所以,在 Databricks 看来,以下四个点是数据湖必备的。



事实上, Databricks 在设计 Delta 时,希望做到流批作业在数据层面做到进一步的统一(如下图)。业务数据经过 Kafka 导入到统一的数据湖中(无论批处理,还是流处理),上层业务可以借助各种分析引擎做进一步的商业报表分析、流式计算以及 AI 分析等等。



所以,总结起来,我认为 Databricks 设计 Delta 时主要考虑实现以下核心功能特性:



Uber 和 Apache Hudi

Uber 的业务场景主要为:将线上产生的行程订单数据,同步到一个统一的数据中心,然后供上层各个城市运营同事用来做分析和处理。在 2014 年的时候,Uber 的数据湖架构相对比较简单,业务日志经由 Kafka 同步到 S3 上,上层用 EMR 做数据分析;线上的关系型数据库以及 NoSQL 则会通过 ETL(ETL 任务也会拉去一些 Kakfa 同步到 S3 的数据)任务同步到闭源的 Vertica 分析型数据库,城市运营同学主要通过 Vertica SQL 实现数据聚合。当时也碰到数据格式混乱、系统扩展成本高(依赖收 Vertica 商业收费软件)、数据回填麻烦等问题。后续迁移到开源的 Hadoop 生态,解决了扩展性问题等问题,但依然碰到 Databricks 上述的一些问题,其中最核心的问题是无法快速 upsert 存量数据。



如上图所示,ETL 任务每隔 30 分钟定期地把增量更新数据同步到分析表中,全部改写已存在的全量旧数据文件,导致数据延迟和资源消耗都很高。此外,在数据湖的下游,还存在流式作业会增量地消费新写入的数据,数据湖的流式消费对他们来说也是必备的功能。所以,他们就希望设计一种合适的数据湖方案,在解决通用数据湖需求的前提下,还能实现快速的 upsert 以及流式增量消费。



Uber 团队在 Hudi 上同时实现了 Copy On Write 和 Merge On Read 的两种数据格式,其中 Merge On Read 就是为了解决他们的 fast upsert 而设计的。简单来说,就是每次把增量更新的数据都写入到一批独立的 delta 文件集,定期地通过 compaction 合并 delta 文件和存量的 data 文件。同时给上层分析引擎提供三种不同的读取视角:仅读取 delta 增量文件、仅读取 data 文件、合并读取 delta 和 data 文件。满足各种业务方对数据湖的流批数据分析需求。


最终,我们可以提炼出 Uber 的数据湖需求为如下图,这也正好是 Hudi 所侧重的核心特性。



Netflix 和 Apache Iceberg

Netflix 的数据湖原先是借助 Hive 来构建,但发现 Hive 在设计上的诸多缺陷之后,开始转为自研 Iceberg,并最终演化成 Apache 下一个高度抽象通用的开源数据湖方案。Netflix 用内部的一个时序数据业务的案例来说明 Hive 的这些问题,采用 Hive 时按照时间字段做 partition,他们发现仅一个月会产生 2688 个 partition 和 270 万个数据文件。他们执行一个简单的 select 查询,发现仅在分区裁剪阶段就耗费数十分钟。



他们发现 Hive 的元数据依赖一个外部的 MySQL 和 HDFS 文件系统,通过 MySQL 找到相关的 parition 之后,需要为每个 partition 去 HDFS 文件系统上按照分区做目录的 list 操作。在文件量大的情况下,这是一个非常耗时的操作。同时,由于元数据分属 MySQL 和 HDFS 管理,写入操作本身的原子性难以保证。即使在开启 Hive ACID 情况下,仍有很多细小场景无法保证原子性。另外,Hive Metastore 没有文件级别的统计信息,这使得 filter 只能下推到 partition 级别,而无法下推到文件级别,对上层分析性能损耗无可避免。最后,Hive 对底层文件系统的复杂语义依赖,使得数据湖难以构建在成本更低的 S3 上。


于是,Netflix 为了解决这些痛点,设计了自己的轻量级数据湖 Iceberg。在设计之初,作者们将其定位为一个通用的数据湖项目,所以在实现上做了高度的抽象。虽然目前从功能上看不如前面两者丰富,但由于它牢固坚实的底层设计,一旦功能补齐,将成为一个非常有潜力的开源数据湖方案。


总体来说,Netflix 设计 Iceberg 的核心诉求可以归纳为如下:



痛点小结


我们可以把上述三个项目针对的痛点,放到一张图上来看。可以发现标红的功能点,基本上是一个好的数据湖方案应该去做到的功能点。


7 大维度对比

在理解了上述三大方案各自设计的初衷和面向的痛点之后,接下来我们从 7 个维度来对比评估三大项目的差异。通常人们在考虑数据湖方案选型时,Hive ACID 也是一个强有力的候选人,因为它提供了人们需要的较为完善功能集合,所以这里我们把 Hive ACID 纳入到对比行列中。


第一、ACID 和隔离级别支持


这里主要解释下,对数据湖来说三种隔离分别代表的含义。


  1. Serialization 是说所有的 reader 和 writer 都必须串行执行;

  2. Write Serialization: 是说多个 writer 必须严格串行,reader 和 writer 之间则可以同时跑;

  3. Snapshot Isolation: 是说如果多个 writer 写的数据无交集,则可以并发执行;否则只能串行。Reader 和 writer 可以同时跑。


综合起来看,Snapshot Isolation 隔离级别的并发性是相对比较好的。


第二、Schema 变更支持和设计


这里有两个对比项,一个是 schema 变更的支持情况,我的理解是 Hudi 仅支持添加可选列和删除列这种向后兼容的 DDL 操作,而其他方案则没有这个限制。另外一个是数据湖是否自定义 schema 接口,以期跟计算引擎的 schema 解耦。这里 Iceberg 是做的比较好的,抽象了自己的 schema,不绑定任何计算引擎层面的 schema。


第三、流批接口支持


目前 Iceberg 和 Hive 暂时不支持流式消费,不过 Iceberg 社区正在 issue 179 上开发支持。


第四、接口抽象程度和插件化


这里主要从计算引擎的写入和读取路径、底层存储可插拔、文件格式四个方面来做对比。


Iceberg 是抽象程度做得最好的数据湖方案,四个方面都做了非常干净的解耦。Delta 是 databricks 背后主推的,必须天然绑定 Spark;Hudi 的代码跟 Delta 类似,也是强绑定 Spark。存储可插拔的意思是说,是否方便迁移到其他分布式文件系统上(例如 S3),这需要数据湖对文件系统 API 接口有最少的语义依赖,例如若数据湖的 ACID 强依赖文件系统 rename 接口原子性的话,就难以迁移到 S3 这样廉价存储上,目前来看只有 Hive 没有太考虑这方面的设计;文件格式指的是在不依赖数据湖工具的情况下,是否能读取和分析文件数据,这就要求数据湖不额外设计自己的文件格式,统一用开源的 parquet 和 avro 等格式。这里,有一个好处就是,迁移的成本很低,不会被某一个数据湖方案给绑死。


第五、查询性能优化


第六、其他功能


这里 One line demo 指的是,示例 demo 是否足够简单,体现了方案的易用性,Iceberg 稍微复杂一点(我认为主要是 Iceberg 自己抽象出了 schema,所以操作前需要定义好表的 schema)。做得最好的其实是 Delta,因为它深度跟随 Spark 易用性的脚步。


Python 支持其实是很多基于数据湖之上做机器学习的开发者会考虑的问题,可以看到 Iceberg 和 Delta 是做的很好的两个方案。


出于数据安全的考虑,Iceberg 还提供了文件级别的加密解密功能,这是其他方案未曾考虑到的一个比较重要的点。


第七、社区现状(截止到 2020-01-08)


这里需要说明的是,Delta 和 Hudi 两个项目在开源社区的建设和推动方面,做的比较好。Delta 的开源版和商业版本,提供了详细的内部设计文档,用户非常容易理解这个方案的内部设计和核心功能,同时 Databricks 还提供了大量对外分享的技术视频和演讲,甚至邀请了他们的企业用户来分享 Delta 的线上经验。Uber 的工程师也分享了大量 Hudi 的技术细节和内部方案落地,研究官网的近 10 个 PPT 已经能较为轻松理解内部细节,此外国内的小伙伴们也在积极地推动社区建设,提供了官方的技术公众号和邮件列表周报。Iceberg 相对会平静一些,社区的大部分讨论都在 Github 的 issues 和 pull request 上,邮件列表的讨论会少一点,很多有价值的技术文档要仔细跟踪 issues 和 PR 才能看到,这也许跟社区核心开发者的风格有关。


总结

我们把三个产品(其中 Delta 分为 databricks 的开源版和商业版)总结成如下图:



如果用一个比喻来说明 Delta、Iceberg、Hudi、Hive-ACID 四者差异的话,可以把四个项目比做建房子。由于开源的 Delta 是 Databricks 闭源 Delta 的一个简化版本,它主要为用户提供一个 table format 的技术标准,闭源版本的 Delta 基于这个标准实现了诸多优化,这里我们主要用闭源的 Delta 来做对比。



Delta 的房子底座相对结实,功能楼层也建得相对比较高,但这个房子其实可以说是 Databricks 的,本质上是为了更好的壮大 Spark 生态,在 Delta 上其他的计算引擎难以替换 Spark 的位置,尤其是写入路径层面;Iceberg 的建筑基础非常扎实,扩展到新的计算引擎或者文件系统都非常的方便,但是现在功能楼层相对低一点,目前最缺的功能就是 upsert 和 compaction 两个,Iceberg 社区正在以最高优先级推动这两个功能的实现;Hudi 的情况要相对不一样,它的建筑基础设计不如 iceberg 结实,举个例子,如果要接入 Flink 作为 Sink 的话,需要把整个房子从底向上翻一遍,把接口抽象出来,同时还要考虑不影响其他功能,当然 Hudi 的功能楼层还是比较完善的,提供的 upsert 和 compaction 功能直接命中广大群众的痛点。Hive 的房子,看起来是一栋豪宅,绝大部分功能都有,把它做为数据湖有点像靠着豪宅的一堵墙建房子,显得相对重量级一点,另外正如 Netflix 上述的分析,细看这个豪宅的墙面是其实是有一些问题的。


2020 年 3 月 19 日 11:088892

评论 1 条评论

发布
用户头像
delta支持并发写,hudi目前还不支持并发写吧
2020 年 12 月 31 日 17:41
回复
没有更多了
发现更多内容

情报研判分析可视化平台建设方案,重点人员管控系统开发

WX13823153201

浅谈BSS3.0产品“守成”之策上 • 架构提升篇

鲸品堂

运维 性能 架构·

翻译:《实用的Python编程》09_01_Packages

codists

Python

如何利用ipad随时随地开发代码

有理想的coder

ipad 编程 远程

这份阿里P8大佬手写的 “Java核心面试精选” 疯传阿里内网

码农之家

Java 编程 程序员 互联网 面试

【详解文件IO系列】讲讲 MQ 消息中间件 (Kafka,RocketMQ等)与 MMAP、PageCache 的故事

Linux服务器开发

网络编程 Linux服务器开发 底层实现原理 网络io C++后端开发

5分钟教你学会GaussDB数据分布策略设计

华为云开发者社区

数据库 分布式数据库 GaussDB GaussDB(for openGauss) 数据分布

与同事组队,用 3s 把工作节点打通,建立信赖与协作关系。

叶小鍵

【LeetCode】删除排序链表中的重复元素Java题解

HQ数字卡

算法 LeetCode 4月日更

Rust从0到1-枚举-match控制流

rust 枚举 match

​量化交易机器人系统开发,量化策略交易平台搭建

WX13823153201

量化合约交易机器人系统开发|量化合约交易机器人APP软件开发

开發I852946OIIO

系统开发

让GitHub低头的10W字阿里内部Java面试手册有多强?

周老师

Java 编程 程序员 架构 面试

十大经典系统架构设计面试题

有理想的coder

架构 面试 架构设计 架构面试

1分钟get什么是训练数据

澳鹏Appen

人工智能 机器学习 数据集 人工智能大数据

微擎的日志文件保存在哪里?如何查看。

微擎应用商城

牛客网官推!3天访问量直接破20W的Java高频面试汇总笔记太香了!

程序员小毕

Java 程序员 架构 面试 分布式

人生向前

shun123456789

量化合约机器人APP开发|量化合约机器人软件系统开发

开發I852946OIIO

系统开发

Adobe国际认证,Photoshop软件调整图层大小,官方教程

Adobe国际认证

Adobe国际认证

Kafka源码阅读笔记(1)

InfoQ_Springup

kafka

数字货币自动交易机器人APP开发|数字货币自动交易机器人软件系统开发

开發I852946OIIO

系统开发

从能耗大户“变身”智能绿色办公,只需一步到位!

IoT云工坊

物联网 API sdk 办公空间 智能转型

技术团队内部管理思考

6:00 am

技术管理

阿里被转载上100W次的Java面试题教程!已助我拿下9家大厂offer

周老师

Java 编程 程序员 架构 面试

金三银四期间获千万下载量!阿里大牛熬夜45天整理出来的Java面试突击手册也太香了!

Java王路飞

Java spring 程序员 架构 面试

百度联合清华,全球首个十亿像素数据集来了!

百度大脑

人工智能 百度

Google Analytics

曦语

数据分析

11 个非常实用的 Python 和 Shell 拿来就用脚本实例!

JackTian

Python Shell linux运维 脚本语言 程序员编程

合约跟单交易系统开发量化策略

薇電13242772558

数字货币

阿里内部流传的JDK源码剖析手册!GitHub已获上千万的访问量

周老师

Java 编程 程序员 架构 面试

深度对比Delta、Iceberg和Hudi三大开源数据湖方案-InfoQ