解决hadoop一直存在的瓶颈及扩展性问题,分布式数据存储层HDDS(hadoop新的subproject)

  熟悉使用hadoop的同学应该都知道hadoop的一直存在的几个问题:

  1、单节点故障

  2、namenode的可扩展性

  3、小文件的存储

   第一个问题现在已经比较成熟的解决方案是做主节点的HA,既使用hadoop 2系列版本中的方法,建立两个namenode,一个active状态,另一个是standby状态,两个节点保存的元数据一致,有一个节点服务挂掉之后,另一个节点可以自动顶替上。但是随着集群规模越来越大,我们会发现一个主节点的内存已经不足以存放下整个集群的元数据,这个时候我们想到使用多个节点的内存来服务于现在的整个集群,抽象相当于namenode的角色也搞成一个集群。当然后来着这种办法也被社区所接受于是就有了Federation 联邦hdfs,通过横向扩展namespace的方式从逻辑上分离多个nn节点与其管理的元数据,这方法理论及实现参考如下链接

http://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/Federation.html

但Federation这种方式并不是从根本上解决nn节点的高消耗内存问题,它是以资源为代价以满足集群规模的增长,但我们想一想当我们的数据有淘宝,甚至谷歌这么大的体量时,那我们在主节点上的成本就要有多大了?接下来是第三个问题,第三个问题现在也是普遍存在于各个公司的集群,小文件太多,做一个体量较大的统计分析就消耗了大量的计算资源,运维去看下元数据清单,大量的小文件分布在dn的各个节点上,为什么会这样呢?随着集群规模的扩大,集群的使用者也越来越多,并不是所有的使用者都知道或理解hdfs的存储原理的,那么于是各类不规范的操作,建表、查询都使小文件的数量快速的增长。 跳出前三个问题,我们思考,大数据现在已经被应用于各个行业,随着时间的推移,数据量的增长速度也不可预估的,那么原有的hdfs原理及架构真能够满足我们以后的需求么?在现已发现的问题里我们应该怎样改进?于是就衍生出了我们的HDDS

HDDS的起源与诞生

因为 HDFS 不适合做小文件存储系统,于是社区在 HDFS-7240 里提出了基于 HDFS 的对象存储的话题(HDFS 的对象存储,简称 Ozone,不过现在此 JIRA 名称已被更新)。目标就是能够在现有 HDFS 数据存储能力上,增加对象存储的功能,这里自然也包括了小文件存储的情况。

但是这个功能的改动,区别于其它 HDFS 的普通特性,它的改动将会非常大。为什么这么说呢?小文件所引发的扩展性问题,从更深层次的原因来分析,是由于 NN 将繁重的块服务纳入到了自己的管辖范围内。这样一来的话,NN 要多维护两层关系:

  • Block 块对实际存储位置(DN)的映射
  • Block 块对文件映射

每个映射关系按照上千万规模级别数的块来算,这需要占据掉 GB 级别大小的内存空间的。除了占据 NN 内存空间以外,基于块的结构还会有以下两个更为严重的问题:

  • 对这些映射关系图做更新操作时,会有潜在代价很高的 FSN 锁竞争的问题;
  • 大批量块汇报动作造成 NN、DN 压力。

鉴于 HDFS 早期设计所暴露出来的扩展性问题,对象存储在设计的时候将块服务分离了出去,同时引入了容器(Container)的概念。然后由这些容器对外提供块服务。换句话说,对象存储实现了一套全新的块存储服务。

再后来,随着对象存储功能的不断完善,社区将对象存储底层的容器服务单独拆分开来,命名为 Hadoop 分布式存储层(Hadoop Distributed Data Store,简称 HDDS)。而对象存储则是基于其上的一个场景应用。HDFS-7240 的标题名称也从 Object store in HDFS 更名为 Scaling HDFS。这整个过程的发展演变,也是经过了社区长时间的讨论。

 

HDDS的架构体系

解决问题

 

聊 HDDS 内部的架构体系之前,首先我们要明白一点,HDDS 到底要解决一个什么样的核心问题,答案是 HDFS 的扩展性问题。HDFS 的扩展性问题目前主要集中在以下两点:

  • 繁重的块服务
  • 庞大的内存命名空间存储

