千家信息网

Hadoop2.6.0学习笔记(三)HDFS架构

发表于:2025-02-03 作者:千家信息网编辑
千家信息网最后更新 2025年02月03日,鲁春利的工作笔记,谁说程序员不能有文艺范?HDFS Architecture见:http://hadoop.apache.org/docs/r2.6.0/hadoop-project-dist/had
千家信息网最后更新 2025年02月03日Hadoop2.6.0学习笔记(三)HDFS架构

鲁春利的工作笔记,谁说程序员不能有文艺范?



HDFS Architecture见:
http://hadoop.apache.org/docs/r2.6.0/hadoop-project-dist/hadoop-hdfs/HdfsDesign.html
或下载的tar包解压后的
hadoop-2.6.0/share/doc/hadoop/hadoop-project-dist/hadoop-hdfs/HdfsDesign.html

Hadoop分布式文件系统(Hadoop Distributed File System,简称HDFS)是一个分布式的文件系统,运行在廉价的硬件上。HDFS是高容错的,被设计成在低成本硬件上部署,为应用数据提供高吞吐量的访问,适用于具有大规模数据集的应用程序。

说明:分布式应用中数据是分散在不同的机器上的,而通过分布式的文件系统,提供了统一的数据访问方式,屏蔽了底层数据存储位置的差异。


HDFS的设想和目标
1、硬件故障
在集中式环境下,总是假定机器是能够稳定持续运行的;而分布式环境恰恰相反,它认为硬件错误是常态,而非异常情况。HDFS有成百上千的计算机节点组成,每个节点存储部分数据。大量的节点中,任意节点都有可能由于故障而无法提供服务,因此故障检测,快速、自动的故障恢复是HDFS设计的核心架构目标。

2、流式数据访问
运行于HDFS之上的应用程序需要以流式方式来进行数据集的读取。HDFS不是为了通用的目的而设计的,它主要被设计用来实现批量数据处理,而非交互式的数据运算;高吞吐量的数据处理,而非低延迟的数据计算。

3、大数据集
HDFS以支持大数据集合为目标,一个存储在上面的典型文件大小一般都在GB至TB,一个单一HDFS实例应该能支撑数以千万计的文件。

4、一致性模型
HDFS应用对文件要求的是write-one-read-many访问模型。一个文件经过创建、写,关闭之后就不需要改变。这一假设简化了数据一致性问题,使高吞吐量的数据访问成为可能。

5、由移动数据到移动计算的转移
将计算移动到数据附近,比之将数据移动到应用所在显然更好,HDFS提供给应用这样的接口。

6、跨异构硬件和软件平台的可移植性
HDFS被设计成可轻易从一个平台移动到另一个平台。

HDFS Architecture
HDFS采用主/从(master/slave)结构,一个HDFS集群由一个NameNode(简称NN)节点和一定数量的DataNode(简称DN)节点组成。
NN是HDFS集群的master server,是整个HDFS集群的核心,它管理HDFS集群的名称空间,并接收客户端的请求(具体请求还是由DN处理)。DN一般情况下每台slave机器会配置一个,管理slave机器上存储的数据。
当用户上报数据时,数据以数据块(Block)的形式存储在数据节点上,一个文件可能被分割为一个或者多个数据块。
NN执行文件系统的namespace操作,例如打开、关闭、重命名文件和目录,同时维护了block到DN的映射关系。DN在NN的指挥下进行block的创建、删除和复制,以及根据NN维护的block和DN的映射关系处理client的数据读写请求。

说明:
上述为单NN方式,NN存储的是元数据信息,一旦出故障,那么整个HDFS集群就挂了。
部署时一个主机可以同时配置NN和DN,也可以配置多个DN,但很少有人那么干。
数据块是有副本的,默认为3,存储为本机、同一机架内机器、其他机架内机器(机架感知)。
Client端的读写请求都要先和NN打招呼,然后再通过DN真正干活。

