HDFS(Hadoop Distributed File System)是Hadoop项目的核心子项目,是Hadoop主要应用的一个分布式文件系统。实际上,Hadoop中有一个综合性的文件系统抽象,它提供了文件系统实现的各类接口,HDFS只是这个抽象文件系统的一个实例。
Hadoop的文件系统
Hadoop整合了众多文件系统,它首先提供了一个高层的文件系统抽象org.apache.hadoop.fs.FileSystem,这个抽象类展示了一个分布式文件系统,并有几个具体实现,如下表所示。
文件系统 |
UR方案 |
Java实现(org.apache.hadoop) |
定义 |
Local |
file |
fs.LocalFileSystem |
支持有客户端校验和的本地文件系统。带有校验和的本地文件系统在fs.RawLocalFileSystem中实现 |
HDFS |
hdfs |
hdfs.DistributeFileSystem |
Hadoop的分布式文件系统 |
HFTP |
hftp |
hdfs.HftpFileSystem |
支持通过HTTP方式以只读的方式访问HDFS,distcp经常用在不同的HDFS集群间复制数据 |
HSFTP |
hsftp |
hdfs.HsftpFileSystem |
支持通过HTTPS方式以只读的方式访问HDFS |
HAR |
har |
fs.HarFileSystem |
构建在其他文件系统上进行归档文件的文件系统。Hadoop归档文件主要用来减少NameNode的内存使用 |
KFS |
kfs |
fs.kfs.KosmosFileSystem |
Cloudstroe(其前身是Kosmos文件系统)文件系统是类似于HDFS和Google的GFS的文件系统,使用C++编写 |
FTP |
ftp |
fs.ftp.FtpFileSystem |
由FTP服务器支持的文件系统 |
S3(本地) |
s3n |
fs.s3native.NativeS3FileSystem |
基于Amazon S3的文件系统 |
S3(基于块) |
s3 |
fs.s3.NativeS3FileSystem |
基于Amazon S3的文件系统,以块格式存储解决了S3的5GB文件大小的限制 |
Hadoop提供了许多文件系统接口,用户可使用URI方案选取合适的文件系统来实现交互。比如,想要列出本地文件系统的目录,那么可以执行以下shell命令:
hadoop fs -ls file:///
HDFS简介
总的来说,HDFS主要有以下特点:
1) 处理超大文件
这里的超大文件通常是指数百MB,甚至数百TB大小的文件。目前在实际应用中,HDFS已经能用来存储管理PB级的数据了。
2) 流式地访问数据
HDFS的设计建立在更多地响应“一次写入,多次读取”任务的基础之上。这意味着一个数据集一旦由数据源生成,就会被复制分发到不同的存储节点中,然后响应各种各样的数据分析任务请求。在大多数情况下,分析任务都会涉及数据集中的大部分数据,也就是说,对HDFS来说,请求读取整个数据集要比读取一条记录更加高效。
3) 运行于廉价的商用机器集群上
4) 不适合低迟延数据访问
HDFS是为了处理大型数据集分析任务,主要是为了达到高的数据吞吐量而设计的,这就要求可能以高延迟作为代价。目前有一些补充方案,比如HBase,通过上层数据管理项目来尽可能的弥补这个不足。
5) 无法高效存储大量小文件
在Hadoop中需要用NameNode(名称节点)来管理文件系统的元数据,以响应客户端请求返回文件位置。因此文件数量大小的限制要由NameNode来决定。例如,每个文件索引目录及块大约占100字节,如果有100万个文件,每个文件占一个块,那么至少要消耗200MB内存,这似乎还可以接受。但如果有更多文件,那么NameNode的工作压力更大,检索处理元数据所需的时间就不可接受了。
6) 不支持多用户写入及任意修改文件
在HDFS的一个文件中只有一个写入者,而且写操作只能在文件末尾完成,即只能执行追加操作。目前HDFS还不支持多个用户对同一个文件的写操作以及在文件任意位置进行修改。
HDFS的相关概念
块
在操作系统中都有一个文件块的概念,文件以块的形式存储在磁盘中,此处块的大小代表系统读/写可操作的最小文件大小。也就是说,文件系统每次只能操作磁盘块大小的整数倍数据。
这里我们介绍的HDFS中的块是一个抽象的概念,它比上面操作系统中所说的块要大得多。在配置Hadoop系统时会看到,它的默认块大小为64MB。和单机上的文件系统相同,HDFS分布式文件系统中的文件也被分成块进行存储,它是文件存储处理的逻辑单元。
HDFS作为一个分布式文件系统,设计是用来处理大文件的,使用抽象的块会带来很多好处。
1) 可以存储任意大的文件而不受网络中任一单节点磁盘大小的限制。
可以想象一下,单个节点存储100TB的数据是不可能的,但是由于逻辑块的设计,HDFS可以将这个超大的文件分成众多块,分别存储在集群的各个机器上。
2) 使用抽象块作为操作的单元可以简化存储子系统。
HDFS中的块大小固定,这样它简化了存储系统的管理,特别是元数据信息可以和文件块内容分开存储。
3) 块更有利于分布式文件系统中复制容错的实现。
在HDFS中,为了处理节点故障,默认将文件块副本设定为3份,分别存储在集群的不同节点上。当一个块损坏时,系统会通过NameNode获取元数据信息,在另外的机器上读取一个副本并进行存储,这个过程对于用户来说都是透明的。当然,这里的文件块冗余量可以通过文件进行配置,比如在有些应用中,可能会为操作频繁较高的文件块设置较高的副本数量以提高集群的吞吐量。
NameNode
NameNode可以说是HDFS的中心服务器,它负责管理文件系统的命名空间(NameSpace),比如打开、关闭、重命名文件或目录,负责确定数据块到具体DataNode节点的映射,那它是怎么做到呢?因为NameNode控制了两个关键表:
① filename->blocksequen(namespace image,即文件fsimage),相对而言是静态的,存储在磁盘上。
② block->machinelist (“inodes“) 相对而言动态,存储在内存中,每次NameNode重启时都会重建这些信息。
SecondaryNameNode
HA的一个解决方案。但不支持热备。配置即可。
SecondaryNameNode周期性从NameNode上下载元数据信息(fsimage,edits),然后把二者合并,生成新的fsimage,在本地保存,并将其推送到NameNode,同时重置NameNode的edits。
更详细的请看HDFS文件结构->编辑日志及文件系统映像这一章节。
DataNode
DataNode在文件系统相当于Worker,用来执行具体的任务:存储文件块,被客户端和NameNode调用。同时,它会通过心跳(Heartbeat)定时向NameNode发送所存储的文件块信息。
副本存放与读取策略
副本的存放是HDFS可靠性和性能的关键,优化的副本存放策略也正是HDFS区分于其他大部分分布式文件系统的重要特性。HDFS采用一种称为机架感知(rack-aware)的策略来改进数据的可靠性、可用性和网络带宽的利用率。
大型HDFS实例一般运行在跨越多个机架的计算机组成的集群上,不同机架上的两台服务器之间的通信需要经过交换机,这样会增加数据传输的成本。在大多数情况下,同一个机架内的两台机器间的带宽会比不同机架的两台机器间的带宽大。
一方面,通过一个机架感知的过程,NameNode可以确定每个DataNode所属的机架ID。目前HDFS采用的策略就是将副本存放在不同的机架上,这样可以有效防止整个机架失效时数据的丢失,并且允许读数据的时候充分利用多个机架的带宽。这种策略设置可以将副本均匀地分布在集群中,有利于在组件失效情况下的负载均衡。但是,因为这种策略的一个写操作需要传送数据块到多个机架,这增加了写操作的成本。
举例来看,在大多数情况下,副本系统是3,HDFS的存放策略是将一个副本存放在本地机架的节点上,另一个副本放在同一个机架的另一个节点上,第三个副本放在不同机架的节点上。这种策略减少了机架间的数据传输,提高了写操作的效率。机架的错误远比节点的错误少,所以这个策略不会影响数据的可靠性和可用性。同时,因为数据块只放在两个不同的机架上,所以此策略减少了读取数据时需要的网络传输总带宽。这一策略在不损害数据可靠性和读取性能的情况下改进了写的性能。
另一方面,在读取数据时,为了减少整体的带宽消耗和降低整体的带宽延迟时,HDFS会尽量让读取程序读取离客户端最近的副本。如果在读取程序的同一个机架上有一个副本,那么久读取该副本;如果一个HDFS集群跨越多个数据中心,那么客户端也将首先读取本地数据中心的副本。
安全模式
NameNode在启动的时候首先进入安全模式,。处于安全模式的NameNode不会进行数据块的复制,且文件系统中的内容不允许修改也不允许删除,直到安全模式结束。在这个阶段NameNode相当于block->machinelist表的重建过程。NameNode从所有的DataNode接收心跳信号和块状态报告。块状态报告包括了某个DataNode所有的数据块列表。每个数据块都有一个指定的最小副本数(dfs.replication.min)。当NameNode检测确认某个数据块的副本数据达到最小值时,该数据块被认为是安全的;在一定百分比(dfs.safemode.threshold.pct默认是0.999,如果设为1则HDFS永远是处于SafeMode)的数据块NameNode检测确认是安全之后(加上一个额外dfs.safemode.extension默认30秒等待时间),NameNode将退出安全模式状态。接下来它会确认还有哪些数据块的副本没有达到指定书目,并将这些数据块复制到其他DataNode上。
下面这行摘录自NameNode启动时的日志(block上报比例1达到了阀值0.9990)
The ratio of reported blocks 1.0000 has reached the threshold 0.9990. Safe mode will be turned off automatically in 18 seconds.
用户可以通过dfsadmin -safemode value 来操作安全模式,参数value的说明如下:
enter – 进入安全模式
leave – 强制NameNode离开安全模式
get – 返回安全模式是否开启的信息
wait – 等待,一直到安全模式结束。
参考资料:Hadoop实战 第2版 陆嘉恒著
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/9161.html