基于 EMR 的新一代数据湖存储加速技术详解

摘要:本文整理自阿里云开源大数据平台数据湖存储团队孙大鹏在 7 月 17 日阿里云数据湖技术专场交流会的分享。本篇内容主要分为两个部分:
背景介绍
JindoData 数据湖存储解决方案
背景介绍

大数据行业蓬勃发展,主要源自于通讯技术的发展,全球数据规模,预计 2025 年将增长到 163ZB,相当于全球 60 亿人,平均每人 27TB 数据。数据量爆发式增长,使得企业拥有了更多数据资源。更多数据意味着需要更大的存储。此外,数据本身极具价值,因此要挖掘数据价值并进行充分利用,以此反向推动业务的发展和改造。

大数据技术的发展趋势是云化、轻量化、服务化。数据湖、与云融合、实时计算已经成为大数据领域的关键词。存算分离概念在云计算早期已被提出。存储与计算耦合的自建平台会造成额外成本,且受限于本地网络带宽。有了云计算以后,网络带宽得到了很大缓解。可以按量收费,提供服务化、容器化的能力,更好地做运维开发。
业界存储架构演进

早期的大数据基于 HDFS 构建数仓。 HDFS 是非常好的分布式存储选型,单集群可稳定支撑到 4-6 亿文件规模,数据量可达 100 PB 。但是 HDFS 运维成本比较高,存储作为基础组件,一旦存储出现问题,则意味着整个业务被中断。此外,达到 4-6 亿文件规模,100PB 数据量后,再进行扩展则会出现问题。
因此,社区提出了 HDFS Federation 方案。将 HDFS 集群进行扩展,并将业务进行拆分,大业务可以独立使用一组 NameNode,可突破单组 NameNode JVM 的限制,实现了 HDFS 元数据和容量的横向扩展。此外,社区开发了 NS Router 组件,帮助更好地使用 HDFS 元数据。
随着 HDFS 的扩展,其运维成本也成倍增加。业界开始选择利用对象存储的高可用、高吞吐,基于云上对象存储构建数据湖。每个云厂商都会从设计到运维上投入大量人力、物力保证对象存储可靠、稳定、高效。
从存算一体到云原生数据湖

开源大数据平台经历了几次大的演进。
第一代开源大数据平台 EMR,为更好地将 Hadoop 搬到云上提供了基础运维。在线下使用物理机,在云上使用 ECS 本地盘机型,即可实现与物理机近似的存储能力和成本。其特点为将线下 IDC 集群搬上云,可以通过云简化集群部署和扩容,但不解决 HDFS 的上线、运维等问题。
第二代开源大数据平台 EMR 将 OSS 和 S3 对象存储作为 storage connector 引入集群。当存储集群达到一定规模后,温数据、冷数据可以转存到 OSS 或 S3 对象存储,进一步降低存储成本。
第三代开源大数据平台的特点为本地集群基本不保留任何元数据,而是保留在云上。DLF 使用 Table 替代了 Hive Metastore 元数据方案,表的元数据通过云服务托管,利用 OSS 做存储,使集群基本实现无状态。因此,用户只需创建好集群即可使用资源,体验极佳。且可以对接更多存储引擎,互相之间能够实现隔离,比如离线、在线可以利用云上元数据和存储实现集群分离。
数据湖存储演进之路

数据湖存储的演进主要也分为三个阶段:
数据湖 1.0:存算分离架构,冷热分层,以 Hadoop 生态为主。
数据湖 2.0:以对象存储为中心,统一存储承载生产业务、大规模、高性能。
数据湖 3.0:以对象存储为中心,构建企业数据湖全兼容、多协议、统一元数据。
JindoData 数据湖存储解决方案

经过不断演化,最终实现了 JindoData 数据湖存储解决方案。JindoData 是存储加速项目。JindoFS 存储系统构建在 OSS 之上,提供了文件元数据功能和目录功能,可以和 NameNode 进行比对,解决了对象存储在模拟文件系统时的操作比如 rename 等问题。Jindo FSx 是存储加速系统,负责解决带宽问题。客户端或计算集群侧有存储资源,如果都通过网络,则延时、效率与 HDFS 存在差距,经过不断地放大后,用户会逐渐感受到性能差距。因此需要 Jindo FSx 存储加速系统来解决带宽和延时问题。
基于以上两大核心系统,我们对上层提供了 HDFS API 和 POSIX API ,两个 API 基本可以满足大数据平台上对存储的使用需求,Flink 、Hadoop 、Spark 等大数据相关组件可以直接通过相关 API 方便地接入。比如当前新兴的 AI 训练可以将中间结果、TFRecord 等通过 POSIX API 存到对象存储系统里。
JindoSDK 生态工具解决了和生态对接问题,比如与计算对接、本地 POSIX 挂载。JindoDistCP 解决从 OSS 和 HDFS 之间的数据迁移,JindoTable 能够以表粒度做迁移,JindoShell 能够帮助我们更好地使用对象存储。
底层数据源可以对接 HDFS、对象存储、NAS 以及阿里云 OSS。