HDFS Namespace
HDFS支持传统的层次型文件组织,与大多数其他文件系统类似,用户可以创建目录,并在其间创建、删除、移动和重命名文件。HDFS不支持user quotas和访问权限,也不支持链接(link),不过当前的架构并不排除实现这些特性。Namenode维护文件系统的namespace,任何对文件系统namespace和文件属性的修改都将被Namenode记录下来。应用可以设置HDFS保存的文件的副本数目,文件副本的数目称为文件的 replication因子,这个信息也是由Namenode保存。
说明:
可以通过hdfs dfsadmin -setQuota可以对目录进行限额。
hdfs dfs -setrep可以动态调整副本数目。
hdfs上任何的操作都会记录在edits日志文件中,由参数dfs.namenode.edits.dir指定存放路径。

HDFS Data Replication
HDFS被设计成在一个大集群中可以跨机器地可靠地存储海量的文件。它将每个文件存储成block序列,除了最后一个block,所有的block都是同样的大小。文件的所有block为了容错都会被复制。每个文件的block大小和replication因子都是可配置的。Replication因子可以在文件创建的时候配置,以后也可以改变。
HDFS中的文件是write-one,并且严格要求在任何时候只有一个writer。Namenode全权管理block的复制,它周期性地从集群中的每个Datanode接收心跳包和一个Blockreport。心跳包的接收表示该Datanode节点正常工作,而Blockreport包括了该Datanode上所有的block组成的列表。

1、副本存放
默认情况下,replication因子是3,HDFS的存放策略是第一个副本存放在client连接到的DN节点,一个副本放在同一机架上的另一个节点,最后一个副本放在不同机架上的一个节点。
说明:
HDFS的机架感知不是自适应的,需要管理人员进行配置。
2、副本选择
为了降低整体的带宽消耗和读延时,HDFS会尽量让reader读最近的副本。
3、安全模式
Namenode启动时会进入一个称为Safemode的特殊状态,处在这个状态的Namenode是不会进行数据块的复制的。
Namenode从所有的Datanode接收心跳包和Blockreport。Blockreport包括了某个Datanode所有的数据块列表。
每个block都有指定的最小数目的副本(dfs.namenode.replication.min),当Namenode确认了某个数据块副本的最小数目,那么该block被认为是安全的。
如果一定百分比(dfs.namenode.safemode.threshold-pct)的数据块检测确认是安全的,那么Namenode将退出Safemode状态,接下来它会确定还有哪些数据块的副本没有达到指定数目,并将这些block复制到其他Datanode。

文件系统元数据的持久化
NN存储HDFS Namespace的元数据,任何对文件元数据的修改操作,NN都使用一个称为Editlog的事务日志记录下来。例如,在HDFS中创建一个文件,NN会在Editlog中插入一条记录来表示;同样,修改文件的replication因子也将往Editlog中插入一条记录。NN在本地OS的文件系统上存储Editlog文件,整个文件系统的namespace,包括block到文件的映射、文件的属性,都存储在称为FsImage的文件中,这个文件也是存放在NN所在的文件系统上。
NN在内存中保存者整个文件系统namespace和文件Blockmap的映射,一个4G内存的NN足够支持海量的文件和目录。当NN启动时,它从硬盘读取Editlog和FsImage,讲所有Editlog中的事务作用于FsImage文件,并将新版本的FsImage从内存中flush到硬盘上,然后再truncate这旧的Editlog,因为这个旧的Editlog已经被作用到FsImage上了,该过程称为checkpoint。
DN讲文件保存在本地的文件系统上,但是它并知道关于文件的任何信息。DN不会在一个目录中存放所有文件,相反,它用启发式的方法来确定每个目录中的最佳文件数目,并且在适当的时候创建子目录。当一个DN启动时,它扫描本地文件系统,对这些本地文件产生相应的一个所有HDFS数据块的列表,然后发送报告到DN,这个报告就是BlockReport。

通信协议
所有的HDFS通信协议都是构建于TCP/IP协议之上。客户端通过一个可配置的端口与NN通信,通过ClientProtocol与NN通信;而DN使用DatanodeProtocol与NN通信。ClientProtocol与DatanodeProtocol协议都是基于RPC协议进行的封装。在HDFS的设计中,NN不会主动发起RPC,而只是被动响应DN和Client端的请求。

