Apache Hadoop HDFS架构

承接上一篇翻译的HDFS的博客。这篇博客翻译自

https://www.edureka.co/blog/apache-hadoop-hdfs-architecture/

介绍

在这篇博客里,我将介绍Apache Hadoop HDFS的架构。如果想熟练掌握Hadoop,HDFS&YARN是两个很重要的概念。在上一篇博客中,你已经知道了HDFS是一个分布式文件系统,部署在廉价的硬件上。现在,是时候来更深入地了解HDFS来发现它的神奇。

本篇博客主要包含一下内容:

  • HDFS的Master/Slave拓扑结构
  • NameNode,DataNode和Secondary NameNode的概念
  • 块(block)是什么?
  • 副本管理
  • Rack Awareness机架感知机制
  • HDFS背后的读写机制

HDFS架构:

Apache HDFS是一个以块(block)为结构的文件系统。每个文件都被分割成不同的块,块的大小事先已经确定。这些块被存储在Hadoop集群中一台或多台机器中。Apache Hadoop HDFS架构遵循 Master/Slave架构,一个hadoop HDFS集群由一个NameNode(Master Node)和多个DataNode(SlaveNode)组成。HDFS可以部署在很多支持Java的机器上。尽管我们可以在一台物理机器上运行多个DataNode进程,但是在实际的生产中,这些DataNode进程运行在不同的机器上。

NameNode

NameNode是Hadoop HDFS架构中负责维护和管理DataNode(slave nodes)上的块的。NameNode是一个高可用的服务器,这个高可用的服务器管理着文件系统的命名空间,控制这客户对文件的访问。HDFS架构中,用户的数据永远不会存储在NodeNode上,只会存储在DataNode上。

NameNode的功能:

  • 是master守护进程,维护管理着DataNodes
  • 记录着存储在HDFS集群中所有文件的元数据信息。这些元数据包括:块的存储位置、文件大小、权限、等级。与元数据有关的文件有两个:1、FsImage(文件系统镜像?)这个文件包含了文件系统命名空间。2、EditLogs(编辑日志?)这个文件记录了所有对于文件系统的修改,与最近的FsImage相关联。
  • 记录着所有对于文件系统元数据的修改记录。比如:如果HDFS上的一个被删除了,NameNode会立刻把这个删除操作记录在EditLog当中。
  • NameNode会定时接收心跳信息,接收集群中DataNode发来的一个块的数据来确认集群中所有的DataNode都在线。
  • NameNode为HDFS中的块维护着一个记录,在这个记录中记录着所有块的位置。
  • NameNode同样负责维护所有块的副本因子(replication factor)
  • 当DataNode宕机的时候,NameNode会选择其他的DataNode更新副本的存储情况,来平衡整个系统中所有机器的硬盘使用量,保持整个系统中的负载均衡。

DataNode

DataNode是HDFS中的slave nodes。和NameNode是一台高可用服务器不同,DataNode可以部署在廉价的硬件上,这意味着,这是一个相对廉价的系统,并没有高可用性。DataNode是一个块服务器,将块数据存储在本地的EXT4文件系统。

DataNode功能:

  • 它们是slave进程,运行在HDFS集群中的slave节点上
  • 实际的文件数据都存储在DataNode上
  • DataNode处理客户端对文件的简单的读写请求
  • DataNode会向NameNode周期性发送心跳信息来报告HDFS是否正常。默认情况下,这个周期是3秒

截止到现在,你一定已经意识到,NameNode对于整个HDFS非常重要,如果NameNode宕机的话,我们就完蛋了。但是不用担心,Hadoop也提供了相应的解决方案,接下来我们进一步了解HDFS。

Secondary NameNode:

除了NameNode和DataNode这两个进程外,整个集群中还有一个进程:Secondary NameNode。Secondary NameNode和NameNode同时工作,作为一个辅助进程(helper daemon)。但是需要注意的是,Secondary NameNode并不是NameNode的备份。

