写点什么

存储系统如何适配 Hadoop?

作者:焱融科技
  • 2022 年 5 月 24 日
  • 本文字数:1988 字

    阅读完需:约 7 分钟

存储系统如何适配 Hadoop?

近年来,Hadoop 相关的大数据框架非常成熟,应用广泛。与此同时,Hadoop 默认的存储组件 HDFS 开始逐渐暴露出自己的短板:存算一体带来的资源不匹配,NameNode 的扩展瓶颈等等。


因此,Hadoop 的存算分离成为了热门趋势。使用者开始用对象存储、分布式文件存储等存储产品,来替代 HDFS,在规避了 HDFS 的同时,又能利用好其他存储系统的优势特性。


那么,存储系统应该如何适配 Hadoop 呢?

官方指南

1、适配方案


目前,Hadoop 官方给出的存储兼容方案,主要有两个文档:


HCFS (https://cwiki.apache.org/confluence/display/HADOOP2/HCFS)


文档中定义了分布式文件系统适配 Hadoop 的两种方式:


All such filesystems (including HDFS) must link up to Hadoop in two ways.

  1. The filesystem looks like a "native" filesystem, and is accessed as a local FS, perhaps with some filesystem-specific means of telling the MapReduce layer which TaskTracker is closest to the data.

  2. The filesystem provides an implementation of the org.apache.hadoop.fs.FileSystem class (and in Hadoop v2, in implementation of the FileContext class}


即:

  1. 将文件系统作为“原生”文件系统。按照本地磁盘的方式进行访问。

  2. 文件系统提供一个 org.apache.hadoop.fs.FileSystem 类,供 Hadoop 应用进行访问。


第一种方式很好理解,就是通过其他文件系统挂载到本地目录,然后按照本地目录的方式去使用。但是这种方式也存在着一定的局限——它可以完成基本的功能,但是无法针对计算场景做额外的缓存。


第二种是目前主流的方式,通过实现 FileSystem 接口,与自定义的存储系统进行交互。因为最终实现的 jar 包会部署在计算节点上,所以可以针对性地做一些优化工作,比如数据预读、支持不同的写缓存策略,或是更复杂的分布式缓存等等。


还有另外一种方式文档中没有介绍,就是通过实现 HDFS 的后端服务来进行对接。这种方式相对来说使用比较少,我们会在最后做简要介绍。


接下来,详细介绍一下 FileSystem 目前的设计方式,以及如何去实现相关的功能。


2、接口文档


Hadoop 官方在用户手册中,详细介绍了相关的接口,包括接口前置条件、完成表现、原子性要求、一致性要求等等。详细文档地址如下:


https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/filesystem/index.html


但是,在开发初期,并不建议直接看这个文档,原因是:

  • 第一,内容非常繁琐,同名的系列函数会逐一介绍。完全看完耗时很久,而且在关注细节的过程中会失去对整体的概念;

  • 第二,目前文中有部分列出的接口已经可以实现了,并不需要过多关注。另外它们基于某个其他抽象接口实现的功能,你只需要实现抽象接口即可;

  • 第三,文档的内容,与实际代码接口有所差异,并且文章中多处写到,如果文档与 HDFS 有所差异,以 HDFS 为准;

  • 基于上述原因,建议开发者直接从 Hadoop 的源码,或其他适配的存储系统的适配代码着手,开始了解相关设计。


FileSystem 的接口设计


Hadoop 调用的接口分为 1.x 的 FileSystem 和 2.x 的 FileContext。

1、Hadoop 1.x 接口 FileSystem



FileSystem 的实现,可以分为两类:


  • 实际功能类实现

Hadoop 已经内置支持了很多的存储系统,例如本地文件系统 RawLocalFileSystem,基于 AmazonS3 的 S3AFileSystem,以及基于 FTP 的 FTPFileSystem 等等。新的存储系统做适配,也要采用这种方式来做实现。

  • 装饰器类实现

FilterFileSystem 本身并没有实现具体的行为,而是调用一个 FileSystem 对象接口,起到了装饰器的功能。它主要用于派生类实现额外的功能逻辑,而不需要关注底层的具体存储系统。


2、Hadoop  2.x 接口 FileContext



当你看到 1.x、2.x 接口的时候,可能会想是不是需要实现两份代码?不需要担心,Hadoop 的接口设计很好地避免了这个问题。FileContext 本身并不是接口,它通过调用 AbstractFileSystem 的接口来完成功能。AbstractFileSystem 的实现分为三种:


  • DelegateToFileSystem:这个类中将所有 2.x 接口的函数使用了 1.x 的 FileSystem 做了实现。因此,我们并不需要再把 1.x 的任务重复一遍,只需要继承这个类,做一些我们期望的接口改动即可;

  • FilterFs:同 1.x 的 FilterFileSystem,起到装饰器的功能;

  • 其他:如果不希望直接用 1.x 接口来做实现,直接继承 AbstractFileSystem 来实现功能也没有问题。


存储系统的常见适配方式


了解完 Hadoop 的接口之后,还需要考虑在实现中如何与自己的存储对接,具体指的是和存储系统的架构、功能考量、开发量考量等等问题。目前,有很多存储系统已经做了支持,我们可以做一些了解,作为参考,大致可以分为以下几类:



后续扩展


本文只对存储系统对接 Hadoop 做了简单的基础性功能介绍。如果后续想要进一步优化,可以在分布式缓存、扩展性、预读策略、输出缓存策略等方面去做额外的工作。感兴趣的还可以参考目前市面上一些好的案例,例如 Hadoop 自带的各种对象存储的实现。

发布于: 刚刚阅读数: 4
用户头像

焱融科技

关注

Drive Future Storage 2020.05.29 加入

面向未来的下一代云存储

评论

发布
暂无评论
存储系统如何适配 Hadoop?_hadoop_焱融科技_InfoQ写作社区