初识数据湖

对于数据湖的入门者,本文记录一下对数据湖的初步认识。

概念

数据湖是个什么概念呢?一般来说把一家企业产生的数据维护在一个平台内,这个平台我们称之为“数据湖”。

个人认为数据湖应该是一种不断演进中、可扩展的大数据存储、处理、分析的基础设施。以数据为导向,实现任意来源、任意规模、任意类型数据的全量获取、全量存储、多模式处理与全生命周期管理;并通过与各类外部异构数据源的交互集成,支持各类企业级应用。

看下面这幅图,这个湖的数据来源多种多样,有的可能是结构化数据,有的可能是非结构化数据,有的甚至是二进制数据。有一拨人站在湖的入口,用设备在检测水质,这对应着数据湖上的流处理作业;有一拨抽水机从湖里抽水,这对应着数据湖的批处理作业;还有一批人在船头钓鱼或者在岸上捕鱼,这对应着数据科学家从数据湖中通过机器学习的手段提取价值。

总结起来,数据湖主要有 4 个方面的特点:

  • 存储原始数据,这些原始数据的来源非常丰富
    结构化数据
    半结构化数据
    非结构化数据
    二进制数据(图片等)

  • 支持多种计算模型
    批处理
    流计算
    交互式分析
    机器学习

  • 有完善的数据管理能力
    能做到多种数据源接入
    时间不同数据之间的连接
    支持 Schema 管理
    支持权限管理

  • 灵活的底层存储
    一般用 S3/OSS/HDFS 这种廉价的分布式文件系统
    支持 Parquet/Avro/Orc 文件格式
    支持数据缓存加速
    满足对应场景的数据分析需求

那么,开源的数据湖架构一般是什么样的呢?一般分为四层:

  • 最底层是廉价、弹性可扩展的分布式文件系统,云上用户 S3 和 OSS 这种对象存储用的更多一些,毕竟价格便宜很多;非云上用户一般采用自己维护的 HDFS。
  • 第二层是数据加速层。提供本地数据缓存(多块 SSD)和元数据加速服务。数据湖架构是一个存储计算彻底分离的架构,如果所有的数据访问都远程读取文件系统上的数据,那么性能和成本开销很大。如果能把经常访问到的一些热点数据缓存在计算节点本地,这就非常自然的实现了冷热分离,一方面能获取到不错的本地读取性能,另一方面还节省了远程访问的带宽。这一层里边,通常会选择开源的 alluxio,或者选择阿里云上的 Jindofs。
  • 第三层就是 Table Format 层,提供面向用户的主表级语义。要是把一些数据文件封装成一个有业务语义的 table,提供 ACID、snapshot、schema、partition 等表级别的语义。一般对应着开源的 Delta、Iceberg、Hudi 等项目。对一些用户来说,他们认为 Delta、Iceberg、Hudi 这些就是数据湖,其实这几个项目只是数据湖这个架构里边的一环,只是因为它们离用户最近,屏蔽了底层的很多细节,所以才会造成这样的误解。数据湖和数据中台一样,是一种架构理念,而不是专指某一个技术。
  • 最上层就是不同计算场景的计算引擎了,满足不同的分析需求。开源的一般有 Spark、Flink、Hive、Presto、Hive MR 等,这一批计算引擎可以同时访问同一张数据湖的表。

数据湖 vs 数据仓库

比较数据来源于 AWS。

特性 数据仓库 数据湖
数据 来自事务系统、运营数据库和业务线应用程序的关系数据 来自 IoT设备、网站、移动应用程序、社交媒体和企业应用程序的非关系和关系数据
Schema 设计在数据仓库实施之前(写入型Schema) 写入在分析时(读取型Schema)
性价比 更快查询结果会带来较高存储成本 更快查询结果只需较低存储成本
数据质量 可作为重要事实依据的高度监管数据 任何可以或无法进行监管的数据(例如原始数据)
用户 业务分析师 数据科学家、数据开发人员和业务分析师(使用监管数据)
分析 批处理报告、BI和可视化 机器学习、预测分析、数据发现和分析

Flink数据湖业务场景

场景一: 构建实时Data Pipeline

首先,Flink+Iceberg 最经典的一个应用场景就是构建实时的 Data Pipeline。业务端产生大量的日志数据,被导入到 Kafka 这样的消息队列,运用 Flink 流计算引擎执行 ETL 后,导入到 Apache Iceberg 原始表中。有一些业务场景需要直接跑分析作业来分析原始表的数据,而另外一些业务需要对数据做进一步的提纯,那么我们可以再起一个 Flink 作业从 Apache Iceberg 表中消费增量数据,经过处理之后写到到提纯之后的 Iceberg 表中。此时,可能还有业务需要对数据做进一步的聚合,那么我们继续在 Iceberg 表上启动增量 Flink 作业,将聚合之后的数据结果写入到聚合表中。

