一、概念与HA思路

1. 首先Hadoop架构为主从架构(NameNode/DataNode)
2. NameNode管理着文件系统和与维护客户端访问DataNode
3. Hadoop 2.0 之前的版本,集群中NameNode存在单点故障(SPOF)
4. 单个NameNode机器宕机将导致集群无法使用,直到管理员重启
5. 单个NameNode机器升级时也会导致集群无法使用
6. HDFS HA用于解决单节点故障(使用Active/Standby两个NameNode交替)
   方案一:借助质量好的机器进行读写操作保证日志数据一致
   方案二:使用类似与Zookeeper(2n+1特效) 备份日志数据(保证日志数据的安全性),两个NameNode共同管理一份元数据
   方案三:使用Zookeeper
7. 使用方案二,日志交于JournalNode进程管理,日志节点为奇数个
   AvtiveNameNode启动时接收DataNode心跳汇报,StandbyNameNode也需要
   使用JournalNode至少需要3个节点
8. 既然ActiveNameNode有可能会宕掉,那么客户端如何去找到StandbyNameNode
   这其中有一个Proxy(代理)用于告知客户端
9. ActiveNameNode与StandbyNameNode通过隔离机制互不干预
   通过代理找到ActiveNameNode,通过Zookeeper选主操作转移故障
10.既然ResourceManager也是一个分布式的系统,同样也可能出现单节点故障

二、部署与搭建测试

  1. 目录规划(hdfs存储位置,JournalNode存储位置,等)
  2. 上传并解压Hadoop
  3. 配置自定义(这仅仅配置HDFS NameNode HA)

*.env
# 配置JDK路径
hdfs-site.xml
# 服务配置
dfs.nameservices-->ns1
dfs.ha.namenodes.ns1-->nn1,nn2
dfs.namenode.rpc-address.ns1.nn1-->hadoop09-linux-01.ibeifeng.com:8020
dfs.namenode.rpc-address.ns1.nn2-->hadoop09-linux-02.ibeifeng.com:8020
dfs.namenode.http-address.ns1.nn1-->hadoop09-linux-01.ibeifeng.com:50070
dfs.namenode.http-address.ns1.nn2-->hadoop09-linux-02.ibeifeng.com:50070
# JournalNode存储配置(注意新建自定义目录)
dfs.namenode.shared.edits.dir-->qjournal://hadoop09-linux-01.ibeifeng.com:8485;hadoop09-linux-02.ibeifeng.com:8485;hadoop09-linux-03.ibeifeng.com:8485/ns1
dfs.journalnode.edits.dir-->/home/liuwl/opt/app/hadoop-2.5.0/data/dfs/jn
# 隔离机制
dfs.ha.fencing.methods-->sshfence
# 注意测试那几个节点是否能够连通 ssh hadoop09-linux-01.ibeifeng.com
dfs.ha.fencing.ssh.private-key-files-->/home/liuwl/.ssh/id_rsa
# 访问文件系统权限
dfs.permissions.enabled-->false
core-site.xml
fs.defaultFS-->hdfs://ns1
hadoop.tmp.dir-->/home/liuwl/opt/app/hadoop-2.5.0/data/tmp
hadoop.http.staticuser.user-->liuwl
slaves
hadoop09-linux-01.ibeifeng.com
hadoop09-linux-02.ibeifeng.com
hadoop09-linux-03.ibeifeng.com

  4. 分发配置文件目录(注意刚才新建的data/dfs/jn,其他节点也要保持一致)

scp -r hadoop/ [email protected]:/home/liuwl/opt/app/hadoop-2.5.0/etc
scp -r hadoop/ [email protected]:/home/liuwl/opt/app/hadoop-2.5.0/etc

  5. 分别启动Zookeeper(转13步)

bin/zkServer start

  6. 分别启动JournalNode服务

sbin/hadoop-daemon.sh start journalnode

  7. 在nn1所在节点进行格式化文件系统,并启动

bin/hdfs dfs namenode -format
sbin/hadoop-daemon.sh start namenode

  8. 在nn2所在节点进行同步元数据信息,并启动

bin/hdfs namenode -bootstrapStandby
sbin/hadoop-daemon.sh start namenode

  9. 将nn1切换为Active(手动切换)

bin/hdfs haadmin -transitionToActive nn1

  10. 在nn1所在节点启动所有datanode

sbin/hadoop-daemon.sh start datanode

  11. kill掉nn1上的namenode,并手动设置nn2为Active

nn1: kill -9 xxx/sbin/hadoop-daemon.sh stop namenode
nn2: bin/hdfs haadmin -transitionToActive nn2 --forceactive

  12. 网页上查看namenode状态或使用命令

bin/hdfs haadmin -getServiceState nn2

  13. 使用Zookeeper自动转移故障

