第五部分:HDFS负载均衡
HDFS的数据也许并不是非常均匀的分布在各个DataNode中。一个常见的原因是在现有的集群上经常会增添新的DataNode节点。当新增一个数据块(一个文件的数据被保存在一系列的块中)时,NameNode在选择DataNode接收这个数据块之前,会考虑到很多因素。其中的一些考虑的是:
•将数据块的一个副本放在正在写这个数据块的节点上。
•尽量将数据块的不同副本分布在不同的机架上,这样集群可在完全失去某一机架的情况下还能存活。
•一个副本通常被放置在和写文件的节点同一机架的某个节点上,这样可以减少跨越机架的网络I/O。
•尽量均匀地将HDFS数据分布在集群的DataNode中。
第六部分:HDFS机架感知
HDFS机架感知
通常,大型
Hadoop 集群是以机架的形式来组织的,同一个机架上不同 节点间的网络状况比不同机架之间的更为理想。 另外,
NameNode 设法将 数据块副本保存在不同的机架上以提高容错性。
而
HDFS 不能够自动判断集群中各个
datanode 的网络拓扑情况
Hadoop允 许集群的管理员通过配置
dfs.network.script 参数来确定节点所处的机架。 文件提供了
IP->rackid 的翻译。
NameNode 通过这个得到集群中各个
datanode 机器的
rackid
。 如果
topology.script.file.name 没有设定,则每个
IP 都会翻译 成
/
default-rack
。
java代码:
int main(int argc , char *argv[]) { for(int i=1 ;i< argc; i++) { char* ipStr = argv[i]; // 找到ip对应的rack设置,下面的 cout<<"/rack1/"<<i<<" "; } cout<< endl; }
有了机架感知,
NameNode 就可以画出上图所示的
datanode 网络拓扑图。
D1,R1 都是交换机,最底层是
datanode
。 则
H1 的
rackid=/D1/R1/H1
,
H1的
parent 是
R1
,
R1 的是
D1
。 这些
rackid 信息可以通过
topology.script.file.name 配置。有了这些
rackid 信息就可以计算出任意两台
datanode 之间的距离。
distance(/D1/R1/H1,/D1/R1/H1)=0 相同的
datanode
distance(/D1/R1/H1,/D1/R1/H2)=2 同一
rack 下的不同
datanode
distance(/D1/R1/H1,/D1/R1/H4)=4 同一
IDC 下的不同
datanode
distance(/D1/R1/H1,/D2/R3/H7)=6 不同
IDC 下的
datanode
第七部分:HDFS访问
访问方式
HDFS 给应用提供了多种访问方式。用户可以通过
Java API 接口访问,也可以通过
C 语言的封装
API 访问,还可以通过浏览器的方式访问
HDFS 中的文 件。
第八部分:HDFS 健壮性
HDFS 的主要目标就是即使在出错的情况下也要保证数据存储的可靠性。 常见的三种出错情况是:
Namenode 出错
,
Datanode 出错和网络割裂
(
network partitions)
。
磁盘数据错误,心跳检测和重新复制
每个
Datanode 节点周期性地向
Namenode 发送心跳信号。网络割裂可能导致一部分
Datanode 跟
Namenode 失去联系。
Namenode 通过心跳信号的缺失来检测这一情况,并将这些近期不再发送心跳信号
Datanode 标记为宕机 ,不会再将新的
IO 请求发给它们。任何存储在宕机
Datanode 上的数据将不 再有效。
Datanode 的宕机可能会引起一些数据块的副本系数低于指定值,
Namenode 不断地检测这些需要复制的数据块,一旦发现就启动复制操作。 在下列情况下,可能需要重新复制:某个
Datanode 节点失效,某个副本遭 到损坏,
Datanode 上的硬盘错误,或者文件的副本系数增大。
数据完整性
从某个
Datanode 获取的数据块有可能是损坏的,损坏可能是由
Datanode 的存储设备错误、网络错误或者软件
bug 造成的。
HDFS 客户端软 件实现了对
HDFS 文件内容的校验和
(checksum) 检查。当客户端创建一个新 的
HDFS 文件,会计算这个文件每个数据块的校验和,并将校验和作为一个 单独的隐藏文件保存在同一个
HDFS 名字空间下。当客户端获取文件内容后 ,它会检验从
Datanode 获取的数据跟相应的校验和文件中的校验和是否匹 配,如果不匹配,客户端可以选择从其他
Datanode 获取该数据块的副本。
元数据磁盘错误
FsImage 和
Editlog 是
HDFS 的核心数据结构。如果这些文件损坏了,整个
HDFS 实例都将失效。因而,
Namenode 可以配置成支持维护多个
FsImage 和
Editlog 的副本。任何对
FsImage 或者
Editlog 的修改,都将同步到它们的副 本上。这种多副本的同步操作可能会降低
Namenode 每秒处理的名字空间事 务数量。然而这个代价是可以接受的,因为即使
HDFS 的应用是数据密集的 ,它们也非元数据密集的。当
Namenode 重启的时候,它会选取最近的完整 的
FsImage 和
Editlog 来使用。
Namenode 是
HDFS 集群中的单点故障
(single point of failure) 所在。如果
Namenode 机器故障,是需要手工干预的。目前,自动重启或在另一台机器 上做
Namenode 故障转移的功能还没实现。
快照
快照支持某一特定时刻的数据的复制备份。利用快照,可以让
HDFS 在 数据损坏时恢复到过去一个已知正确的时间点。
HDFS 目前还不支持快照功 能,但计划在将来的版本进行支持。
第九部分:HDFS 文件删除恢复机制
当用户或应用程序删除某个文件时,这个文件并没有立刻从
HDFS 中删除。实际上,
HDFS 会将这个文件重命名转移到
/trash 目录。只要文件还在
/trash 目录中,该文件就可以被迅速地恢复。文件在
/trash 中保存的时间是可 配置的,当超过这个时间时,
Namenode 就会将该文件从名字空间中删除。 删除文件会使得该文件相关的数据块被释放。注意,从用户删除文件到
HDFS 空闲空间的增加之间会有一定时间的延迟。
只要被删除的文件还在
/trash 目录中,用户就可以恢复这个文件。如果 用户想恢复被删除的文件,他
/ 她可以浏览
/trash 目录找回该文件。
/trash 目 录仅仅保存被删除文件的最后副本。
/trash 目录与其他的目录没有什么区别 ,除了一点:在该目录上
HDFS 会应用一个特殊策略来自动删除文件。目前 的默认策略是删除
/trash 中保留时间超过
6 小时的文件。将来,这个策略可以 通过一个被良好定义的接口配置。
开启回收站
Hdfs
-site.xml
<configuration>
<property>
<name>fs.trash.interval</name>
<value>
1440
</value>
<description>Number ofminutes between trash checkpoints.
If zero, the trashfeature is disabled.
</description>
</property>
</configuration>
1, fs.trash.interval 参数设置保留时间为
1440 秒
(1 天
)
2,
回收站的位置:在
HDFS 上的 /
user/$USER/.Trash/Current/
hdfs-site.xml
<configuration>
<property>
<name>fs.trash.interval</name>
<value>
1440</value>
<description>Number ofminutes between trash checkpoints.
If zero, the trashfeature is disabled.
</description>
</property>
</configuration>
1, fs.trash.interval参数设置保留时间为1440秒(1天)
2, 回收站的位置:在HDFS上的 /user/$USER/.Trash/Current/
第十部分:HDFS缺点
大量小文件
因为 Namenode 把文件系统的元数据放置在内存中,所以文件系统所能 容纳的文件数目是由 Namenode 的内存大小来决定。一般来说,每一个文件 、文件夹和 Block 需要占据 150 字节左右的空间,所以,如果你有 100 万个文 件,每一个占据一个 Block ,你就至少需要 300MB 内存。当前来说,数百万 的文件还是可行的,当扩展到数十亿时,对于当前的硬件水平来说就没法实 现了。还有一个问题就是,因为 Map task 的数量是由 splits 来决定的,所以 用 MR 处理大量的小文件时,就会产生过多的 Maptask ,线程管理开销将会 增加作业时间。举个例子,处理 10000M的文件,若每个 split 为 1M ,那就会 有 10000 个 Maptasks ,会有很大的线程开销;若每个 split 为 100M ,则只有 100 个 Maptasks ,每个 Maptask 将会有更多的事情做,而线程的管理开销也 将减小很多。
单节点问题
NameNode 如果失效,整个集群将瘫痪。我们会在
Hadoop HA 课程里详 细的讲解。