对于第一点,HDDS 提供了一种基于容器的块服务,这个在前面也提到过了。第二点元数据的存储,HDFS 目前是将所有的元数据都存在内存中的,虽然说这样查询起来响应快,但是随着元数据的增多,对于 NN 节点的内存消耗是非常惊人的。而 HDDS 在这里引入了第三方更高效的 K-V 数据库做元数据的存储,目前支持的有 RocksDB 和 LevelDB 两种。

HDDS内部概念及定义

由于是完全不同于现有 HDFS 的结构设计,HDDS 内部定义了很多新的概念。主要有以下一些。

  • Container:容器,由这些容器对外提供块存储服务。每个容器有自己的大小空间,即所属的 DN 节点。在 HDDS 模式下,DN 管理的将不再是直接的块副本数据,而是 Container 容器副本。Replication 操作以及 DN 的心跳汇报都是基于容器层面来做的。
  • Block:块存储单元,与 HDFS 模式下的块类似。是存储数据的单元,也是客户端实际数据写入单元。
  • Chunk:实际文件存储,一个 Block 块单元由一组 Chunk 文件组成。
  • Pipeline:管道,这个管道信息指容器实际位置的节点信息。比如 Pipeline 中包含 3 个节点,意为容器需要 Replication 在这 3 个节点上。当然,在后续容器数据写入的时候,也会保证 Pipeline 节点上的数据一致。
  • SCM:容器管理服务(Storage Container Manager)。这个服务类似于 HDFS 的 NN 这样的角色。SCM 服务是 HDDS 中十分核心的服务,它负责管理所有的容器分配、删除等操作。对于外部使用者而言,它们都需要向 SCM 请求分配容器来提供块的存储写入。
  • KSM(OM):对象存储管理服务(Key Space Manager,命名空间管理服务)。原先 KSM 服务与 SCM 服务都是偏向于底层服务的,但是 KSM 实际的功能属性是对象存储的元数据管理,所以后来更名为 Ozone Manager(OM)服务了。KSM 服务属于构建于 HDDS 其上的一个应用服务。

HDDS的内部结构

HDDS 的内部结构图

上图中绿色部分就是本文阐释的 HDDS 层,灰色部分是基于其上的对象存储服务(Ozone)。目前社区实现的对象存储服务,与业界流行的基于 Bucket、Key 的存储,在概念上区别不大。

再从纵向深度上来看 HDDS 的结构,如下图:

图中 C 字母打头指的是容器。每个容器内部由块组成,每个块又是由物理 Chunk 文件组成。在对象存储中,我们所说的一个 Key(对象),实际指向可能是一个或多个块,根据所存入对象大小而定。每个容器副本的内部结构如下:

从上图可以看出,对于每个容器而言,它都有独有的 db 文件来存储上面的元数据信息(主要为块与 Chunk 信息)。从这里我们也能够看出 HDDS 的核心设计都是围绕容器展开的。

而另外一个关于容器副本的状态一致性问题,HDDS 内部采用了开源库 Apache Ratis 来做容器的状态一致性管理,避免了在 HDDS 内部实现复杂的一致性控制逻辑。Apache Ratis 是一致性协议 Raft 的 Java 实现库。

HDDS的元数据存储

相比较于 HDFS 完全内存式的元数据存储,HDDS 做出了以下两点改进:

  • 引进更高效的 K-V 数据库
  • 元数据粒度拆分更加细致化

这里我们主要谈论第二点。在基于容器化的块服务模式下,元数据的映射关系会复杂一些,主要有下面一些关系:

  1. 容器 -> 实际位置
  2. 块 -> 容器
  3. 块 -> 实际数据

以及一些基本元数据信息:

  • 所有容器的信息,由 SCM 服务节点管理;
  • 所有块的信息,由所在节点自行管理,HDDS 无需全局管理块信息;
  • 所有管道的信息,同样由 SCM 服务节点管理。

从上面可以看出,HDDS 将繁重的块管理移交给了存储节点本身,这样还能充分利用起每个节点本身的处理能力,可以说这是一种分布式元数据管理的方式了。而对于每个节点本身,只需要将自身容器信息汇报给 SCM 服务即可。在这种基于容器化的方式下,也不会有大量块汇报引发的性能问题。

但是这里会有个关键的问题,如果块不是中心被管理的,而且 SCM 只管理容器信息,客户端怎么找到实际块所在的位置信息,从而进行数据的读写呢?答案是通过 SCM 与外部服务的协作来完成,流程如下图所示。

 

