HDFS源码系列(一)细说NameNode

1,052 阅读4分钟

hdfs源码剖析系列基于hadoop2.7.5版本,如有理解有误之处请指出。

总所周知,hadoop三大组件hdfs,yarn以及mapreduce。hdfs作为一个分布式存储文件系统在大数据生态圈中占据相当重要的地位。

在hdfs中主要角色有NameNodeDataNode以及secondarynamenode

  • NameNode

    接受客户端的读写请求

    存储元数据信息

    接收datanode的心跳

    分配block的存储节点

  • DataNode

    处理客户端的读写请求

    存储数据

    定时发送心跳给NameNode

  • SecondaryNameNode

    合并editlog以及fsimage,降低NameNode启动时间

相关概念

namespace

hdfs的命名空间指的是以"/"为根的整个目录树,它通过FSDirectory类来管理。

在FSDirectory中有个inodeMap字段,该字段记录了根目录下的所有INode,INode的详细内容见下文。

inode table

如果对linux比较熟悉,那么看到inode很容易联想到linux的inode。 hdfs正是借鉴了Linux的inode,将文件和目录都抽象成INode。

根据实际类型其实际引用的类也不同,如果实际类型为目录则实际引用的类为INodeDirectory,如果实际类型为文件则实际引用的类为INodeFile。

阅读INodeFile类可得知类中有个有个私有成员变量blocks,它的类型为BlockInfoContiguous[],从变量名的命名不难推出,blocks记录的是文件的block块。

接着我们进入BlockInfoContiguous类,可以看到在它内部有bc以及triplets这两个成员变量,bc记录了该block归属于哪个文件,而triplets则记录了block的副本保存在了那些DataNode上。

本章只对NameNode进行简单的概述,不详细介绍这些类了,后期笔者会再对这些类进行讲解。

根据以上两点可以看出namespace管理了文件和block关系,而INode管理了Block块与DataNode的关系。

editlog与fsimage

在hdfs中,各种文件操作都会被记录到editlog,并且定时合并到fsimage,这样的一个过程被称为checkpoint。一般由SNN(secondary namenode)去负责合并的工作。

主要影响合并时机的为 dfs.namenode.checkpoint.period(合并间隔,默认3600秒。在hdfs2.x被标志为过时配置)dfs.namenode.checkpoint.txns(两次checkpoint之间最大的记录数)

fs.checkpoint.period,fs.checkpoint.size以及 dfs.namenode.checkpoint.size在hdfs2.x被标志为过时配置。建议使用官方建议的这两个配置控制checkpoint。

虽然NameNode启动也会合并fsimage和editlog,但是如果没有SNN定期合并去分担压力,那么当NameNode长时间运行后重启,editlog和fsimage的合并会极大影响NameNode的启动时间。

高可用机制

看到这不难看出NameNode在hdfs中负责着相当重要的作用,但是在hdfs1.x版本中的NameNode有单点故障的问题,为了解决单点故障问题在hdfs2.0以后引入的高可用机制。在高可用机制下,NameNode分为active以及standby两种状态,active状态代表这个NamaNode为主NameNode,反之则代表为备用NameNode。当主节点因为异常下线时备用节点会从standby状态变为active状态接管hdfs。大致流程如下图

image.png

在高可用环境下,每台NameNode节点上都会多一个zkfc进程(ZooKeeperFailoverController),它会去监控本地NameNode健康状态并且与zk集群维持一个session。

当本地NameNode状态健康并且zk中某个znode不存在,会去请求加锁(创建znode),如果成功加锁(成功创建znode)赢得选举,该节点就会成为active节点。

当zkfc检测到NameNode状态异常时则会删除zk中的那个znode,并且另外节点上的zkfc收到事件通知,并重新开始选举。

以上便是本文章的全部内容,感谢各位大佬看到这里。本章内容主要对namespace以及inode进行我个人的理解,并且简单对高可用流程进行描述。至于像hdfs的读写流程以及其中的数据本地化等等,博主打算在后续hdfs读写流程源码文章中进行。另外后期可能也会对高可用进行更深更细致的讲解,后面的文章更新要看笔者的时间。由于笔者目前还是萌新,有理解错误以及改进的地方希望各位大佬指出。