有人可能会提出质疑,这个场景好像通过 Flink+Hive 也能实现。Flink+Hive 的确可以实现,但写入到 Hive 的数据更多的是为了实现数仓的数据分析,而不是为了做增量拉取。一般来说,Hive 的增量写入是以 partition 为单位,时间是 15min 以上,Flink 长期高频率地写入会造成 partition 膨胀。而 Iceberg 允许实现 1min 甚至 30s 的增量写入,这样就可以大大提高了端到端数据的实时性,上层的分析作业可以看到更新的数据,下游的增量作业也可以读取到更新的数据。

  • 核心优势:
    可以借助 Flink 实现数据 exactly-once 语义地入湖和出湖
    新写入数据可以在 checkpoint 周期内可见
    可以方便地构建 data pipeline,满足不同业务层的数据加工和分析需求

  • 对比 Hive 方案:
    hive 的增量写入以 partition 为单位,长期高频率的 checkpoint 写入,会导致 hive partition 的膨胀
    本质上 hive 的增量写入和消费粒度都太大,实时性无法比肩 iceberg

场景二: CDC数据实时摄入摄出

第二个经典的场景,就是可以用 Flink+Iceberg 分析来自 MySQL 等关系型数据库的 binlog 等。

一方面,Flink 已经原生的支持 CDC 数据解析,一条 binlog 数据通过 flink-cdc-connector 拉取之后,自动转换成 Flink runtime 能识别的 insert、delete、update_before、update_after 四种消息,供用户进一步的实时计算。

另一方面,Iceberg 已经较为完善的实现了 equality delete 功能,也就是用户定义好到删除的 record,直接写到 Iceberg 表内就可以删除对应的行,本身就是为了实现数据湖的流式删除。在 Iceberg 未来的版本中,用户将不需要设计任何额外的业务字段,不用写几行代码就可以完成 binlog 流式入湖到 Iceberg (社区 PR 已经提供了一个 Flink 写入 CDC 数据的原型)。

此外,CDC 数据成功入湖 Iceberg 之后,常见的计算引擎 Presto、Spark、Hive 等,都可以实时的读取到 Iceberg 表中最新的数据。

场景三: 近实时场景的流批统一

第三个经典场景是近实时场景的批流统一。在常用的 lambda 架构中,有一条实时链路和一条离线链路。实时链路一般由 Flink、Kafka、HBase 这些组件构建而成,离线链路一般会用到 Parquet、Spark等组件。这里边涉及到的计算组件和存储组件非常多,系统维护成本和业务开发成本都非常高。有很多场景,它们的实时性要求并没有那么苛刻,例如可以放松到分钟级别,这种场景我们称之为近实时场景。那么,我们是不是可以通过 Flink+Iceberg 来优化我们常用的 lambda 架构呢?

我们可以用 Flink+Iceberg 把整个架构优化成上图所示。实时的数据通过 Flink 写入到 Iceberg 表中,近实时链路可以通过 Flink 计算增量数据,离线链路也可以通过 Flink 批计算读取整个快照做全局分析,得到对应的分析结果,供不同场景下的用户读取和分析。经过这种改进之后,我们把计算引擎统一成了 Flink,把存储组件统一成了 Iceberg,整个系统的维护开发成本大大降低。

第四个场景,是采用 Iceberg 全量数据和 Kafka 的增量数据来 Bootstrap 新的 Flink 作业。我们现有的流作业在线上跑着,突然有一天某个业务方跑过来说,他们遇到一个新的计算场景,需要设计一个新的 Flink 作业,跑一遍去年一年的历史数据,跑完之后再对接到正在产生的 Kafka 增量数据。那么,这时候应该怎么办呢?

我们依然可以采用常见的 lamnda 架构,实时链路通过 Kafka -> Flink -> Iceberg 实时写入到数据湖,由于 Kafka 成本较高,保留最近 7 天数据即可,Iceberg 存储成本较低,可以存储全量的历史数据(按照 checkpoint 拆分成多个数据区间)。启动解析 Flink 作业的时候,只需要去拉取 Iceberg 的数据,跑完之后平滑的对接到 Kafka 数据即可。

场景五: 通过 Iceberg 数据来订正实时聚合结果

第五个场景,和第四个场景类似。同样是在 lambda 架构下,实时链路由于事件丢失或者到达顺序的问题,可能导致流计算结果不一定完全准确,这时候一般都需要全量的历史数据来订正实时计算的结果。而 Iceberg 可以很好的充当这个角色,因为它可以高性价比的管理好历史数据。

Why Iceberg

Delta vs Hudi vs Iceberg

