Hadoop File System

Hadoop分布式文件系统(HDFS)是一种旨在在商品硬件上运行的分布式文件系统。它与现有的分布式文件系统有许多相似之处。但是,与其他分布式文件系统的区别很明显。HDFS具有高度的容错能力,旨在部署在低成本硬件上。HDFS提供对应用程序数据的高吞吐量访问,适用于具有大型数据集的应用程序。

 

 


架构


HDFSæ¶æ

这是HDFS的一个简单架构图。

Rack1和Rack2是两台DataNode,也就是两台从节点。

NameNode是主节点。

其中Datanode是运行在从节点的一个进程,而Namenode是运行在主节点的一个进程。

DataNode负责数据的存储,而NameNode负责元数据的管理。

在HDFS中,我们存储数据可以看成一个数据块一个数据块的存储,每个文件都会分割成很多数据块,现在版本应该默认时128M了吧,毕竟计算机性能比以前好了,而且数据量也越来越大了。

而且对于一个文件,它的多个数据块大小都一样,都是设置的数据块大小,除了最后一块。也就是说,数据是一条条往数据块里面写,然后每写满一个数据块大小就分出一个数据块,这样就可以将前面的数据块都给填满,除了最后一块可能填不满之外。这样做的道理就是为了能够将数据尽可能和计算机性能匹配,你如果到处都是几kB或者几MB的文件,大量的这些杂碎文件就变成了很多任务,交给了很多线程去处理,无疑会降低性能。而且本身128M的数据可以很快处理完,硬是要分成很多零碎文件,交给很多task,然后又加大网络通信,时间说不定还会更长。

Datanode会定期向Namenode汇报自身所保存的文件block信息,而namenode则会负责保持文件的副本数量,HDFS的内部工作机制对客户端保持透明,客户端请求访问HDFS都是通过向namenode申请来进行。

文件的各个block的存储管理由datanode节点承担,datanode是HDFS集群从节点,每一个block都可以在多个datanode上存储多个副本(副本数量也可以通过参数设置dfs.replication,默认是3),至于怎么存储的等会儿就知道了。

HDFS文件系统会给客户端提供一个统一的抽象目录树,客户端通过路径来访问文件,形如:hdfs://namenode:port/dir-a/dir-b/dir-c/file.data。就和我们平时访问的文件形式目录差不多。

HDFS是设计成适应一次写入,多次读出的场景,且不支持文件的修改。需要频繁的RPC交互,写入性能不好。

目录结构及文件分块位置信息(元数据)的管理由namenode节点承担,namenode是HDFS集群主节点,负责维护整个hdfs文件系统的目录树,以及每一个路径(文件)所对应的数据块信息(blockid及所在的datanode服务器),然后对于元数据管理是非常重要的一个环节

 


写数据分析


刚才也大概知道了hdfs的简单架构。但是一些动态的流程可能不是一张图片就能够了解的。

我们来详细分析一下hdfs到底是怎么写数据的。

首先我们要有几个疑问,hdfs数据量那么大,一个文件又要分成那么多个,到底怎么传输?

数据副本那么多,又怎么传到多个机器上?

副本的放置策略又是什么?

我们来一一看看整个流程。

大概的流程就是这样

待这个数据块传输完成客户端后告诉namenode数据块传输完成,这时候namenode才会更新元数据信息记录操作日志。

请求和应答是使用RPC的方式,客户端通过ClientProtocol与namenode通信,namenode和datanode之间使用DatanodeProtocol交互。在设计上,namenode不会主动发起RPC,而是响应来自客户端或 datanode 的RPC请求。客户端和datanode之间是使用socket进行数据传输,和namenode之间的交互采用nio封装的RPC。

在流式复制时如果有一台或两台(不是全部)没有复制成功,不影响最后结果,只不过datanode会定期向namenode汇报自身信息。如果发现异常namenode会指挥datanode删除残余数据和完善副本。如果副本数量少于某个最小值就会进入安全模式。

机架感知策略

