分布式文件系统架构设计(20201126073806)

分布式文件系统架构设计(20201126073806)
分布式文件系统架构设计(20201126073806)

分布式文件系统架构设计

1. 前言...................................................... 3.

2. HDFS1 (3)

3. HDFS2 (5)

4. HDFS3 ............................................................................................. 1 1

5. 结语..................................................... 1.5

1. 刖言

Hadoop 是一个由Apache基金会所开发的分布式系统基础架构。用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力进行高速运算和存储。

Hadoop 实现了一个分布式文件系统(Hadoop Distributed File System ),简称HDFS,解

决了海量数据存储的问题;实现了一个分布式计算引擎MapReduce ,解决了海量数据如何计

算的问题;实现了一个分布式资源调度框架YARN,解决了资源调度,任务管理的问题。而我

们今天重点给大家介绍的是Hadoop 里享誉世界的优秀的分布式文件系统-HDFS。

Hadoop 重要的比较大的版本有:Hadoop1 ,Hadoop2 , hadoop3 。同时也相对应的有HDFS1 ,HDFS2,HDFS3三个大版本。后面的HDFS的版本,都是对前一个版本的架构进行了调整优

化,而在这个调整优化的过程当中都是解决上一个版本的架构缺陷,然而这些低版本的架构缺陷也是我们在平时工作当中会经常遇到的问题,所以这篇文章一个重要的目的就是通过给大家介绍HDFS不同版本的架构演进,通过学习高版本是如何解决低版本的架构问题从而来提升我

们的系统架构能力。

2. HDFS1

最早出来投入商业使用的的Hadoop 的版本,我们称为Hadoopl ,里面的HDFS就是HDFS1 ,

当时刚出来HDFS1,大家都很兴奋,因为它解决了一个海量数据如何存储的问题。HDFS1用的是主从式架构,主节点只有一个叫:Name node ,从节点有多个叫:DataNode 。

我们往HDFS上上传一个大文件,HDFS会自动把文件划分成为大小固定的数据块(HDFS1的时候,默认块的大小是64M,可以配置),然后这些数据块会分散到存储的不同的服务器上面,为了保证数据安全,HDFS1里默认每个数据块都有3个副本。Name node 是HDFS的主节

点,里面维护了文件系统的目录树,存储了文件系统的元数据信息,用户上传文件,下载文件

等操作都必须跟NameNode 进行交互,因为它存储了元数据信息,Name node 为了能快速

响应用户的操作,启动的时候就把元数据信息加载到了内存里面。DataNode 是HDFS的从节

点,干的活就很简单,就是存储block文件块。

01 / HDFS1 架构缺陷

缺陷一:单点故障问题(高可用)

我们很清楚的看到,HDFS1里面只有一个NameNode ,那么也就是说如果这个Name node 出问题以后,整个分布式文件系统就不能用了。

缺陷二:内存受限问题

NameNode 为了能快速响应用户的操作,把文件系统的元数据信息加载到了内存里面,那么

如果一个集群里面存储的文件较多,产生的元数据量也很大,大到name node 所在的服务器

撑不下去了,那么文件系统的寿命也就到尽头了,所以从这个角度说,之前的HDFS1的架构里Name node 有内存受限的问题。

我们大体能看得出来,在HDFS1架构设计中,DataNode 是没有明显的问题的,主要的问题

是在NameNode 这儿。

3. HDFS2

HDFS1明显感觉架构不太成熟,所以HDFS2就是对HDFS1的问题进行解决。

01 /单点故障问题解决(高可用)

大家先跟着我的思路走,现在我们要解决的是一个单点的问题,其实解决的思路很简单,因为

之前是只有一个NameNode ,所以有单点故障问题,那我们把设计成两个Name node 就可以了,如果其中一个name node 有问题,就切换到另外一个NameNode 上。

NameNode

所以现在我们想要实现的是:其中一个Name node 有问题,然后可以把服务切换到另外一个

Name node 上。如果是这样的话,首先需要解决一个问题:如何保证两个NameNode 之间的

元数据保持一致?因为只有这样才能保证服务切换以后还能正常干活。

保证两个NameNode 之间元数据一致

为了解决两个NameNode 之间元数据一致的问题,引入了第三方的一个JournalNode 集群。

IdumalnDde 集群

JournO'INodo Journal Nodo

L -riri -!

0$ 1 # ----------

Ail JF M

Jour nalNode 集群的特点:JournalNode 守护进程是相对轻量级的,那么这些守护进程可与

其它Hadoop 守护进程,如NameNode ,运行在相同的主机上。由于元数据的改变必须写入大多数(一半以上)JNs,所以至少存在3个JournalNodes 守护进程,这样系统能够容忍单

个Journal Node 故障。当然也可以运行多于3个JournalNodes ,但为了增加系统能够容忍