Secondary NameNode的功能:

  • Secondary NameNode会从NameNode的RAM中读取文件系统和元数据的信息,把这些信息写入硬盘和文件系统。
  • 将NameNode的EditLogs和FsImage组合到一起
  • 周期性地从NameNode下载EditLogs信息,并将EditLogs的操作信息应用于自己的FsImage,新的FsImage被拷贝回NameNode。NameNode下次启动的时候使用这个FsImage。

因此,Secondary NameNode负责周期性地检查HDFS,所以它也被称作CheckpointNode。

块:

我们已经知道,文件数据在HDFS中被分割成多个块分散在不同的DataNode中,接下来我们学习一下块究竟是什么?它是怎么形成的?

块是存储介质上最小的连续存储单元。总体来讲,对于任何一种文件系统而言,存储的数据其实都是多个块的集合。类似的,HDFS也把文件按块存储,只不过这些块分散到了Hadoop集群中去了。每个块的默认大小是128MB(Hadoop 2.X)。这个块的大小是可以配置的。

HDFS中,每个文件并不会存储在精确的多个块中。比如上图中的例子,example.txt文件是一个514MB的文件。假设我们的块大小是128MB,我们会使用5个块。前四个块占用了128MB,而最后一个块只占用了2MB。

现在,你一定在想,我们为什么要把一个块的大小默认在128MB这么大的容量?

当我们使用HDFS的时候,我们针对的都是大数据量,TB级别或者PB级别的数据量。如果我们把一个块的大小定伪4KB(EXT文件系统就是这么定的),我们会拥有太多的块了,相应的,元数据量就太大。管理这么多的块和元数据会造成巨大的系统开销。

副本管理:

HDFS提供了一种可靠的方案,可以在分布式环境中以数据块为单位存储海量数据。这些块同时也会有副本来增强容错性。默认的副本因子是3,这个是可以配置的。所以在下图中,你可以看到每个数据块都被复制了三份,存储在不同的DataNode上。

因此,如果要在HDFS中使用默认的副本因子存储一个128MB的文件,最终会使用384MB的空间,因为数据块被复制了三份存储在不同的节点上。

NameNode会从DataNode那里周期性地获取block的信息,来维持副本因子。当数据块的副本数量不足或者太多的时候,NameNode都会增加或删除副本。

Rack Awareness机架感知

我们来讨论一下HDFS如何存放副本,还有机架感知是什么。再一次提及NameNode,NameNode会保证副本不会被存储在相同的机架上,也会保证副本不会只存储在一个机架上。为了实现这样的功能,HDFS遵循机架感知算法来减少延迟,增加容错性。设副本因子为3,机架感知算法会让某个块的第一份副本存储在本地机架上,另外两份会被存储在远程机架上,但是,就像上图展示的那样,副本会存储在远程节点不同的DataNode上。如果你有更多的副本的话,剩下的副本会被随机存储在DataNodes上面,但是同一个机架上不会超过两个副本。

这是实际的Hadoop产品化的集群:你拥有多个机架,每个机架上有多个DataNode:

机架感知的优势:

现在你会思考,为什么我们需要机架感知算法?原因如下:

  • 提升网络性能:不同机架上不同节点之间的通信通过switch完成,总体来说,同一个机架当中的机器之间的网络带宽相比跨机架主机的网络带宽要高,机架感知可以帮助你减少不同机架之间的写操作的路由开销,提供一个更好的写操作性能。另外,在读操作的时候,由于你使用的是多个机架的带宽,你也可以获得读性能的提升。
  • 防止数据丢失:即使一个整个机架都坏掉了我们也不用担心数据的丢失。因为我们没有把鸡蛋都放在同一个篮子里面(你懂得)。

HDFS的读/写架构

现在,我们来讨论HDFS是如何进行数据的读写操作的。HDFS遵循一次写,多次读的原则,所以说你不能修改存储在HDFS当中的文件,但是你可以通过重新打开文件在文件结尾增加数据。

HDFS写架构:

假设有一个HDFS的客户端,需要将一个258MB的example.txt写入HDFS。

假设HDFS的块大小伪128MB,所以example.txt文件被HDFS客户端分成块A和块B两个块。

