Hadoop实战-中高级部分 之 HDFS原理 HDFS负载均衡 机架感知 健壮性 文件删除恢复机制
第五部分: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 课程里详 细的讲解。