本文将从NameNode,DataNode,SecondaryNameNode,心跳检测,负载均衡五个方面展开讨论HDFS架构。
HDFS整体架构
首先上一张简单的架构图:
其中:
- 大多数分布式大数据框架都是主从架构。
- HDFS也是主从架构(其中,Master称为管理节点,Slave称为工作节点)
- 主叫NameNode,中文名称为"名称节点"。
- 从叫DataNode,中文名称为"数据节点"。
NameNode
文件系统
先谈谈文件系统概念。
- 文件系统(filesystem)概念:操作系统中负责管理文件,存储文件信息的软件。具体地说,它负责为用户创建文件,存入,读取,修改,转储,删除文件等。
再说说与文件系统有关的几个概念。
-
元数据(metadata):关于用户或目录的描述信息,如文件所在路径,文件名称,文件类型等等,这些信息被称为文件的元数据信息。如:
注意:元数据的概念在其它的的数据框架中也屡有提及。
- 命名空间
- 文件系统中,为了便于管理存储介质上的,给每个目录、目录中的文件、子目录都起了名字,这样形成的层级结构,称之为命名空间。
- 同一目录中,不能有同名的文件或目录。
- 用处:这样通过目录+文件名称的方式能够唯一的定位一个文件。
HDFS-NameNode
- HDFS本质上也是文件系统filesystem,所以它也有元数据metadata;
- 元数据metadata保存在NameNode内存中;
- NameNode作用
- HDFS的主节点,负责管理文件系统的命名空间,将HDFS的元数据存储在NameNode节点的内存中。
- 负责响应客户端对文件的读写请求。
- HDFS元数据
-
文件目录树、所有的文件(目录)名称、文件属性(生成时间、副本、权限)、每个文 件的块列表、每个block块所在的datanode列表。
- 每个文件,目录,block占用大概150Bytes字节的元数据;所以HDFS适合存储大文件,不适合存储小文件(1000个1M的文件和1000个150M的文件所占用的元数据内存是一样多的,但是后者在hdfs上存储的文件更多)。
-
HDFS元数据信息以两种形式保存:编辑日志(edits log)和命名空间镜像文件(fsimage)
(1). edits log:HDFS编辑日志文件 ,保存客户端对HDFS的所有更改记录,如增、删、重命名文件(目录),这些操作会修改HDFS目录树;NameNode会在编辑日志edit日志中记录下来;(类似于MySQL中的binlog)
(2). fsimage:HDFS元数据镜像文件 ,即将namenode内存中的数据落入磁盘生成的文件;保存了文件系统目录树信息以及文件、块、datanode的映射关系,如下图:
-
- hdfs-site.xml中属性dfs.namenode.edits.dir的值决定;用于namenode保存edits log文件。
- hdfs-site.xml中属性dfs.namenode.name.dir的值决定;用于namenode保存fsimage文件。
DataNode
DataNode数据节点的作用比较简单,主要是存储block元数据到datanode本地磁盘;此处的元数据包括数据块的长度,块数据的校验和,时间戳。
SecondaryNameNode
在解释SecondaryNameNode之前,先看看如下2个问题。
- 为什么元数据存储在NameNode的内存中?
答:当HDFS Client需要读写文件时,首先HDFS Client连接到NameNode,获取文件的元数据信息,知道了当前想要访问的文件的block分别存放在哪些DataNode节点上,然后HDFS Client分别连接这些DataNode,然后读写文件。当HDFS Client很多的时候,如果将元数据存储在磁盘上的话,这些Client想要访问这些元数据信息就会特别慢,但是如果将元数据保存在内存中就不一样了。 - 这样做有什么问题?如何解决?
答:这样的问题是:一旦NameNode节点系统故障,会导致保存在NameNode节点内存中的元数据丢失。解决方式:edits log已经记录了客户端对HDFS的所有的更改的操作记录(如增,删,改,重命名文件或者目录)。如果系统故障,重启之后,可以从edits log进行恢复(edits log回放这些操作记录)。但edits log日志大小随着时间变得越来越大,导致系统重启根据日志恢复的时候会变得越来越长;为了避免这种情况,引入检查点机制checkpoint,命名空间镜像fsimage就是根据HDFS数据的持久性检查点,即将内存中的元数据落地磁盘生成的文件。NameNode如果重启,可以将磁盘中的fsimage文件读入到内存,将元数据恢复到某一个检查点,然后再回放检查点之后记录的编辑日志,最后完全恢复元数据。但是依然,随着时间的推移,edits log记录的日志会变多,那么当NameNode重启,恢复元数据过程中,会花越来越长的时间执行edits log中的每一个日志;而在NameNode元数据恢复期间,HDFS不可用。
为了解决这个问题,引入了SecondaryNameNode辅助NameNode,用来合并fsimage和edits log。
-
SecondaryNameNode合并fsimage和edits log详细流程如下:
- SecondaryNameNode首先请求原NameNode进行edits的滚动,这样新的编辑操作就能够进入新的文件中。
- SecondaryNameNode通过HTTP GET方式读取原NameNode中的fsimage及edits log。
- SecondaryNameNode读取fsimage到内存中,然后回放edits log中的每个操作,并创建一个新的统一的fsimage文件。
- SecondaryNameNode通过HTTP PUT方式将新的fsimage发送到原NameNode。
- 原NameNode用新的fsimage替换旧的fsimage,同时系统会更新fsimage文件到记录检查点的时间。
- 这个过程结束后,NameNode就有了最新的fsimage文件和更小的edits log文件。
-
SecondaryNameNode定期做checkpoint检查点操作的两大条件:
- SecondaryNameNode每隔1小时创建一个检查点
- 另外,SecondaryNameNode每1分钟检查一次,从上一检查点开始,edits log文件中是否已包括100万个事务,如果是,也会创建检查点。
SecondaryNameNode一般部署在另外一台节点上,因为它需要占用大量的CPU时间,并需要和NameNode一样多的内存,来执行合并操作。
- 查看edits log和fsimage
hdfs oev -i edits_0000000000000000256-0000000000000000363 -o /home/hadoop/edit1.xml
hdfs oiv -p XML -i fsimage_0000000000000092691 -o fsimage.xml
执行以上两个命令后,会将二进制格式的edits log和fsimage转化为xml文件。
- checkpoint相关属性(参考hadoop官方文档)
属性 | 值 | 解释 |
---|---|---|
dfs.namenode.checkpoint.period | 3600秒(即1小时) | The number of seconds between two periodic checkpoints. |
dfs.namenode.checkpoint.txns | 1000000 | The Secondary NameNode or CheckpointNode will create a checkpoint of the namespace every 'dfs.namenode.checkpoint.txns' transactions, regardless of whether 'dfs.namenode.checkpoint.period' has expired. |
dfs.namenode.checkpoint.check.period | 60(1分钟) | The SecondaryNameNode and CheckpointNode will poll the NameNode every 'dfs.namenode.checkpoint.check.period' seconds to query the number of uncheckpointed transactions. |
心跳机制
工作原理
- NameNode启动的时候,会开一个ipc server在那里
- DataNode启动后向NameNode注册,每隔3秒钟向NameNode发送一个"心跳heartbeat"
- 心跳返回结果带有NameNode给该DataNode的命令,如复制块数据到另一DataNode,或删除某个数据块
- 如果超过10分钟NameNode没有收到某个DataNode 的心跳,则认为该DataNode节点不可用
- DataNode周期性(6小时)的向NameNode上报当前DataNode上的块状态报告BlockReport;块状态报告包含了一个该 Datanode上所有数据块的列表。
心跳的作用
- 通过周期心跳,NameNode可以向DataNode返回指令
- 可以判断DataNode是否在线
- 通过BlockReport,NameNode能够知道各DataNode的存储情况,如磁盘利用率、块列表;跟负载均衡有关
- hadoop集群刚开始启动时,99.9%的block没有达到最小副本数(dfs.namenode.replication.min默认值为1),集群处于安全模式,涉及BlockReport;
心跳相关配置
心跳间隔
属性 | 值 | 解释 |
---|---|---|
dfs.heartbeat.interval | 3 | Determines datanode heartbeat interval in seconds. |
- blockreport
属性 | 值 | 解释 |
---|---|---|
dfs.blockreport.intervalMsec | 21600000 (6小时) | Determines block reporting interval in milliseconds. |
-
查看hdfs-default.xml默认配置文件
负载均衡
- 什么原因会有可能造成不均衡?
- 机器与机器之间磁盘利用率不平衡是HDFS集群非常容易出现的情况。
- 尤其是在DataNode节点出现故障或在现有的集群上增添新的DataNode的时候。
- 为什么需要均衡?
- 提升集群存储资源利用率。
- 从存储与计算两方面提高集群性能。
- 如何手动负载均衡?
$HADOOP_HOME/sbin/start-balancer.sh -t 5% # 磁盘利用率最高的节点若比最少的节点,大于5%,触发均衡。
小结:
- NameNode负责存储元数据,存在内存中。
- DataNode负责存储block块及块的元数据。
- SecondaryNameNode主要负责对HDFS元数据做checkpoint操作。
- 集群的心跳机制,让集群中各节点形成一个整体;主节点知道从节点的死活。
- 节点的上下线,导致存储的不均衡,可以手动触发负载均衡。