接下来,遵循HDFS写数据协议:

  • 首先,HDFS客户端会向NameNode发起一个写两个块的请求。
  • 接下来,NameNode会授予客户端写权限,会提供存储第一个块的所有DataNode的地址。
  • 这些地址的选取,取决于可用性、副本因子和机架感知。
  • 假设副本因子为3,对于每个块来说,NameNode会提供3个DataNode的地址列表,不同的块列表也不同。
  • 假设NameNode提供了这样的地址列表:Block A:{DataNode1,DataNode4,DataNode6}。Block B:{DataNode3,DataNode7,DataNode9}
  • 每个块被复制三次,存入DataNode中。
  • 接下来数据拷贝工作分为三个阶段:
  • 1、建立管道
  • 2、数据流和复制
  • 关闭管道(确认阶段)

建立管道:

在写块之前,客户端首先确认列表中的所有的数据节点,是否已经接收到了数据块。为了完成这个功能,客户端为每个数据块建立管道,分别连接该块的DataNode列表中的所有数据节点。对于Block A而言:

对于数据块A,客户端会进行以下操作:

  • 客户端选择第一个DataNode的地址DataNode1,建立TCP/IP连接。
  • 客户端确认DataNode1已经做好了接收数据块的准备,由于需要对数据进行拷贝操作,客户端同样也会向DataNode1提供后两个DataNode的地址(4和6)。
  • DataNode1会与DataNode4建立连接,DataNode1通知DataNode4做好接收数据块的准备,同时把DataNode6的地址发送给DataNode4,接下来,DataNode4会通知DataNode6做好接收数据的准备。
  • 接下来,确认操作会以相反的顺序完成:DataNode6,4,1
  • 最后,DataNode1会通知客户端所有DataNode已经做好了接收准备,这个时候,客户端会和DataNode 1,4,6建立管道连接。
  • 现在管道已经建立完毕,接下来要进行的是数据拷贝和流化处理。

数据流:

管道建立之后,客户端会把数据传进管道。不要忘记在HDFS文件系统中,数据会根据副本因子复制。现在客户端只会复制一份数据块block A发送给DataNode1,HDFS中数据块的复制总是由DataNode按顺序完成。

所以,在数据拷贝的过程中,遵循以下流程:

  • 客户端向DataNode1写入了数据块以后,DataNode1和DataNode4建立连接
  • DataNode1会把数据块发送进管道,拷贝一份发送给DataNode4
  • DataNode4也会和DataNode6建立连接,再拷贝一份数据块给DataNode6

关闭管道(回复阶段):

当数据块被拷贝到三个,会有一系列的回复操作,向客户端和NameNode确认数据已经被成功写入了。最后,客户端会关闭管道。

如下图所示,确认动作的顺序正好是相反的,从DataNode6到4再到1.最后DataNode 1会把三个节点的确认放入管道,把它发送给客户端,客户端会通知NameNode数据已经被成功写入,NameNode会更新元数据,客户端会关闭管道。

 

同样的,Block B也会按照相同的方式进行拷贝,并且与Block A并行处理。所以还有一下要点需要注意:

  • 客户端会复制Block A和B到第一个数据节点(并行)
  • 会有两个管道连接,上面所讲的过程会在这两个管道上并行发生
  • 客户端把块写入第一个DataNode,DataNode会一步一步复制数据块。

你可以在上图中看到,针对两个块A和B有两个管道连接。这是两个不同块在两个不同管道连接下的流程:

Block A:1A->2A->3A->4A

Block B:1B->2B->3B->4B->5B->6B

HDFS读架构:

HDFS的读结构相对来说好理解一些。我们假设现在客户端要读example.txt。

读操作遵循一下流程:

  • 客户端从NameNode出获取了example.txt数据块的元数据信息
  • NameNode返回了文件数据块的DataNode列表(存储Block A和B的DataNode列表)
  • 客户端与DataNode建立连接
  • 客户端并行地进行读数据(从DataNode1读block1,从DataNode3读B)
  • 读完这些数据块后,客户端会把这些数据块组合成文件。

当HDFS处理读请求的时候,HDFS会选择离client最近的副本,这样就减少了读操作的时延和带宽消耗。所以,如果可能的话,尽可能地会选择在同一个机架上的副本作为被读的数据节点。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值