通过联合使用在多个文件系统中备份namenode的元数据和通过备用namenode创建监测点能防止数据丢失,但是依旧无法实现文件系统的高可用性。namenode依旧存在单点失效的问题。如果namenode失效了,那么所有的客户端,包括MapReduce作业,均无法读、写或列举文件,因为namenode是唯一存储元数据与文件到数据块映射的地方。在这一情况下,Hadoop系统无法提供服务直到有可用的namenode上线。
在这样的情况下,要想从一个失效的namenode恢复,系统管理员得启动一个拥有文件系统元数据副本的新的namenode,并配置datanode和客户端以便使用这个新的namenode。新的namenode直到满足以下情形才能相应服务:
- 将命名空间的映像导入到内存中;
- 重启编辑日志;
- 接收到足够多的来自datanode的数据块报告并退出安全模式。对于一个大型并拥有大量文件和数据块的集群,namenode的冷启动需要30分钟,甚至更长时间。
系统恢复时间太长,也会影响到日常维护。事实上,预期外的namenode失效出现的概率很低,所以在现实中,计划内的失效时间实际更为重要。
Hadoop2针对上述问题增加了对HDFS高可用性的支持。在这一实现中,配置了一对活动-备用(active-standby)namenode。当活动namenode失效,备用namenode就会接管它的任务并开始服务于来自客户端的请求,不会有任何明显的中断。实现这一场景需要在架构上做如下的修改:
- namenode之间需要通过高可用共享存储实现编辑日志的共享。当备用namenode接管工作之后,它将通读共享编辑日志直至末尾,以实现与活动namenode的状态同步,并继续读取由活动namenode写入的新数据。
- datanode需要同时向两个namenode发送数据块处理报告,因为数据块的映射信息存储在namenode的内存中,而不是磁盘。
- 客户端需要使用特定的机制来处理namenode的失效问题。这一机制对用户来说是透明的。
- 辅助namenode的角色被备用namenode所包含,备用namenode为活动的namenode命名空间设置周期性检查点。
可以从两种高可用性共享存储做出选择:NFS过滤器或群体日志管理器(QJM)。QJM是一个专用的HDFS实现,为提供一个高可用的编辑日志而设计,被推荐用于大多数HDFS部署中。QJM以一组日志节点的形式运行,每一次编辑必须写入多数日志节点(journal node)。典型的,有三个journal节点,所以系统能够忍受其中任何一个的丢失。这种安排与Zookeeper的工作方式类似,当然必须知道,QJM的实现并没有使用Zookeeper。
在活动namenode失效之后,备用namenode能够快速实现任务接管,因为最新的状态存储在内存中,包括最新的编辑日志条目和最新的数据块映射信息。实际观察到的失效时间略长一点,大约1分钟左右,这是因为系统需要判断活动的namenode是否真的失效了。
在活动namenode失效且备用namenode也失效的情况下(当然这类情况发生的概率不大),管理员依旧可以声明一个备用namenode并实现冷启动。这类情况并不会比非高可用性(non-HA)的情况更差,并且从操作的角度来说这是一个进步,因为上述处理已经是一个标准的处理过程并植入Hadoop中。
文本中涉及的名词汇总:
- POSIX:可移植操作系统界面
- NFS:网络文件系统
- HA:高可用
- non-HA:非高可用
- 堆外块缓存:off-heap block cache
- 缓存池:cache pool
- 命名空间卷:namespace volume
- 数据块池:block pool
- 单点失效:SPOF,全词single point of failure
- QJM:群体日志管理器,quorum journal manager
- 日志节点:journal node
- 故障转移控制器:failover controller
- 平稳故障转移:graceful failover
--摘自《Hadoop权威指南》