Items Open Source Delta Apache Iceberg Apache Hudi
Open Source Time 2019/04/12 2018/11/06(incubation) 2019/01/17(incubation)
Github Star 2800+ 692 1400+
Releases 5 5 48
ACID Yes Yes Yes
Isolation Level Write/Snapshot serialization Write serialization Snapshot serialization
Time Travel Yes Yes Yes
Row-level DELETE(batch) Yes Ongoing No
Row-level DELETE(streaming) No Ongoing Yes
Abstracted Schema No Yes No
Engine Pluggable No Yes No
Open File Format Yes Yes Yes(Data) + No(Log)
Filter push down No Yes No
Auto-Compaction No Ongoing Yes
Python support Yes Yes No
File Encryption No Yes No
  1. Iceberg 的设计和 Flink 数据湖的需求最匹配
  • 完美解耦计算引擎和文件格式两层,便于接入多样化的计算引擎和文件格式
  • 正确的完成了 Table Format这一层的功能需求
  • 更容易成为 Table Format 层的事实标准
  1. 两个项目的长远规划相似
  • Apache Iceberg:打造流批一体的数据湖存储层
  • Apache Flink:打造流批一体的计算引擎
  • 两者合力打造流批一体的数据湖架构
  1. 强大的社区资源
  • Apache Iceberg 始自 Netflix。Netflix 最早是 All In Cloud 的互联网巨头之一,也是最早在线上生产环境运行 Flink/Spark+Iceberg 这套数据湖方案的公司
  • 支撑着 Apple、LinkedIn、Adobe、腾讯、网易等多家互联网巨头 PB 级的生产数据
  • 严苛的文档审核、代码审核及测试设计。拥有来自其他 Apache项目的1个VP、7个PMC、4个Committer

Delta 和 Hudi 跟 Spark 的代码路径绑定太深,尤其是写入路径。毕竟当时这两个项目设计之初,都多多少少把 Spark 作为它们默认的计算引擎了。而 Apache Iceberg 非常坚定,总值就是要做一个通用化设计的 Table Format。因此它完美的解耦了计算引擎和底下的存储系统,便于多样化计算引擎和文件格式,可以说正确的完成了数据湖架构中的 Table Format 这一层的实现。我们认为它也更容易成为 Table Format 层的开源事实标准。

另一方面,Apache Iceberg 正在朝着批流一体的数据湖存储层发展, manifest 和 snapshot 的设计,有效的隔离不同 transaction 的变更,非常方便批处理和增量计算。而我们知道 Apache Flink 已经是流批一体的计算引擎,可以说这二者的长远规划完美匹配,未来二者将合力打造流批一体的数据湖架构。

最后,我们还发现 Apache Iceberg 这个项目背后的社区资源非常丰富。在国外,Netflix、Apple、Linkedin、Adobe 等公司都有 PB 级别的生产数据运行在 Apache Iceberg 上;在国内,腾讯这样的巨头也有非常庞大的数据跑在 Apache Iceberg 之上,他们最大的一个业务每天有几十T的增量数据写入到 Iceberg。社区成员同样非常资深和多样化,拥有来自其他项目的 7 位 Apache PMC,1位 VP。在代码和设计的 review 上,也非常苛刻,一个稍微大点的 PR 涉及 100+ 的 comment 很常见,这些都使得 Apache Iceberg 的设计+代码质量比较高。

正是基于以上考虑,Apache Flink 最终选择了 Apache Iceberg 作为第一个数据湖接入项目。

数据湖基本架构

上图所示是一个数据湖系统的参考架构。对于一个典型的数据湖而言,它与大数据平台相同的地方在于它也具备超大规模数据所需的存储和计算能力,能提供多模式的数据处理能力;增强点在于数据湖提供了更为完善的数据管理能力,具体体现在:

  • 更强大的数据接入能力
    对各类异构数据源的定义管理能力,以及对于外部数据源相关数据的抽取迁移能力,抽取迁移的数据包括外部数据源的元数据与实际存储的数据。

  • 更强大的数据管理能力
    可分为基本管理能力和扩展管理能力。基本管理能力包括对各类元数据的管理、数据访问控制、数据资产管理,是一个数据湖系统所必须的。扩展管理能力包括任务管理、流程编排以及数据质量、数据治理相关的能力。任务管理和流程编排主要用来管理、编排、调度、监测在数据湖系统中处理数据的各类任务,通常情况下,数据湖构建者会通过读取数据湖的相关元数据,来实现与数据湖系统的融合。而数据质量和数据治理则是更为复杂的问题,一般情况下,数据湖系统不会直接提供相关功能,但是会开放各类接口或元数据,供有能力的企业/组织与已有的数据治理软件集成或者做定制开发。

  • 可共享的元数据
    数据湖中的各类计算引擎会与数据湖中的数据深度融合,而融合的基础就是数据湖的元数据。好的数据湖系统,计算引擎在处理数据时,能从元数据中直接获取数据存储位置、数据格式、数据模式、数据分布等信息,然后直接进行数据处理,而无需进行人工/编程干预。更进一步,好的数据湖系统还可以对数据湖中的数据进行访问控制,控制的力度可以做到“库表列行”等不同级别。

“集中式存储”更多的是业务概念上的集中,本质上希望一个企业组织内部能在一个明确统一的地方进行沉淀。事实上,数据湖的存储应该是一类可按需扩展的分布式文件系统,大多数数据湖实践中也是推荐采用 S3/OSS/HDFS 等分布式文件系统作为数据湖的统一存储。

各个厂商的数据湖解决方案

AWS

华为

阿里云

Azure

参考资料

“新晋网红”数据湖到底该如何理解?
基于 Flink+Iceberg 构建企业级实时数据湖 - 文章
基于 Flink+Iceberg 构建企业级实时数据湖 - 视频
阿里云 云原生数据湖分析 DLA 帮助文档