的故障主机的数量,应该运行奇数个JNs。当运行N个JNs时,系统最多可以接受(N-1)/2 个主机故障并能继续正常运行,所以Jou nal Node 集群本身是没有单点故障问题的。

元数据,StandBy 状态的NameNode 实时从Journal Node 集群同步元数据,这样就保证了

两个NameNode 之间的元数据是一致的。

两个NameNode 自动切换

引入了Journal Node 集群以后,Active状态的NameNode 实时的往Journal Node 集群写

工的参与把 Sta ndby N ameNode 切换成为 Active NameNode ,这个过程并不是自动化的,

但是很明显这个过程我们需要自动化,接下来我们看 HDFS2是如何解决自动切换问题的。为

了解决自动切换问题,

HDFS2弓I 入了 ZooKeeper 集群和ZKFC 进程。

ZKFC 是DFSZKFailoverController 的简称,这个服务跟 NameNode 的服务安装在同一台服

务器上,主要的作用就是监控 NameNode

健康状态并向 ZooKeeper 注册 NameNode ,如果

Active 的NameNode

挂掉后,ZKFC 为StandBy 的NameNode 竞争锁(分布式锁),获得

ZKFC 锁的NameNode 变为active ,所以引入了 ZooKeeper 集群和 ZKFC 进程后就解决了 NameNode 自动切换的问题。

02 / 内存受限冋题解决

目前虽然解决了单点故障的问题,但是目前假如

Active NameNode 出了问题,还需要我们人

? u 11 1 H 廿

前面我们虽然解决了高可用的问题,但是如果NameNode 的元数据量很大,大到当前NameNode 所在的服务器存不下,这个时候集群就不可用了,换句话说就是NameNode 的

扩展性有问题。为了解决这个问题,HDFS2弓I入了联邦的机制。

Diffl带9阳顾lorn

nni

燧架构之美

如上图所示这个是一个完整的集群,由多个name node 构成,name nodel 和name node2

构成一套name node ,我们取名叫nn 1 ,这两个name node 之间是高可用关系,管理的元数据是一模一样的;name node3 和name node4 构成一套name node ,假设我们取名叫nn2 ,

这两个name node 之间也是高可用关系,管理的元数据也是一模一样的,但是nn1和nn2管

理的元数据是不一样的,他们分别只是管理了整个集群元数据的一部分,引入了联邦机制以后,

如果后面元数据又存不了,那继续扩nn 3, nn 4… 就可以了。所以这个时候NameNode 就在存

储元数据方面提升了可扩展性,解决了内存受限的问题。

联邦这个名字是国外翻译过来的,英文名是Federation ,之所以叫联邦的管理方式是因为

Hadoop 的作者是Doug cutti ng ,在美国上学,美国是联邦制的国家,作者从国家管理的方

式上联想到元数据的管理方式,其实这个跟我们国家的管理方式也有点类似,就好比我们整个国家是一个完整的集群,但是如果所有的元数据都由北京来管理的话,内存肯定不够,所以中国分了34个省级行政区域,各个区域管理自己的元数据,这行就解决了单服务器内存受限的问题。

HDFS2弓I入了联邦机制以后,我们用户的使用方式不发生改变,联邦机制对于用户是透明的,

因为我们会在上游做一层映射,HDFS2的不同目录的元数据就自动映射到不同的name node 上。

03 / HDFS2的架构缺陷

缺陷一:高可用只能有两个name node

为了解决单点故障问题,HDFS2设计了两个name node, —个是active,另外一个是sta ndby ,

但是这样的话,如果刚好两个NameNode 连续出问题了,这个时候集群照样还是不可用,所

以从这这个角度讲,NameNode 的可扩展性还是有待提高的。

注意:这个时候不要跟联邦那儿混淆,联邦那儿是可以有无数个name node 的,咱们这儿说

的只能支持两个name node 指的是是高可用方案。

缺陷二:副本为3,存储浪费了200%

其实这个问题HDFS1的时候就存在,而且这个问题跟的设计没关系,主要是DataNode 这儿的问题,DataNode 为了保证数据安全,默认一个block都会有3个副本,这

样存储就会浪费了200% 。

NameNode

4. HDFS3

其实到了HDFS2,HDFS就已经比较成熟稳定了,但是HDFS3还是精益求精,再从架构设计

上重新设计了一

01 / 高可用之解决只能有两个name node

当时在设计HDFS2的时候只是使用了两个NameNode 去解决高可用问题,那这样的话,集

群里就只有一个NameNode 是Standby 状态,这个时候假设同时两个NameNode 都有问题的话,集群还是存在不可用的风险,所以在设计HDFS3的时候,使其可支持配置多个

NameNode 用来支持高可用,这样的话就保证了集群的稳定性。

