对管理hadoop来说,深入了解namenode和辅助的namenode即secondarynamenode十分重要。namenode的目录结构主要如下:
${dfs.name.dir}/current/VERSION /edits /fsimage /fstime
dfs.name.dir这组目录内存储内容相同,这个机制使系统具备了一定的复原能力,特别是其中一个目录处于NFS之上时!也是特别推荐的配置。
VERSION文件是一个Java属性文件,一般内容如下:
#Tue May 29 11:05:47 CST 2012
namespaceID=1545978810
cTime=0
storageType=NAME_NODE
layoutVersion=-18
layoutVersion是一个负数,这个数只要HDFS布局变更就会递减。
namespaceID是文件系统的唯一标识,在format的时候生成。
cTime属性标记了namenode存储系统的创建时间,对于刚格式化的值为0,升级后会有新时间戳。
storageType属性说明该存储目录包含的是namenode的数据结构。
另外的三个文件edits、fsimage、fstime是二进制文件。这些文件都是用Hadoop的Writable对象作为其序列化格式。fsimage文件包含文件系统中的所有目录和文件inode的序列化信息。每个inode都是一个文件或目录的元数据的内容描述方式。他们之间的工作联系是,客户端有写操作时,这些操作首先被记录到编辑日志中,namenode在内存中维护文件系统的元数据;当编辑日志被修改时,相关元数据信息也同步更新。内存中的元数据可支持客户端的读请求。
在每次执行写操作之后,且在像客户端发送成功代码之前,编辑日志都需要更新同步。当namenode向多个目录写数据时,只有在所在写操作均执行完毕之后方可返回成功代码,以确保任何操作都不会因为机器故障而丢失。
fsimage文件是文件元数据的一个永久性检查点。并非每一个写操作都会更新这个文件,因为fsimage是个大文件,如果频繁执行写操作,会使系统运行极为缓慢。但这个特性根本不会降低系统的恢复能力,因为如果namenode发生故障,可以先把fsimage文件载入到内存重构新近的元数据,再执行编辑日志记录的各项操作。事实上,namenode在启动阶段正是这样做的。
这样会使edits文件无限增长。尽管这种情况对namenode的运行没有影响,但由于需要恢复编辑日志中的各项操作,namenode重启操作会比较慢,这段时间内文件系统处于离线状态,造成无法使用。解决方案就是运行辅助namenode,为主namenode内存中的文件系统元数据创建检查点。创建检查点的步骤如下:(参见下图)
(1)、namenode响应Secondary namenode请求,将edit log推送给Secondary namenode,开始重新写一个新的edit log。 (2)、Secondary namenode收到来自namenode的fsimage文件和edit log。采用HTTP GET方式。 (3)、Secondary namenode将fsimage加载到内存,应用edit log,并生成一个新的fsimage文件。 (4)、Secondary namenode将新的fsimage推送给Namenode。采用HTTP POST方式。 (5)、Namenode用新的fsimage取代旧的fsimage,在fstime文件中记下检查点发生的时间。
经过这样的一个流程,主namenode拥有最新的fsimage文件和一个更小的edits文件(可能非空,因为这期间namenode能够继续接受客户端操作请求)。当namenode处于安全模式时,管理员也可以调用:
hadoop dfsadmin -saveNamespace
这个命令来创建检查点更新fsimage和edits。这个过程也是为什么secondary namenode需要和主namenode内存相近的服务器的原因。0.21.0版本之后采用的是一种新型namenode,名为backup节点,其目的在于维护一份最新的namenode元数据的备份。
通过配置fs.checkpoint.period(新版本是dfs.namenode.checkpoint.period)属性可以指定创建检查点时间间隔,默认是1小时,值的单位是秒。还有一个属性会触发创建检查点,就是 fs.checkpoint.size(新版本有所改变)属性,默认是当edits大小超过64M时创建。
辅助namenode的作用不仅是为主节点合并fsimage文件,更重要的是也可以用作namenode元数据的备份(尽管非最新),它的目录结构如下:
${fs.checkpoint.dir}/current/VERSION /edits /fsimage /fstime /previouts.checkpoint/VERSION /edits /fsimage /fstime
目录结构和主namenode结构相同,这种设计方案的好处是,在主namenode发生故障时(假设没有及时备份,甚至NFS也没有),可以从辅助namenode用作新的主namenode。一种方法是将相关存储目录复制到新的namenode中;另一种方法是使用-importCheckpoint选项重启辅助namenode守护进程,从而将辅助namenode用作新的住namenode。借助这个选项,dfs.name.dir属性定义的目录中没有元数据时,辅助namenode就从fs.checkpoint.dir目录载入最新的检查点数据。这部分很重要,因为如果要用于企业生产,就必须要保证使用过程中的各种安全性和可靠性。而且hadoop使用的是单主节点模型,如果主节点宕机或者损坏,需要能够快速的恢复。
和namenode不同,datanode的存储目录是启动时自动创建的,不需要额外格式化(所以添加datanode非常方便,新node配置好写入slaves即可)。datanode的关键文件和目录如下:
${dfs.data.dir}/current/VERSION /blk_ /blk_.meta /blk_ /blk_.meta ...... /subdir0/ /subdir1/ ......
VERSION文件内容和namenode的VERSION非常相似,内容类似如下:
#Mon May 28 05:22:10 CST 2012
namespaceID=1545978810
storageID=DS-693259529-10.210.70.61-50010-1337734254397
cTime=0
storageType=DATA_NODE
layoutVersion=-18
相同的就跟namenode的一样,不同的是storageID。各个datanode的storageID都不相同(但对于存储目录是相同的),namenode可用这个属性来识别datanode。storageType表示这个目录是DATA_NODE,区别于NAME_NODE。
current目录下的文件有blk_前缀的,包含两种文件类型:HDFS块文件(仅包含原始数据)和块的元数据文件(含.meta后缀)。元数据文件包括头部(含版本和类型信息)和该块各区段的一系列的校验和。
当目录中数据块的数量增加到一定规模时,datanode会创建一个子目录来存放新的数据块及其元数据信息。这个数量规模由属性dfs.datanode.numblocks进行配置,默认是64块就创建一个子目录。终极目标是设计一棵高扇出的树,只要访问少数几个目录即可获取数据,同时也避免了很多文件放在一个目录之中的难题。如果dfs.data.dir属性指定了不同磁盘上的多个目录,那么数据块会以轮转的方式写到各个目录中。
namenode启动时,是在安全模式下的。它首先将fsimage载入内存,并执行编辑日志中的各项操作。一旦在内存中成功创建文件系统元数据的映像,则创建一个新的fsimage文件(不需要借助SNN)和一个空的编辑日志。此时namenode监听RPC和HTTP请求。这个过程namenode的文件系统对于客户端来说是只读的。即此模式下写、删除或重命名等操作都会失败。
这是因为系统中数据块的位置并不是namenode维护的,而是以块列表的形式存储在datanode中。在系统的正常操作期间,namenode会在内存中保留所有块位置的映射信息。各个datanode会向namenode检查块列表信息(即向namenode发送块列表的最新情况),namenode了解到足够多的块位置信息之后,即可高效运行文件系统。但如果namenode没有检查到足够多的datanode,则需要将块复制到其他datanode,而大多数情况下这都不必要的(因为只要等待检查到若干datanode检入),这会浪费很多资源。所以需要安全模式,在安全模式下namenode并不向datanode发出任何块复制或删除的指令。如果满足“最小复本条件”,namenode会在30秒后退出安全模式,所谓最小复本条件指在整个文件系统中99.9%的块满足dfs.replication.min属性设置的值即可。在启动一个刚刚格式化的HDFS集群时,系统中没有任何块,所以不会进入安全模式。相关的3个属性如下:
dfs.replication.min 默认为1 成功执行写操作需创建的最少复本数目
dfs.safemode.threshold.pct 默认0.999 在namenode退出安全模式前,满足最小复本数的块的比例。设置高于1则不会退出安全模式。
dfs.safemode.extension 最小副本满足后停留安全模式下的时间。默认30000,单位毫秒。
以上属性参考自己用的hadoop版本,可能有所变动。
使用hadoop dfsadmin -safemode 可进行安全模式的查看、进入、离开操作。有时候需要在执行某条命令前退出安全模式,特别是脚本中,可以使用hadoop dfsadmin -wait命令。
各个datanode运行一个块扫描器,定期检测本节点上的所有块。可以从web查看:
http://datanode:50075/blockScannerReport
通过校验和错误检测坏块,同时检测坏磁道等情况。把坏块报告给namenode,检测周期默认504小时,即三周,可通过dfs.datanode.scan.period.hours属性设置该值。
随着hdfs的使用时间推移,各个datanode上的块会分布越来越不均匀,同时降低MapReduce的本地性,导致部分datanode繁忙。均衡器(balancer)程序是一个Hadoop守护进程,它将块从繁忙的datanode移动到相对空闲的datanode,从而重新分配块。它不断移动块,直到集群达到均衡(节点上使用的空间和空间容量比率以及集群各节点的使用率),差距不超出阈值则认为均衡。调用均衡器命令如下:
start-balancer.sh
Hadoop守护进程提供一个网页
http://10.210.70.82:50030/stacks
来监控JVM中运行着的线程的堆栈使用情况。
Hadoop集群添加新节点、删除新节点这部分放集群搭建配置这篇里。
关于Hadoop升级等内容,另行写篇详细的,也等到自己有了实际经验再来写。
5.31 ps:版本升级实践有了,在这里。