HDFS核心设计

  • 心跳机制
  • 安全模式
  • 副本存放策略
  • 负载均衡

HDFS相关概念

HDFS(Hadoop Distributed File System Hadoop)分布式文件系统,主要用来解决海量数据的存储问题

HDFS中的文件在物理上是分块(block)存储,块的大小可以通过配置参数(dfs.blocksize)来规定,默认在Hadoop2.x版本中是128MB。

HDFS文件的各个block的存储管理由DataNode节点承担,DataNode是HDFS集群从节点,每一个block都可以在多个DataNode上存储多个副本(副本数量可以通过参数设置dfs.replication,默认是3)。

HDFS是设计成适应一次写入,多次读出的场景,不支持文件的修改。

HDFS核心API:Configuration、FileSystem。

HDFS架构解释

在上一篇的Hadoop集群环境搭建中对集群规划分为:NameNode、DataNode、SecondaryNameNode以及ResourceManager和NodeManager。我们只知道需要这样去规划一个基本的分布式集群,并不知其所以然,那么这里对HDFS部分名词阐释:

主节点Namenode:掌管文件系统目录树,管理文件系统的元数据(一个block元信息消耗大约150byte的内存),负责保持和分配文件副本的数量,并处理客户端读写的请求。客户端请求访问HDFS都是通过向NameNode申请来进行的。

从节点DataNode:存储整个集群的所有的数据块,处理真正的数据读写。通过心跳机制定期汇报给NameNode有关block的信息。

SecondaryNameNode:严格说并不是NameNode备份节点,而是NameNode的助手,主要给NameNode分担压力之用。

下图可以很好的帮助理解

HDFS design

HDFS核心设计

心跳机制(HearBeat)

在上面架构解释中说到,DataNode通过心跳机制定期汇报给NameNode有关block的信息,那么HDFS的心跳机制是什么原理呢?

我们知道,Hadoop是Master(NameNode、ResourceManager)/Slave(DataNode、NodeManager)结构,Master启动的时候会启动一个IPC(Inter-Process Comunocation,进程通信)server服务,等待Slave的连接;而Slave启动时,会主动连接master的IPC server服务,并且是每隔3秒连接一次master,这个每隔一段时间去连接一次的机智,我们形象的称为心跳

Slave通过心跳汇报自己的信息给Master,Master也通过心跳给Slave下达命令;NameNode通过心跳得知DataNode的状态,ResourceManager 通过心跳得知 NodeManager 的状态。如果Master长时间都没有收到slave的心跳,就认为slave挂掉了,那么NameNode感知到Data挂掉死亡的时长是怎么计算的呢?

原理是这样的:DataNode启动好了之后,会专门启动一个线程来负责给NameNode发送心跳数据包,如果整个DataNode没有任何问题,但是仅仅只是当前负责发送信息的数据包线程挂掉了,那么NameNode会发送命名向这个DataNode进行确认,如果第一次没有返回结果,仅且只会检查第二次。如果发送数据包线程没有问题,是DataNode出现了某些问题,就没有DataNode的汇报;HDFS的标准: 如果连续10次没有收到DataNode的汇报,那么NameNode就会认为该DataNode存在宕机的可能。

这里需要查看hdfs-site.xml配置文件中的两个相关设置:

1
2
3
4
5
6
7
8
<property>
<name>heartbeat.recheck.interval</name>
<value>5000</value>
</property>
<property>
<name>dfs.heartbeat.interval</name>
<value>3</value>
</property>

那么计算公示就可以出来:timeout=2*heartbeat.recheck.interval+10*dfs.heartbeat.interval

需要注意的是,heartbeat.recheck.interval时间单位是ms(毫秒,默认为5分钟),dfs.heartbeat.interval时间单位是s(秒,默认为3秒)。

安全模式

安全模式是HDFS的自我保护数据安全的措施,当NameNode发现集群中的block丢失率(默认为0.999f,可修改dfs.safemode.threshold.pct手动配置)达到一定比例时,NameNode就会进入安全模式,在安全模式下,客户端不能对HDFS上的任何数据进行操作,只能查看元数据信息。

安全模式常用操作命令:

强制NameNode退出安全模式:hadoop dfsadmin -safemode leave

进入安全模式:hadoop dfsadmin -safemode enter

查看安全模式状态:hadoop dfsadmin -safemode get

等待安全模式结束:hadoop dfsadmin -safemode wait

副本存放策略

数据分块存储和副本的存放是保证可靠性和高性能的关键

副本存放策略说明:HDFS默认的副本数是3,第一个Block副本放在客户端所在的Node里,如果客户端不在集群范围,则第一个Node随机选取(不会选择太满和太忙的Node),第二个副本放置到与第一个节点不同的机架中的其中一个Node,第三个副本在和第二个副本在同一个机架,随机放在不同的Node中。

下图Block1-3表示三个副本。

replications

修改副本数:

修改集群文件hdfs-site.xml:

1
2
3
4
<property>
<name>dfs.replication</name>
<value>2</value>
</property>

命令设置:命令+副本数+文件夹路径或某个文件路径

bin/hadoop fs -setrep -R 2 /

负载均衡

节点与节点之间磁盘利用率不平衡是HDFS集群非常容易出现的情况(集群内新增,删除节点,某个节点机器内一个盘存储达到饱和等)当HDFS负载不均衡时,需要对HDFS进行数据的负载均衡调整,数据均衡过程的核心是一个数据均衡算法。进行数据的负载均衡调整必须满足以下原则:

  • 数据平衡不能导致数据块减少,数据备份的丢失
  • 管理员可以终止数据平衡进程
  • 每次移动的数据量以及占用的网络资源必须是可控的
  • 数据均衡过程中,不能影响NameNode的正常工作

影响Balancer的几个参数:

- threshold:默认设置是10,参数范围0-100,判断集群是否平衡的阀值,理论上设置的越小,整个集群越平衡

dfs.balance.bandwidthPerSec:默认值是1048576(1M/S),Balancer运行时允许占用的带宽

用命令设置:

hadoop dfsadmin -setBalanacerBandwidth 10485760

sbin/start-balancer.sh -t(threshold) 10%

在hdfs-site.xml配置文件中设置bandwidthPerSec:

1
2
3
4
5
<property>
<name>dfs.balance.bandwidthPerSec</name>
<value>10485760</value>
<description>负载均衡时的带宽大小设置</description>
</property>