02 /解决存储浪费问题

HDFS3之前的存储文件的方案是将一个文件切分成多个Block进行存储,通常一个Block 64MB 或者128MB,每个Block 有多个副本(replica),每个副本作为一个整体存储在一个DataNode 上,这种方法在增加可用性的同时也增加了存储成本。ErasureCode 通过将M个

数据block 进行编码(Reed-Solomon,LRC) ,生成K 个校验(parity)block, 这M+K 个block

组成一个block group,可以同时容忍K个block失败,任何K个block都可以由其他M个block 算出

来.overhead 是K/M。

以M=6,K=3 为例,使用EC之前,假设block副本数为3,那么6个block 一共18个副本,overhead 是200%,使用EC后,9个block,每个block 只需一个副本,一共9个副本,其中6个数据副本,3个校验副本,overhead 是3/6=50% 。

在存储系统中,纠删码技术主要是通过利用纠删码算法将原始的数据进行编码得到校验,并将数据和校验一并存储起来,以达到容错的目的。其基本思想是将k块原始的数据元素通过一定的编码计算,得到m块校验元素。对于这k + m块元素,当其中任意的m块元素出错(包括数

据和校验出错),均可以通过对应的重构算法恢复出原来的k块数据。生成校验的过程被称为编码(encoding ),恢复丢失数据块的过程被称为解码( decoding )。

Reed-Solomon ( RS )码是存储系统较为常用的一种纠删码,它有两个参数 RS(k,m)。如下图所示,k 个数据块组成一个向量被乘上一个生成矩阵(

Codeword

它是社区最新的 HDFS3内部的方案,需要对整个 HDFS 内部实现进行改造, 包括DataNode NameNode 还有DFSClient ,该方案同时支持在线和离线

EC 。

03 / 在线EC

k 和m ,记为

Gen erator Matrix )

GT 从而得到一个码字(

codeword )向量,该向量由 k 个数据块和 m 个校验块构成。如果一

个数据块丢失, 可以用(GT)-1乘以码字向量来恢复出丢失的数据块。 RS(k,m)最多可容忍 m 个

块(包括数据块和校验块)丢失。

d :

Data

Data

Parity

G T

当前HDFS block 的副本作为一个整体连续(contiguous)的存储在一个DataNode 上,在locality 上具有一定的优势,特别是对于MapReduce 这样的应用,但是这种方法不好做在线

EC。当前社区方案不以block为单位进行EC,而是以strip为单位进行EC(HDFS依旧管理Block)设计思路参考了QFS。对于配置了EC的文件,客户端写入时将文件的数据切成一个个

的64KB的strip ,相邻的strip 发往不同的DataNode, 比如当前使用(6,3)-Reed-solomon 编码,当前正在写的文件有 6 个strip: strip1, strip2, strip3, strip4, strip5, strip6, 那么这 6 个strip和相应的编码出来的3个校验strip共9个strip会并行的发往9个不同的DataNode 。这种方式写入性能更好,但是也会对网卡出口带来一些压力,同时牺牲了locality 。如果文件

大小不是64KB * 6的整数倍(本文例子),那么最后一个strip group 显然不是满的,这时客户

端还会将最后一个strip group 的长度记在校验块中,后续读的时候,可以根据这个长度和数

据块长度还有文件长度来校验。

对于append 和hflush 操作,最后一个parity strip group 很可能还没有切换成新的strip group,这就需要DataNode 更新最后一个parity strip 的数据。

读操作,丢失block时,只需要读9个DataNode 中任意6个DataNode 即可修复。修复过程需要读多个DataNode ,耗费网络带宽和磁盘IO。

04 / 离线EC

该方案也支持离线EC,可以异步的将多副本文件转成EC文件,通过集成在NameNode 中的ECManager 和DataNode 上的ECWorker 来支持。命令行工具提供replication 和ec之间

的转换,可以通过命令行配置哪些文件/目录使用EC.在转换方程中,不支持append 。

这样的话,HDFS3靠就删码技术解决了存储浪费的问题。

5.结语

好了,到目前为止我们看到HDFS,三个大的版本的演进的过程,一开始是HDFS1,HDFS1有

问题,所以就有了HDFS2,HDFS2就是为了解决HDFS1架构缺陷的,同学们,我们回过头

来想想,其实HDFS1的那些架构设计问题,是不是我们平时的项目当中也是存在的,所以以

后大家在项目中遇到类似问题的时候,不妨可以参考借鉴一下HDFS2的解决的思路。HDFS3是对HDFS2的优化,其实HDFS3解决的这些问题,如果自己设计过文件系统的同学(本人自

己设计过分布式图片服务器)也可用类似的思路去解决系统的高可用和副本造成存储浪费的问

题。

相关主题
相关文档
最新文档