JindoSDK:超级数据湖 SDK

JindoSDK 是对接生态的重要 SDK,上层可以对接各种引擎,下层对接各种存储。通常,很多组件和存储都是基于烟囱式开发,导致 SDK 能力规格存在很大偏差。因此我们重点打造了 Native Core 层,使用 C++ 语言开发,对上层抽象出了 ObjectStore API 、DataStream API 和 FileSystem API。 通过 Cython 对接 Python SDK, 通过 JNI 对接 Hadoop SDK,通过 C SDK 对接 Jindo Fuse,使上层所有计算引擎都可以使用相同的一套原生 SDK。因此,SDK 层面改进后,上层全链路都可以享受 SDK 改进带来的收益,比如文件系统元数据操作优化、IO 路径的读写优化、安全、灵活的 STS 配置策略等。
ObjectStore 是对象存储的接口,OSS、S3 都可以归结到 ObjectStore 内部 API。上图左下角为 Jindo Native SDK 和 OSS Java SDK 的性能对比,可以看到 Jindo SDK 性能平均提升 2.2 倍。

Hadoop SDK 访问 OSS ,性能也可以得到全面提升。几个 SDK 广泛应用在 EMR 生产集群,其稳定性等性能都已经过阿里云上的产品验证。
JindoFS:构建在 OSS 上的高性能存储系统

JindoFS 重点解决了超大规模 HDFS 存储集群的挑战,比如单组 NameNode 架构存在容量限制,如果想突破容量限制,必须投入极高的运维成本,需要运维十多个服务包括 NameNode、ZKFC 、ZK、JN;同时,元数据运维重启时间可高达几个小时,参数调优、JVM GC、全局锁等问题也存在挑战。除此之外,DataNode 做节点上下线、集群节点替换、HDFS 内部 balancer 等都需要解决。

早期,受限于当时的技术,使用 QJM 架构来解决上述痛点。而随着 Raft 在业界广泛推广和使用,JindoFS 选择基于 Raft 架构建元数据,内部只需三个 NamespaceService 节点,避免了 HDFS 大量服务部署。
运维成本上,实现了分钟级重启。通过 C++语言开发,性能非常好。基于 OSS 存储,可以大大简化顶层设计,服务也更高效,且本地 block 可以用作缓存。

半托管的 JindoFS 通过这套元数据可以解决 HDFS 的运维复杂度以及 OSS 接口的损耗,满足用户“对系统稳定可靠、运维简单、节省成本;对象存储数据湖和 HDFS 相比性能只好不差”的需求。

随着 JindoFS 半托管的深入使用,我们发现即使运维简单,但因为需要为用户在半托管上部署一套服务,也会给用户带来一定的运维成本。因此我们实现了基于云原生容器化和存储服务化的 JindoFS 数据湖 3.0 架构,
数据层面, OSS 服务可以提供两层 API ,分别是对象 API 和目录 API,通过两套 API 组合使用,可以基本满足所有高性能元数据和存储需求。客户实际部署时,可以将 SDK 以及 JindoFSx 加速等组件部署在线下、容器或 ECS 里,使容器上的组件也可以更好地使用云上服务。

JindoFS 使用了对象存储作为底层存储,因此可以实现冷热分层,可以根据对象文件生命周期的不同,选择标准型、低频型、归档型和冷归档型四种模式,最大程度地节省成本。归档类型适合长期存储但可能很长时间不读的数据,低频适合读得比较少的数据。
JindoFSx:高性能/性价比的存储加速系统

JindoFSx 缓存加速系统部署在 worker 上。很多对象存储远端有一定的网络开销,而如果全走网络请求,会导致延时增加。IO 越短,GPU 机器成本也可以发挥到最大。JindoFSx 可以在内部进行分层,能够对本地存储资源进行管理。通过 JindoSDK 对上层对接了各种 ETL、交互式分析、实时计算、机器学习等组件,底层可以对接不同数据源。比如阿里云上可能要访问其他云的对象存储,带宽性能上可能无法满足高性能查询的需求。但部署 JindoFSx 以后,对数据进行缓存、预热即可基本满足存储需求。

JindoFSx 实现了分布式缓存架构,包括 Namespace、Storage,上层有一套 NameSpaceService 服务做文件元数据层面的加速,通过文件系统接口暴露给 JindoSDK,供上层应用使用,以此解决 IO 密集、带宽受限、远端数据访问的问题。
生态工具和场景

上图为数据湖存储对接计算引擎的大图,通过 OSS 可以方便地对接各种服务和存储。

我们在数据流层面做了异步数据预读、复用,使得读取 Parquet/ORC 格式时可以实现高效寻址,利用缓存使数据读取更高效。

对象存储上的 rename 操作比较重,因此我们设计了 JindoCommitter,基于对象存储系统的 Multiple Upload,结合 OSS 文件系统层面的定制支持,可以实现在保证数据一致性前提下无需 rename 操作的 Job Committer。在 OSS 上运行作业时,只要加上 Jindocommitter ,即可同时保证 Hadoop V1 版本的事务性和 Hadoop V2 版本的高性能。

