hadoop HA
一、 Hadoop 的高可用性
1. 概论
本指南提供了一个HDFS 的高可用性(HA )功能的概述,以及如何配置和管理HDFS 高可用性(HA) 集群。本文档假定读者具有对HDFS 集群的组件和节点类型具有一定理解。有关详情,请参阅Apache 的HDFS 的架构指南。
http://hadoop.apache.org/common/docs/current/hdfs_design.html
2. 背景
CDH4 之前,在HDFS 集群中NameNode 存在单点故障(SPOF )。对于只有一个NameNode 的集群,如果NameNode 机器出现故障,那么整个集群将无法使用,直到NameNode 重新启动。
NameNode 主要在以下两个方面影响HDFS 集群:
(1). NameNode 机器发生意外,比如宕机,集群将无法使用,直到管理员重启NameNode
(2). NameNode 机器需要升级,包括软件、硬件升级,此时集群也将无法使用
HDFS 的HA 功能通过配置Active/Standby 两个NameNodes 实现在集群中对NameNode 的热备来解决上述问题。如果出现故障,如机器崩溃或机器需要升级维护,这时可通过此种方式将NameNode 很快的切换到另外一台机器。
3. 架构
在
一个典型的HDFS(HA) 集群中,使用两台单独的机器配置为NameNodes 。在任何时间点,确保NameNodes
中只有一个处于Active 状态,其他的处在Standby 状态。其中ActiveNameNode
负责集群中的所有客户端操作,StandbyNameNode 仅仅充当备机,保证一旦ActiveNameNode
出现问题能够快速切换。
为了保证Standby 节点与Active 节点的状态保持同步,目前是通过两个节点同时访问一个共享的存储设备( 如NFS) 来实现的,在以后的版本中可能会做进一步的改进。
当Active
节点的namespace 发生改变时,存储在共享目录中的日志文件也会被修改,Standby
节点监测到日志变化后,将其作用到自身的namespace 。当Active 节点发生故障需要进行切换时,Standby 节点由Standby
状态转换为Active 状态前将会把所有未读日志作用到自身的namespace
以确保自身的namespace 与主节点的namespace 保持一致。
为了实现快速切换,Standby 节点获取集群的最新文件块信息也是很有必要的。为了实现这一目标,DataNode 需要配置NameNodes 的位置,并同时给他们发送文件块信息以及心跳检测。
任
意时间只有一个ActiveNameNode 对于HDFS(HA) 集群的正常运行至关重要,否则两者的namespace
将不能保持同步,面临数据丢失和其它问题的危险性。为了防止出现这种情况,管理员必须为共享存储配置至少一个安全机制。这种机制应该保证:
在切换期间,如果不能证实当前Active 节点已经改变了状态,那么此机制应切断当前Active
节点对共享存储的访问,这样可以防止在切换期间当前Active 节点继续对namespace 进行修改,确保新的Active
节点能够安全的切换。
注意:
此版本只支持手动切换,这意味着集群并不能自动检测Active 节点发生故障。
二、 HDFS(HA) 的硬件配置
为了部署一个HA 群集,你应该准备以下几点:
1.NameNode 机器,Active 、Standby 应该具有相同的硬件
2.
共享存储,需要有一个能够保证所有NameNode 读写的共享目录。通常,这应该是一个远程文件系统,支持NFS 和挂载在每个NameNode
机器上。在此版本中,只有一个对共享可编辑目录的支持。这个共享可编辑目录的可用性很有限,因此,为了消除单点故障,必须提高此存储设备的可用性。一个高
品质的专用NAS 设备要好过通过一个简单的Linux
服务器提供NFS 服务的方式。
注意:
在HDFS(HA) 集群中,Standby 节点还执行着对namespace 状态的checkpoint 功能,因此没有必要再运行SecondaryNameNode 、CheckpointNode 、BackupNode 。
三、 HDFS(HA) 的软件配置
1. 配置概述
对于使用一个NameNode 的集群,HA 的配置与HDFS 的Federation 机制是兼容的,新的配置项被设计用在集群中的所有相同类型的节点具有相同的配置,不需要为相同类型节点的不同机器部署不同的配置文件。
HDFS(HA) 集群使用NameServiceID 来标示NameNode ,作为NameNode 的编号。
2. 现有的配置参数
下面的配置参数发生了变化:
core-site.xml
(1)fs.defaultFS - 如果没有配置则使用fs.default.name
Xml代码
<property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster</value>
</property>
3. 新增的配置参数
hdfs-site.xml
(1)dfs.federation.nameservices --- federation 服务名
Xml代码
<property>
<name>dfs.federation.nameservices</name>
<value>mycluster</value>
</property>
(2) 如果同时还使用HDFS 的Federation 机制,则应该使用逗号分隔nameservices 列表
Xml代码
<property>
<name>dfs.federation.nameservices</name>
<value>mycluster,mycluster1</value>
</property>
(3)dfs.ha.namenodes.[nameservice ID] --- 每个NameNode 在名称服务中的唯一标识, 此版本最大只支持两个NameNode
Xml代码
<property>
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2</value>
</property>
(4)dfs.namenode.rpc-address.[nameservice ID] --- rpc 通信地址
Xml代码
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1</name>
<value>machine1.example.com:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>machine2.example.com:8020</value>
</property>
(5)dfs.namenode.http-address.[nameservice ID] --- http 通信地址
Xml代码
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>machine1.example.com:50070</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>machine2.example.com:50070</value>
</property>
(6)dfs.namenode.shared.edits.dir --- 共享存储目录位置
Xml代码
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>file:///mnt/filer1/dfs/ha-name-dir-shared</value>
</property>
4. 客户端故障转移配置
(1)dfs.client.failover.proxy.provider.[nameservice ID] --- HDFS 客户端与Active 节点通信的java 类,使用其确定Active 节点是否活跃
Xml代码
<property>
<name>dfs.client.failover.proxy.provider.mycluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
5. 安全配置
dfs.ha.fencing.methods
--- 用于在Active 节点切换期间的安全机制,确保在任何时间都只有一个NameNode 处于活跃状态。在故障切换期间,haadmin
命令确保在将其它NameNode 转换为Active 状态之前Active 节点处在Standby 状态,或其进程已被终止。
至少应该配置一个,因为没有默认配置,因此如果配置则HA 机制将会失效。
如果要实现自定义的安全机制,参照org.apache.hadoop.ha.NodeFencer
(1)sshfence 方式
通过SSH 连接到ActiveNameNode 杀死监听服务端TCP 监听的进程
Xml代码
<property>
<name>dfs.ha.fencing.methods</name>
<value>sshfence</value>
</property>
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/home/exampleuser/.ssh/id_rsa</value>
</property>
或者配置非标准的用户名和端口以及超时时间
Xml代码
<property>
<name>dfs.ha.fencing.methods</name>
<value>sshfence([[username][:port]])</value>
</property>
<property>
<name>dfs.ha.fencing.ssh.connect-timeout</name>
<value> 60000</value>
</property>
(2)shell 方式
运行脚本实现安全机制
Xml代码
<property>
<name>dfs.ha.fencing.methods</name>
<value>shell(/path/to/my/script.sh arg1 arg2 ...)</value>
</property>
四、 HDFS (HA) 的初始化
设
定所有的必要配置项后,必须首先同步两个NameNode 上的元数据。如果是新建的HDFS 集群,则应首先格式化一个NameNode
,或者想把非HA 集群转换为HA 集群,按照dfs.namenode.name.dir 、dfs.namenode.edits.dir
的配置把当前NameNode 节点的元数据目录复制到另一个NameNode.
还应该确保共享存储目录下(dfs.namenode.shared.edits.dir ) 包含NameNode 所有的元数据。
五、 HDFS(HA) 的管理
sbin/start-dfs.sh
默认以HA 方式启动集群,启动后为Standby 状态,使用如下命令设置Active 节点
# bin/hdfs haadmin –DFSHAadmin –transitionToActive nn1
如果让nn2 成为变为active nn1 变为standby ,则
# bin/hdfs haadmin -DfSHAadmin -failover nn1 nn2
如果失败(is not ready to become active) 则
# bin/hdfs haadmin -DfSHAadmin -failover --forceactive nn1 nn2
Usage: DFSHAAdmin [-ns <nameserviceId>]
[-transitionToActive <serviceId>]
[-transitionToStandby <serviceId>]
[-failover [--forcefence] [--forceactive] <serviceId> <serviceId>]
[-getServiceState <serviceId>]
[-checkHealth <serviceId>]
[-help <command>]