鲁春利的工作笔记,谁说程序员不能有文艺范?
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}指定。
<property> <name>dfs.namenode.name.dir</name> <value>/usr/local/hadoop2.6.0/data/dfs/name</value> </property>
查看${dfs.namenode.name.dir}目录:
[hadoop@nnode name]$ pwd /usr/local/hadoop2.6.0/data/dfs/name [hadoop@nnode name]$ ls current [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之前是不知道该值的,可以区分新建的DN namespaceID=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文件进行配置:
<property> <name>dfs.datanode.data.dir</name> <value>/usr/local/hadoop2.6.0/data/dfs/data</value> </property>
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_1073741829 hello world! lucl123456/r/nceshi/r/n123456/r/n ceshi 123456 [hadoop@dnode1 subdir0]$ hdfs dfs -cat lucl.txt hello world! lucl123456/r/nceshi/r/n123456/r/n ceshi 123456 [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文件:
<?xml version="1.0" encoding="UTF-8"?> <EDITS> <EDITS_VERSION>-60</EDITS_VERSION> <RECORD> <OPCODE>OP_START_LOG_SEGMENT</OPCODE> <DATA> <TXID>36029</TXID> </DATA> </RECORD> <RECORD> <OPCODE>OP_TIMES</OPCODE> <DATA> <TXID>36030</TXID> <LENGTH>0</LENGTH> <PATH>/user/hadoop/lucl.txt</PATH> <MTIME>-1</MTIME> <ATIME>1448694798698</ATIME> </DATA> </RECORD> <RECORD> <OPCODE>OP_END_LOG_SEGMENT</OPCODE> <DATA> <TXID>36031</TXID> </DATA> </RECORD> </EDITS>
查看fsp_w_picpath文件:
<inode> <id>20980</id> <type>FILE</type> <name>httpdomainscan_192.168.1.101_0_20130913160407.hsl</name> <replication>2</replication> <mtime>1448683960850</mtime> <atime>1448683943208</atime> <perferredBlockSize>134217728</perferredBlockSize> <permission>hadoop:hadoop:rw-r--r--</permission> <blocks> <block> <id>1073745442</id> <genstamp>4628</genstamp> <numBytes>134217728</numBytes> </block> <block> <id>1073745443</id> <genstamp>4629</genstamp> <numBytes>53807068</numBytes> </block> </blocks> </inode>
说明:通过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节点显示已启动
原创文章,作者:3628473679,如若转载,请注明出处:https://blog.ytso.com/194825.html