健壮性
HDFS的主要目标就是实现在失败情况下数据存储可靠性,常见的三种失败为:NN failure、DN failure和网络分割(network partition)。
(1)硬盘数据错误、心跳检测和重新复制
DN定期向NN发送心跳信息,但是网络切割可能导致部分DN失去与NN的连接。NN通过心跳包的缺失检测到这一情况,将这些DN标记为dead,不会再将新的IO请求发给它们。HDFS将无法再访问处于dead状态的DN上存储的数据,因此一些block的副本数将低于配置的阀值。NN不断跟踪需要复制的数据块,并在任何需要的时候启动复制。在下述情况下可能触发重新复制:DN失效、某个block损坏、DN节点磁盘错误或者副本因子增加。

(2)集群均衡
HDFS集群的自动均衡计划,即当DN节点的磁盘空间不足时自动将数据移动到其他节点,或者当某个文件的请求数突然增加时, 复制数据到集群中的其他节点已满足应用需求,但该机制暂未实现。

(3)数据完整性
由于客户端访问时,由于存储设备故障、网络故障或者软件BUG,都有可能导致数据块损坏,HDFS实现了数据内容校验和,当读取数据时会自动检验数据块的完整性,若存在问题,会尝试从其他DN读取数据。

(4)元数据磁盘错误
FsImage和Editlog是HDFS的核心数据结构,它们的损坏将导致整个HDFS集群不可使用。因此,NN可以配置为FsImage和Editlog存储多个副本(dfs.namenode.name.dir配置以逗号分割的多个路径),所有的操作都会对多个副本同步更新。

说明:
NN在HDFS集群中存在单独故障(SPOF)问题。当NN节点失败时,如果没有配置HA则必须进行人工处理,或者讲NN配置为HA模式。

(5)快照
HDFS does not currently support snapshots but will in a future release.


NameNode

NN节点数据在本地存储的位置由hdfs-site.xml文件中参数${dfs.namenode.name.dir}指定。

        dfs.namenode.name.dir        /usr/local/hadoop2.6.0/data/dfs/name

查看${dfs.namenode.name.dir}目录:

[hadoop@nnode name]$ pwd/usr/local/hadoop2.6.0/data/dfs/name[hadoop@nnode name]$ lscurrent[hadoop@nnode name]$

在第一次部署好Hadoop集群之后,需要在NN节点上格式化磁盘

$HADOOP_HOME/bin/hdfs namenode -format

格式化完成后会在${dfs.namenode.name.dir}/current目录下生成如下目录结构:

current目录下有四类文件:

事务日志记录文件(edits);

文件系统映像(fsp_w_picpath);

当前文件系统映像应用过的事务号(seen_txid);

VERSION文件。

[hadoop@nnode current]$ ll -h-rw-rw-r-- 1 hadoop hadoop   42 Nov 21 17:21 edits_0000000000000035252-0000000000000035253-rw-rw-r-- 1 hadoop hadoop   42 Nov 21 17:23 edits_0000000000000035254-0000000000000035255-rw-rw-r-- 1 hadoop hadoop   42 Nov 21 17:25 edits_0000000000000035256-0000000000000035257-rw-rw-r-- 1 hadoop hadoop   42 Nov 21 17:27 edits_0000000000000035258-0000000000000035259-rw-rw-r-- 1 hadoop hadoop   42 Nov 21 17:28 edits_0000000000000035260-0000000000000035261-rw-rw-r-- 1 hadoop hadoop 231K Nov 21 22:29 fsp_w_picpath_0000000000000035842-rw-rw-r-- 1 hadoop hadoop   62 Nov 21 22:29 fsp_w_picpath_0000000000000035842.md5-rw-rw-r-- 1 hadoop hadoop 231K Nov 21 23:29 fsp_w_picpath_0000000000000035930-rw-rw-r-- 1 hadoop hadoop   62 Nov 21 23:29 fsp_w_picpath_0000000000000035930.md5-rw-rw-r-- 1 hadoop hadoop    6 Nov 21 17:27 seen_txid-rw-rw-r-- 1 hadoop hadoop  204 Nov 21 23:29 VERSION

VERSION文件是属性文件:

[hadoop@nnode current]$ cat VERSION #Sat Nov 21 23:29:03 CST 2015# 文件系统唯一标识,首次format时设置,DN注册到NN之前是不知道该值的,可以区分新建的DNnamespaceID=339614018# Cluster标识,DN与这里的需要一致clusterID=CID-61347f43-0510-4b07-ad99-956472c0e49f# NN存储的创建时间,当NN升级后,该值会更新cTime=0# 存储类型(DATA_NOME/NAME_NODE)storageType=NAME_NODE# block pool标识,后续再介绍(192.168.1.117是原来配置的IP地址,后台改成192.168.137.117了)blockpoolID=BP-892593412-192.168.1.117-1431598212853# 用一个负整数来表示HDFS永久数据结构的版本号layoutVersion=-60[hadoop@nnode current]$

seen_txid是记录事务ID的文件,format之后是0,表示NN里面edit-*文件的尾数,事务最后一次被应用到fsp_w_picpath的id

-rw-rw-r-- 1 hadoop hadoop      42 Nov 21 17:27 edits_0000000000000035258-0000000000000035259-rw-rw-r-- 1 hadoop hadoop      42 Nov 21 17:28 edits_0000000000000035260-0000000000000035261-rw-rw-r-- 1 hadoop hadoop  236143 Nov 21 22:29 fsp_w_picpath_0000000000000035842-rw-rw-r-- 1 hadoop hadoop      62 Nov 21 22:29 fsp_w_picpath_0000000000000035842.md5-rw-rw-r-- 1 hadoop hadoop  236027 Nov 21 23:29 fsp_w_picpath_0000000000000035930-rw-rw-r-- 1 hadoop hadoop      62 Nov 21 23:29 fsp_w_picpath_0000000000000035930.md5-rw-rw-r-- 1 hadoop hadoop       6 Nov 21 17:27 seen_txid-rw-rw-r-- 1 hadoop hadoop     204 Nov 21 23:29 VERSION[hadoop@nnode current]$ cat seen_txid 35260[hadoop@nnode current]$

edits文件为NN保存的事务日志文件,存储位置由${dfs.namenode.edits.dir}指定,默认取NN节点数据文件位置${dfs.namenode.name.dir}。

fsp_w_picpath文件存储的是NN节点的元数据文件。

说明:

当namenode -format命令执行的时候,在namenode节点和datanode节点的VERSION中都会产生一个namespaceID值,并且这两个值必须相同。如果再次执行格式化,那么namenode会产生一个新的namespaceID,但是datanode不会产生新的值。


示例一:查看edits文件

bin/hdfs oev -i edits_0000000000000000057-0000000000000000186   -o edits.xml

示例二:查看fsp_w_picpath文件

bin/hdfs oiv -p XML -i fsp_w_picpath_0000000000000000055  -o fsp_w_picpath.xml


DataNode

DN节点数据的存储位置也是通过hdfs-site.xml文件进行配置:

         dfs.datanode.data.dir         /usr/local/hadoop2.6.0/data/dfs/data

DN节点数据存储结构:

/usr/local/hadoop2.6.0/data/dfs/data|---current|------BP-892593412-192.168.1.117-1431598212853|-------current|---------------dfsUsed|-------------------168801504 1448121566578|---------------finalized|-------------------subdir0|-----------------------subdir0  subdir1  subdir10  subdir11  subdir2  ......  subdir9(目录)|-------------------------  -rw-rw-r-- 1 hadoop hadoop 1377 Nov 21 16:53 blk_1073744377|-------------------------  -rw-rw-r-- 1 hadoop hadoop   19 Nov 21 16:53 blk_1073744377_3560.meta|-------------------------  -rw-rw-r-- 1 hadoop hadoop 1438 Nov 21 16:53 blk_1073744378|-------------------------  -rw-rw-r-- 1 hadoop hadoop   19 Nov 21 16:53 blk_1073744378_3561.meta|-------------------------  -rw-rw-r-- 1 hadoop hadoop 1671 Nov 21 16:53 blk_1073744379|-------------------------  -rw-rw-r-- 1 hadoop hadoop   23 Nov 21 16:53 blk_1073744379_3562.meta|---------------rbw(空目录)|---------------VERSION|-------------------#Sat Nov 28 12:03:36 CST 2015|-------------------namespaceID=339614018|-------------------cTime=0|-------------------blockpoolID=BP-892593412-192.168.1.117-1431598212853|-------------------layoutVersion=-56|-----------dncp_block_verification.log.curr|-----------dncp_block_verification.log.prev|-----------tmp(空目录)----------------|-------VERSION|-----------#Sat Nov 28 12:03:36 CST 2015|-----------storageID=DS-e1bf6500-fc2f-4e73-bfe7-5712c9818965|-----------clusterID=CID-61347f43-0510-4b07-ad99-956472c0e49f|-----------cTime=0|-----------datanodeUuid=33c2f4cb-cd26-4530-9d9b-40d0b748f8b8|-----------storageType=DATA_NODE|-----------layoutVersion=-56|---in_use.lock|-------14187(对应的DataNode进程的进程号,可通过ps -ef|grep DataNode查看)


