HDFS(二)高可用架构

引言

在 hadoop 1.x 的 HDFS 框架中只存在一个 namenode 节点,当这个 namenode 节点出现内存溢出、宕机等意外情况之后,整个系统就会停止服务,直到我们重启这个 namenode 节点。为了解决这个问题,在 hadoop2.x 的 HDFS 框架中,实现了 HA 的机制,接下来我们来看看 2.x 中的这个机制是如何保证系统的高可用。

架构

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 机制的第三个关键点 -- 如何防止脑裂问题的发生。

在 QJM 中,是通过 epoch 数来解决脑裂问题的。当 namenode 变为 active 状态时,会分配到一个 epoch 数,这个数是独一无二的,并且比之前的所有 namenode 持有的 epoch 数要高。当 namenode 向 journal 发送消息时,会带上这个数。journal node 收到消息时,只有当这个 epoch 比本地存储的 opoch 数大时才会处理该请求,否则拒绝此次请求。

通过 epcho 数只是切断了这个 namenode 和 journal node 集群的通信,但是客户端仍然可以和这个 namenode 通信,由于这个 namenode 不能和 journal node 通信,因此无法处理客户端的请求,这样就会导致客户端无法对系统就行操作,为了解决这个问题,HDFS 提供了 fencing 机制,当 standby 节点转变为 active 节点时,会通过 ssh 的方式发送一条命令,杀掉另一台机器上的 namenode 进程,确保系统只有一个 active 的 namenode 节点存在,这样就解决了脑裂的问题。

故障转移

上面的内容只是讲到了当 namenode 不能提供服务之后我们的解决方案,但是并没有提到我们如何检测 namenode 是否挂掉了,以及如何将 stangdy 节点转变为 active 节点。这就是 HA 机制的第四个关键点 -- 什么时候以及如何进行故障转移。

以下部分参考 https://blog.csdn.net/Androidlushangderen/article/details/53148213

为了检测 namenode 是否挂掉,HDFS 引入了 zookeeper,当一个 namenode 被成功切换为 active 状态时,它会在 zookeeper 内部创建一个临时的 znode,在这个 znode 中将保留当前 active nodenode 的一些信息,比如主机名等等。当 active nanode 出现失败的情况下,监控程序会将 zookeeper 上对应的临时 znode 删除,znode 的删除事件会主动触发到下一次的 active namenode 的选择。

为了解决故障转移的问题,HDFS 引入了 ZKFC(ZKFailoverController) 组件,它是 HDFS HA 自动切换的核心对象,也就是我们平常在 namenode 节点上启动的 ZKFC 进程,在这个进程内部,运行这 3 个服务对象:

  • HealthMonitor:监控 namenode 是否不可用或是进入了一个不健康的状态
  • ActiveStandbyElector:控制和监控 ZK 上的节点状态
  • ZKFailoverController:协调 HealMonitor 和 ActiverStandbyElector 对象,处理它们发来的 event 变化事件,完成自动切换的过程。

当 HealthMonitor 检测到当前 namenode 不健康时,ZKFailoverController 会调用 ActiveStandbyElector 中的 quitElection 方法,从而使自身暂时退出 Active 状态;如果 namenode 状态健康,则会调用 ActiveStandbyElector 中的 joinElection,参与 namenode 的选举。这是故障转移的大致过程,详细的源码分析可以参考上面那篇文章。

把 HDFS 中的四个关键点解决了之后,我们对于 HA 机制也有了充分的了解,下面给出它的整体架构图:

HDFS的HA机制

以上是我对 HDFS HA 机制的总结,如果当中存在错误,欢迎指出!

猜你喜欢

转载自www.cnblogs.com/firepation/p/11442735.html