hdfs-site.xml
dfs.ha.automatic-failover.enabled-->false
core-site.xml
ha.zookeeper.quorum-->hadoop09-linux-01.ibeifeng.com:2181,hadoop09-linux-02.ibeifeng.com:2181,hadoop09-linux-03.ibeifeng.com:2181

  14. 按照官方文档,需要初始化Zookeeper,注意每个节点上的Zookeeper服务为开启状态(转13步)

bin/hdfs zkfc -formatZK
# 单独启动zookeeper的故障转移监控器(DFSZKFailoverController),每个namenode都有一个
sbin/hadoop-deamon.sh start zkfc

  15. 测试Zookeeper存储

../zookeeper-3.4.6/bin/zkCli.sh

  16. 启动yarn,上传一个wc.input,节点三运行MR程序,运行时,kill掉ActiveNameNode

sbin/start-yarn.sh
bin/yarn jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.5.0.jar wordcount tmp/mapreduce/wordcount/input tmp/mapreduce/wordcount/output
kill -9 xxx
# 查看namenode状态
# 分析结论:DFSZKFailoverController监控NameNode状态,NameNode宕掉,监听器马上告诉Zookeeper,
# Zookeeper告知Standby的DFSZKFailoverController,进入切换Active流程
# DFSZKFailoverController进行选主操作,
# 确保新的Active节点,然后通过RPC将StandbyNameNode切换为ActiveNameNode,完成故障转移
# HA 解决了元数据共享,Active切换,隔离,并保证了元数据的安全性

  17. ResourceManager HA (支持一个ActiveResourceManager对应多个StandbyResourceManager)

yarn-site.xml
# 运行MapRedue程序必配
yarn.nodemanager.aux-services-->mapreduce_shuffle
# 配置日志聚集功能
# 日志聚集是YARN提供的日志中央化管理功能,
# 它能将运行完成的Container/任务日志上传到HDFS上,
# 从而减轻NodeManager负载,且提供一个中央化存储和分析机制,
# 默认情况下,Container/任务日志是存在各个NodeManager上的
yarn.log-aggregation-enable-->true
# 在HDFS上聚集的日志最多保存多长时间
yarn.log-aggregation.retain-seconds-->604800
# 使用ResourceManager HA
yarn.resourcemanager.ha.enabled-->true
# 添加一个ResourceManager集群ID
yarn.resourcemanager.cluster-id-->yarn-cluster
# 指定两个ResouceManager
yarn.resourcemanager.ha.rm-ids-->rm109,rm110
# 指定ResourceManager所在机器
yarn.resourcemanager.hostname.rm109-->hadoop09-linux-02.ibeifeng.com
yarn.resourcemanager.hostname.rm110-->hadoop09-linux-03.ibeifeng.com
# 配置Zookeeper机器地址
yarn.resourcemanager.zk-address-->hadoop09-linux-01.ibeifeng.com:2181,hadoop09-linux-02.ibeifeng.com:2181,hadoop09-linux-03.ibeifeng.com:2181
# ResourceManager恢复
yarn.resourcemanager.recovery.enabled-->true
# 修改ResourceManager默认存储日志的方式
yarn.resourcemanager.store.class-->org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore
# 分发到各个节点

  18. 分别启动(之前先启动Zookeeper)

节点1:sbin/start-dfs.sh
节点1:sbin/start-yarn.sh
节点1:sbin/start-yarn.sh

  19. 打开web查看各类信息,当使用节点3打开resourcemanager,发现它会自动重定向到节点2
  20. 节点1测试一个mr程序,断掉节点2的ResourceManager,查看web

bin/yarn jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.5.0.jar wordcount tmp/mapreduce/wordcount/input tmp/mapreduce/wordcount/output2
kill -9 xx
# 当kill节点2的ResourceManager的一瞬间,节点报错(连接超时)
# java.io.IOException: Failed on local exception: java.io.EOFException; Host Details : local host is: "hadoop09-linux-01.ibeifeng.com/10.0.0.108"; destination host is: "hadoop09-linux-02.ibeifeng.com":8032;
# 打开节点3的web页面发现该程序仍在运行,即由节点3的ResoreceManager接管执行mr程序
# 过了几十秒后mr程序成功运行完毕
# 内部已设置一个监控器,所以可以自动切换

  21. 进入Zookeeper客户端查看

../zookeeper-3.4.6/bin/zkCli.sh
[zk: localhost:2181(CONNECTED) 0] ls /
[rmstore, yarn-leader-election, hadoop-ha, zookeeper]
[zk: localhost:2181(CONNECTED) 1] ls /rmstore
[ZKRMStateRoot]
[zk: localhost:2181(CONNECTED) 2] ls /rmstore/ZKRMStateRoot
[RMAppRoot, RMVersionNode, RMDTSecretManagerRoot]
05-08 15:33