通过hdfs命令上传一个文件到hdfs:

[hadoop@dnode1 subdir0]$ ll -h ~/httpdomainscan_192.168.1.101_0_20130913160407.hsl -rwxrwxr-x 1 hadoop hadoop 180M Nov 28 12:06 /home/hadoop/httpdomainscan_192.168.1.101_0_20130913160407.hsl


在DN节点目录current/finalized/subdir0/subdir14下能看到新创建了两个bock块:

-rw-rw-r-- 1 hadoop hadoop 128M Nov 28 12:12 blk_1073745442-rw-rw-r-- 1 hadoop hadoop 1.1M Nov 28 12:12 blk_1073745442_4628.meta-rw-rw-r-- 1 hadoop hadoop  52M Nov 28 12:12 blk_1073745443-rw-rw-r-- 1 hadoop hadoop 411K Nov 28 12:12 blk_1073745443_4629.meta

说明:

HDFS中block块的大小固定为128M,但是当一个数据文件的大小不足一个块大小时,按实际大小分配空间。

我的HDFS集群有两个DN节点副本的参数配置的为2,因此在主机dnode1和dnode2的subdir14目录下都新创建了两个节点。


NN节点edits文件

# 此时多了一个edits_inprogress_0000000000000036000的文件-rw-rw-r-- 1 hadoop hadoop   42 Nov 21 17:28 edits_0000000000000035260-0000000000000035261-rw-rw-r-- 1 hadoop hadoop 1.0M Nov 28 13:31 edits_inprogress_0000000000000036000-rw-rw-r-- 1 hadoop hadoop 231K Nov 21 22:29 fsp_w_picpath_0000000000000035842-rw-rw-r-- 1 hadoop hadoop   62 Nov 21 22:29 fsp_w_picpath_0000000000000035842.md5-rw-rw-r-- 1 hadoop hadoop 231K Nov 21 23:29 fsp_w_picpath_0000000000000035930-rw-rw-r-- 1 hadoop hadoop   62 Nov 21 23:29 fsp_w_picpath_0000000000000035930.md5-rw-rw-r-- 1 hadoop hadoop    6 Nov 21 17:27 seen_txid-rw-rw-r-- 1 hadoop hadoop  204 Nov 21 23:29 VERSION

再次查看:

# 多了两个事务日志,且seen_txid也更新了(36002)-rw-rw-r-- 1 hadoop hadoop      42 Nov 21 17:28 edits_0000000000000035260-0000000000000035261-rw-rw-r-- 1 hadoop hadoop      42 Nov 28 13:55 edits_0000000000000036000-0000000000000036001-rw-rw-r-- 1 hadoop hadoop      42 Nov 28 13:56 edits_0000000000000036002-0000000000000036003-rw-rw-r-- 1 hadoop hadoop  236143 Nov 21 22:29 fsp_w_picpath_0000000000000035842-rw-rw-r-- 1 hadoop hadoop      62 Nov 21 22:29 fsp_w_picpath_0000000000000035842.md5-rw-rw-r-- 1 hadoop hadoop  236027 Nov 21 23:29 fsp_w_picpath_0000000000000035930-rw-rw-r-- 1 hadoop hadoop      62 Nov 21 23:29 fsp_w_picpath_0000000000000035930.md5-rw-rw-r-- 1 hadoop hadoop       6 Nov 28 13:55 seen_txid-rw-rw-r-- 1 hadoop hadoop     204 Nov 21 23:29 VERSION