首先,我们能从上图中直观地看到,元数据被拆分成了 3 个独立的 DB 存储:KSM 服务负责数据元信息,SCM 负责容器信息(包含 Pipeline 管道信息),DN 负责实际数据文件信息。当一个客户端发起读写数据请求时,将会依次经过图上的步骤:

  1. 客户端向 KSM 服务请求某个 key(文件)的数据,KSM 服务查询此 key 对应的 Block 块信息,然后从块信息中得到此块所属于的 Container 容器 ID;
  2. KSM 得到相应的容器 ID 后,请求 SCM 服务,得到此容器信息,得到其 Pipeline 管道信息,也就是此容器所在的节点位置信息;
  3. 客户端得到 SCM 返回的节点位置信息;
  4. 之后,客户端再请求到实际物理节点,查询本地节点的容器 DB 文件,得到对应块的物理文件信息,最终进行数据读写操作。

尽管以上分离的元数据存储增加了请求操作流程,但是在扩展性方面无疑得到了增强,同样在结构上也非常灵活。在上图中,HDDS 对外表现为 DN 和 SCM 提供了整体容器块存储服务。KSM 则是其上的一个对象存储的服务,它需要向 SCM 请求块来做数据的存储。在未来,当然可能会有其它别的类似于 KSM 的服务应用。

基于 HDDS 之上如何构建 HDFS

这里其实涉及到两套体系结构的融合问题,但是这种融合并不那么简单。最大的难点是如何做到 HDFS 的块能够平滑地迁移成 HDDS 的容器块结构。在这里,社区提出了以下两种做法:

1. 改造现有 HDFS 内部的块结构,增加容器管理模块,调整块映射结构或者将块管理从 NN 中移出。现有 NN 内部的映射关系如下所示:

  • 文件名 --> INodeFile
  • File --> Block[](块 ID)
  • Block --> DN[](实际位置)
  • Block --> Block Data(实际数据)

在以上 4 组关系中,后 3 组都需要做略微改动,加入容器 ID 的标识来适配 HDDS 的新的结构(假设此时 DN 已经可以提供容器服务)。在这套方法中,我们需要做一层这样的映射转换,中间还要有容器信息的关联,操作复杂性比较高。而且涉及到 HDFS 的 FSN 锁分离工作,这并不是一件轻松的事情。

2. 临时轻便的解决方案,构建出一个兼容性文件系统(Hadoop compatible FS,简称 HCFS)。社区在对象存储中实现了 Ozone FileSystem 的文件系统,简称 Ozfs。Ozfs 实现了一套完整的兼容性文件系统 API。对于上层的 Hive、Spark 应用来说,无需做任何改变。通过 Ozfs,用户可以将老结构的 HDFS 数据读出,写入到对象存储下,也就是 HDDS 的 K-V 元数据结构。而新的数据直接通过 Ozfs 写入到 HDDS 即可。这整个过程对于 HDFS 的元数据来说,就从完全内存式地存储变为了高效 K-V 式的 DB 存储方式。但是这种方式的一个弊端是,它并不是针对所有的外部应用生效。它要强依赖于兼容性文件系统 API 来操作。而第一种方法是直接改造了 HDFS 内部的元数据结构来构建新的存储层,它是能够对所有外部应用生效的。

下图是两种方案的方案图:

目前社区的Ozone便是构建在HDDS之上的应用,

What is Apache Hadoop Ozone?

Ozone is a new subproject of Apache Hadoop. It provides an object store semantic for Hadoop.

It uses Hadoop Distributed Data Storage (HDDS) for storage layer. HDDS is another new subproject of Apache Hadoop.

ozone是apache Hadoop的一个新的子项目。它为Hadoop提供对象存储接口应用。

它使用Hadoop分布式数据存储(HDDS)作为存储层。HDDS 是Apache Hadoop的另一个新的子项目

下面附上ozone的文档链接

https://hadoop.apache.org/ozone/docs/0.3.0-alpha/settings.html

目前hdds及ozone处于初期阶段,技术的进步得益于开源,开源是众人的贡献!

本文参考

http://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/Federation.html

https://hadoop.apache.org/ozone/docs/0.3.0-alpha/settings.html

https://gitbook.cn/books/5be9340eed715b5f9a6c4b82/index.html

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值