HDFS采用一种称为机架感知(rack-aware)的策略来改进数据的可靠性、可用性和网络带宽的利用率。大型HDFS实例一般运行在跨越多个机架的计算机组成的集群上,不同机架上的两台机器之间的通讯需要经过交换机。在大多数情况下,同一个机架内的两台机器间的带宽会比不同机架的两台机器间的带宽大。通过一个机架感知的过程,Namenode可以确定每个Datanode所属的机架id。一个简单但没有优化的策略就是将副本存放在不同的机架上。这样可以有效防止当整个机架失效时数据的丢失,并且允许读数据的时候充分利用多个机架的带宽。这种策略设置可以将副本均匀分布在集群中,有利于当组件失效情况下的负载均衡。但是,因为这种策略的一个写操作需要传输数据块到多个机架,这增加了写的代价。在大多数情况下,副本系数是3,HDFS的存放策略是将一个副本存放在本地机架的节点上,一个副本放在同一机架的另一个节点上,最后一个副本放在不同机架的节点上。这种策略减少了机架间的数据传输,这就提高了写操作的效率。机架的错误远远比节点的错误少,所以这个策略不会影响到数据的可靠性和可用性。于此同时,因为数据块只放在两个(不是三个)不同的机架上,所以此策略减少了读取数据时需要的网络传输总带宽。在这种策略下,副本并不是均匀分布在不同的机架上。三分之一的副本在一个节点上,三分之二的副本在一个机架上,其他副本均匀分布在剩下的机架中,这一策略在不损害数据可靠性和读取性能的情况下改进了写的性能。

安全模式

Namenode启动后会进入一个称为安全模式的特殊状态。处于安全模式的Namenode是不会进行数据块的复制的。Namenode从所有的 Datanode接收心跳信号和块状态报告。块状态报告包括了某个Datanode所有的数据块列表。每个数据块都有一个指定的最小副本数。当Namenode检测确认某个数据块的副本数目达到这个最小值,那么该数据块就会被认为是副本安全(safely replicated)的;在一定百分比(这个参数可配置)的数据块被Namenode检测确认是安全之后(加上一个额外的30秒等待时间),Namenode将退出安全模式状态。接下来它会确定还有哪些数据块的副本没有达到指定数目,并将这些数据块复制到其他Datanode上。


读数据分析


一个个数据块读到客户端,然后一个个数据块合并,就还原了最开始的文件。同样,机架感知策略同样适用。

从某个Datanode获取的数据块有可能是损坏的,损坏可能是由Datanode的存储设备错误、网络错误或者软件bug造成的。HDFS客户端软件实现了对HDFS文件内容的校验和(checksum)检查。当客户端创建一个新的HDFS文件,会计算这个文件每个数据块的校验和,并将校验和作为一个单独的隐藏文件保存在同一个HDFS名字空间下。当客户端获取文件内容后,它会检验从Datanode获取的数据跟相应的校验和文件中的校验和是否匹配,如果不匹配,客户端可以选择从其他Datanode获取该数据块的副本。


元数据管理


元数据包括了抽象目录树,datanode信息等等,主要保存在了namenode里面,当然secondaryNamenode里面也会保存一些,等会儿再说。

我们这里先看看元数据怎么管理的,以及为什么要管理元数据。

先看看hdfs-site.xml的两个配置项

我们配置了本地目录这两个,就会在对应的目录生成相应的文件和文件夹。

我们看看这个目录下有这两个文件。其中主要的就是current,看看下面有啥。

这个是我的目录下的。

有edits_*******的文件,有edits_inpro......文件,有fsimage镜像文件,还有md5文件,有VERSION,有seen_txid

$dfs.namenode.name.dir/current/seen_txid非常重要,是存放transactionId的文件,format之后是0,它代表的是namenode里面的edits_*文件的尾数,namenode重启的时候,会按照seen_txid的数字恢复。所以当你的hdfs发生异常重启的时候,一定要比对seen_txid内的数字是不是你edits最后的尾数,不然会发生重启namenode时metaData的资料有缺少,导致误删Datanode上多余Block的信息。

edits就是普通的日志文件,我们将所有的操做都记录到这里面。

fsimage就是hdfs的一个镜像。

我们有两个进程,,一个是namenode,一个是secondarynamenode。

secondarynamenode会定期从namenode合并namenode的edits和fsimage,并将新的fsimage返回给namenode。

发布了66 篇原创文章 · 获赞 31 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_43272605/article/details/101100656