查看DN节点元数据信息:

hdfs oiv -p XML -i fsp_w_picpath_0000000000000035842 -o fsp_w_picpath.xml

下载到本地并打开:

到DN节点查找ID为1073741829的数据块文件:

# cd current/finalized/subdir0[hadoop@dnode1 subdir0]$ find . -name "*1073741829*.meta"./subdir0/blk_1073741829_1008.meta[hadoop@dnode1 subdir0]$ cd subdir0[hadoop@dnode1 subdir0]$ ll|grep 1073741829-rw-rw-r-- 1 hadoop hadoop       63 May 27  2015 blk_1073741829-rw-rw-r-- 1 hadoop hadoop       11 May 27  2015 blk_1073741829_1008.meta[hadoop@dnode1 subdir0]$ cat blk_1073741829hello world!lucl123456\r\nceshi\r\n123456\r\nceshi123456[hadoop@dnode1 subdir0]$ hdfs dfs -cat lucl.txthello world!lucl123456\r\nceshi\r\n123456\r\nceshi123456[hadoop@dnode1 subdir0]$

备注:上传了一个hsl文件,但是从edits中未看到日志记录,另外就是fsp_w_picpath一直修改时间一直不变

间隔一段时间后再查看current目录:

-rw-rw-r-- 1 hadoop hadoop      42 Nov 28 19:38 edits_0000000000000036294-0000000000000036295-rw-rw-r-- 1 hadoop hadoop      42 Nov 28 19:40 edits_0000000000000036296-0000000000000036297-rw-rw-r-- 1 hadoop hadoop 1048576 Nov 28 19:40 edits_inprogress_0000000000000036298-rw-rw-r-- 1 hadoop hadoop  235504 Nov 28 18:08 fsp_w_picpath_0000000000000036205-rw-rw-r-- 1 hadoop hadoop      62 Nov 28 18:08 fsp_w_picpath_0000000000000036205.md5-rw-rw-r-- 1 hadoop hadoop  235504 Nov 28 19:08 fsp_w_picpath_0000000000000036263-rw-rw-r-- 1 hadoop hadoop      62 Nov 28 19:08 fsp_w_picpath_0000000000000036263.md5-rw-rw-r-- 1 hadoop hadoop       6 Nov 28 19:40 seen_txid-rw-rw-r-- 1 hadoop hadoop     204 Nov 21 23:29 VERSION

查看edits文件:

  -60      OP_START_LOG_SEGMENT          36029            OP_TIMES          36030      0      /user/hadoop/lucl.txt      -1      1448694798698            OP_END_LOG_SEGMENT          36031      

查看fsp_w_picpath文件:

    20980    FILE    httpdomainscan_192.168.1.101_0_20130913160407.hsl    2    1448683960850    1448683943208    134217728    hadoop:hadoop:rw-r--r--                        1073745442            4628            134217728                            1073745443            4629            53807068            

说明:通过fsp_w_picpath能够了解到文件与数据块的关系,但是无法知道数据库与节点的关系。

org.apache.hadoop.hdfs.server.namenode.NameNode * NameNode serves as both directory namespace manager and * "inode table" for the Hadoop DFS.  There is a single NameNode * running in any DFS deployment.  (Well, except when there * is a second backup/failover NameNode, or when using federated NameNodes.) * * The NameNode controls two critical tables: *   1)  filename->blocksequence (namespace) *   2)  block->machinelist ("inodes") * * The first table is stored on disk and is very precious. * The second table is rebuilt every time the NameNode comes up.


启动过程会读取fsp_w_picpath文件:

NN在启动时会去加载fsp_w_picpath中的数据,构造元数据结构。


在启动的过程中会处于safemode模式,此时HDFS的数据是不看操作的,默认时间是30秒。


启动成功后sfaemode会被关闭


NN节点显示已启动


0