在 hadoop 1.x 的 HDFS 框架中只存在一个 namenode 节点,当这个 namenode 节点出现内存溢出、宕机等意外状况以后,整个系统就会中止服务,直到咱们重启这个 namenode 节点。为了解决这个问题,在 hadoop2.x 的 HDFS 框架中,实现了 HA 的机制,接下来咱们来看看 2.x 中的这个机制是如何保证系统的高可用。node
1.x 只存在一个 namenode 才不能保证系统长时间运行,所以第一个关键点就是为这个系统多添加几个 namenode 节点,当其中一个 namenode 挂掉以后,其余 namenode 顶上提供服务,不过存在多个 namenode 会提升系统的复杂性,所以在 2.x 的 HDFS 高可用架构,只配备了两个 namenode 节点(active 和 standby)。系统运行过程当中,只有 active 节点才对外提供服务,standby 节点负责同步 edit 文件,与本地的 fsimage 文件合并,这样就保证它们存储数据的一致性了。网络
可是在同步 edit 文件也有面临一个问题,即是同步 edit 文件的频率改如何设定?若是 active 每插入一条文件,standby 就要同步一条数据,那么系统的性能就会降低很多;若是按照必定的时间间隔去同步 edit 文件,那么系统就有可能存在丢失数据的风险,所以第二个关键点就是设计能够共享 edit 文件的系统,active 节点负责往这个系统的 edit 文件写入数据,standby 节点负责同步这个系统中的 edit 文件。架构
因为这个系统存储着 edit 文件,所以咱们要保证这个系统也是高可用的,hadoop 提供了两个方案 -- QJM(Quorum Journal Manager) 和 NFS,我将重点放在 QJM 上,想要了解 NFS 的小伙伴能够看下 这篇博客 。QJM 包含 2N+1 个 journal 节点,每一个 journal 节点提供了一个简单的 RPC 接口,容许 namenode 读取或写入数据。当 namenode 写入 edit 文件时,它向集群中的 journal node 发送写入请求,只有当 N+1 个节点写入成功时,才表明客户端的写入是成功的。框架
如今系统的架构愈来愈清晰了,两个 namenode 节点,一个共享 edit 文件系统,active 节点写入数据,standby 节点同步 edit 文件,系统看似能够长时间提供服务了,但其中仍是存在问题。假设有这样一种场景,active 节点运行过程当中网络断了,此时系统误觉得其不能提供服务了,将 standby 节点转变为 active 节点了。但是以前的 active 节点网络恢复以后仍是能够提供服务的,这时系统中就存在两个 namenode 节点,运行过程当中就会存在各类各样的问题了,这种状况称为脑裂。这就是 HA 机制的第三个关键点 -- 如何防止脑裂问题的发生。ssh
在 QJM 中,是经过 epoch 数来解决脑裂问题的。当 namenode 变为 active 状态时,会分配到一个 epoch 数,这个数是独一无二的,而且比以前的全部 namenode 持有的 epoch 数要高。当 namenode 向 journal 发送消息时,会带上这个数。journal node 收到消息时,只有当这个 epoch 比本地存储的 opoch 数大时才会处理该请求,不然拒绝这次请求。oop
经过 epcho 数只是切断了这个 namenode 和 journal node 集群的通讯,可是客户端仍然能够和这个 namenode 通讯,因为这个 namenode 不能和 journal node 通讯,所以没法处理客户端的请求,这样就会致使客户端没法对系统就行操做,为了解决这个问题,HDFS 提供了 fencing 机制,当 standby 节点转变为 active 节点时,会经过 ssh 的方式发送一条命令,杀掉另外一台机器上的 namenode 进程,确保系统只有一个 active 的 namenode 节点存在,这样就解决了脑裂的问题。源码分析
上面的内容只是讲到了当 namenode 不能提供服务以后咱们的解决方案,可是并无提到咱们如何检测 namenode 是否挂掉了,以及如何将 stangdy 节点转变为 active 节点。这就是 HA 机制的第四个关键点 -- 何时以及如何进行故障转移。性能
如下部分参考 blog.csdn.net/Androidlush…ui
为了检测 namenode 是否挂掉,HDFS 引入了 zookeeper,当一个 namenode 被成功切换为 active 状态时,它会在 zookeeper 内部建立一个临时的 znode,在这个 znode 中将保留当前 active nodenode 的一些信息,好比主机名等等。当 active nanode 出现失败的状况下,监控程序会将 zookeeper 上对应的临时 znode 删除,znode 的删除事件会主动触发到下一次的 active namenode 的选择。.net
为了解决故障转移的问题,HDFS 引入了 ZKFC(ZKFailoverController) 组件,它是 HDFS HA 自动切换的核心对象,也就是咱们日常在 namenode 节点上启动的 ZKFC 进程,在这个进程内部,运行这 3 个服务对象:
当 HealthMonitor 检测到当前 namenode 不健康时,ZKFailoverController 会调用 ActiveStandbyElector 中的 quitElection 方法,从而使自身暂时退出 Active 状态;若是 namenode 状态健康,则会调用 ActiveStandbyElector 中的 joinElection,参与 namenode 的选举。这是故障转移的大体过程,详细的源码分析能够参考上面那篇文章。
把 HDFS 中的四个关键点解决了以后,咱们对于 HA 机制也有了充分的了解,下面给出它的总体架构图:
以上是我对 HDFS HA 机制的总结,若是当中存在错误,欢迎指出!