目录 rename 的优化提供了针对 EMR 优化前缀重命名接口,目录 rename 降低到毫秒级并保证原子性。另外,我们支持了 fast copy,对比大部分对象存储对于 object 的 copy 操作需要将数据进行真实拷贝, fast copy 只需在内部做一次索引转换,避免了数据真实拷贝。

很多数据湖引擎是基于文件系统原子 rename 特性设计的,即对象如果已经存在,则不能被二次覆盖。对于这个重要特性,我们在 OSS 上做了重点支持。首先,OSS 是一个强一致性存储,比如向 bucket 里写入 object,如果没有强一致的保证,在 list 时可能无法获取到最新的对象。其次,对象存储的 rename 是 Key 覆盖, Key 级别对象不会检查文件是否存在。而数据湖场景下,原子 rename 特性,我们实现了两种方案:在 SDK 层面基于 OTS 构建原子 Rename 的能力。同时进行深度优化后,已经可以实现 OSS 原生原子性 rename 支持,不依赖任何外部服务,可以在文件做 copy 时进行强一致的检测。

对象存储是不支持 Flush 的,而像 Flink、Flume 这类引擎对 Flush 的依赖是比较重的,我们在对象存储上也做了深度优化,虽然不能保证完整的 Flush 语义,即数据 Flush 以后立刻可见,但是可以保证 Flush 以后数据不丢,对于 Flume 层面来说已经完全满足实际使用需求。 Flink 里使用了 MPU 接口,实现了 recoverable writer 的可恢复写入。

数据湖生态的 JindoTable 是专门为结构化数据设计一套工具集,可以帮助降低存储成本和维护成本。

JindoTable 可以以表维度做数据冷热转换。比如表存在 OSS 或 HDFS 上,可以通过 JindoTable 操作 Hive MetaStore 等的数据,可以按照 DB 级别、表级别、前缀级别做生命周期转换,可以很方便地进行冷热数据统计,并按特点进行数据分层操作。

Hadoop 原生 DistCP 在对象存储和 HDFS 同步数据会存在一些问题,比如拷贝策略、存储类型、数据校验等支持。JindoDistCP 重点解决这类问题:JindoDistCP 上实现了异构 checksum 比对,HDFS 和对象存储的 checksum 算法是不同的,传统的做法无法将 HDFS 和对象直接做 checksum 比对,在 JindoDistCP 里进行了透明的 checksum 转换,保证了写入和传输过程中的数据准确性。
此外,我们对 JindoDistCP 的内核也进行了重新优化,实现了动态拷贝,类似抢占式拷贝的方式,大文件和小文件可以快速同时并行,带宽利用率大幅提高。
问答
Q:JindoFS 和 HDFS 性能数据对比如何?
A:后续会逐步发布测试数据,JindoFS 本身设计上有一定优势。在 HDFS 里做 rename、delete 等操作,特别是对大目录进行操作时,会存在大量的加锁和检查操作。随着文件数量变大,时间也会递增;这些操作在 JindoFS 上的时间是稳定的。
Q:JindoFS 只有三个节点,最大能够支持多大文件数量?
A:早期版本是一般是三节点组 raft,这种模式可以稳定支持十亿级别,相比于 HDFS 有两倍的提升。现在的 3.0 云原生架构下,用户通过 endpoint 访问,元数据服务可以在内部进行横向扩展。
Q:JindoFS 和 Alluxio 的对比?
A:JindoFS 是元数据的管理和优化,Alluxio 是一套开源分布式缓存加速服务,其功能定位与 JindoFSx 比较接近。Alluxio 主打开源,Jindo 在对象存储上做了较多优化,加上 Native 底层,理论上性能会有一定优势。
Q:HDFS 上 k8s 场景是否有具体的实践?
A:HDFS 是一个存储引擎,每个存储节点是有状态的。HDFS 部署在 k8s 节点也需要重度的运维,比如释放需要首先进行 HDFS Decommission 操作,要日常对节点进行 balance 等,k8s 部署 HDFS 无明显优势。
更多信息:
产品官网
[1] 数据湖构建 Data Lake Formation:https://www.aliyun.com/product/bigdata/dlf
[2] 开源大数据平台 EMR: https://www.aliyun.com/product/emapreduce
[3] 大数据知识图谱: https://developer.aliyun.com/learning/topic/bigdata
数据湖系列
[1] 数据湖揭秘—Delta Lake: https://developer.aliyun.com/article/909818
[2] 数据湖构建—如何构建湖上统一的数据权限: https://developer.aliyun.com/article/918403
[3] 关于 Data Lake 的概念、架构与应用场景介绍:https://developer.aliyun.com/article/944650
[4] 数据湖架构及概念简介:
https://developer.aliyun.com/article/1004847
[5] 数据湖统一元数据和权限
https://developer.aliyun.com/article/1008235
[6] 数据湖管理及优化
https://developer.aliyun.com/article/1023298
更多 数据湖 相关技术问题,可扫码加入钉钉交流群~

评论