1. Hadoop HA高可用

(1)所谓HA(High Availablity),即高可用(7*24小时不中断服务)。

(2)实现高可用最关键的策略是消除单点故障。HA严格来说应该分成各个组件的HA机制:HDFS的HA和YARN的HA。

(3)Hadoop2.0之前,在HDFS集群中NameNode存在单点故障(SPOF)。

(4)NameNode主要在以下两个方面影响HDFS集群

  • NameNode机器发生意外,如宕机,集群将无法使用,直到管理员重启

  • NameNode机器需要升级,包括软件、硬件升级,此时集群也将无法使用

HDFS HA功能通过配置Active/Standby两个NameNodes实现在集群中对NameNode的热备来解决上述问题。如果出现故障,如机器崩溃或机器需要升级维护,这时可通过此种方式将NameNode很快的切换到另外一台机器。

16. Hadoop HA高可用 - 图1

2. 配置HDFS-HA集群

hadoop102 hadoop103 hadoop104
NameNode NameNode NameNode
ZKFC ZKFC ZKFC
JournalNode JournalNode JournalNode
DataNode DataNode DataNode
ZK ZK ZK
ResourceManager
NodeManager NodeManager NodeManager

要先配置好zookeeper 并启动

  1. sudo mkdir /opt/ha
  2. sudo chown atguigu:atguigu /opt/ha
  3. #将/opt/module/下的 hadoop-3.1.3拷贝到/opt/ha目录下
  4. cp -r /opt/module/hadoop-3.1.3 /opt/ha/
  5. #删除复制后hadoop文件夹中的 data文件夹和logs文件夹
  6. cd /opt/ha/hadoop-3.1.3/
  7. rm -rf data/ logs mapreduce1-1.0-SNAPSHOT.jar

配置core-site

  1. vim etc/hadoop/core-site.xml
  2. #修改以下两个key的值 追加一个zookeeper集群地址
  1. <configuration>
  2. <property>
  3. <name>fs.defaultFS</name>
  4. <value>hdfs://mycluster</value>
  5. </property>
  6. <!-- hadoop数据存放路径 注意为data.dir 而不tmp.dir -->
  7. <property>
  8. <name>hadoop.data.dir</name>
  9. <value>/opt/ha/hadoop-3.1.3/data</value>
  10. </property>
  11. <!--追加 zookeeper quorum 地址 配置ZooKeeper服务集群,用于活跃NameNode节点的选举-->
  12. <property>
  13. <name>ha.zookeeper.quorum</name>
  14. <value>hadoop102:2181,hadoop103:2181,hadoop104:2181</value>
  15. </property>
  16. </configuration>

配置hdfs-site.xml

  1. vim etc/hadoop/core-site.xml
  2. #覆盖原有配置
  1. <configuration>
  2. <!--配置NameNode的数据存储目录,需要与上文创建的目录相对应-->
  3. <property>
  4. <name>dfs.namenode.name.dir</name>
  5. <value>file://${hadoop.data.dir}/name</value>
  6. </property>
  7. <property>
  8. <name>dfs.datanode.data.dir</name>
  9. <value>file://${hadoop.data.dir}/data</value>
  10. </property>
  11. <!-- nameservices名称 自定义的HDFS服务名,在高可用集群中,无法配置单一HDFS服务器入口,所以需要指定一个逻辑上的服务名,当访问服务名时,会自动选择NameNode节点进行访问 -->
  12. <property>
  13. <name>dfs.nameservices</name>
  14. <value>mycluster</value>
  15. </property>
  16. <!-- 三个namenode 定义HDFS服务名所指向的NameNode主机名称 -->
  17. <property>
  18. <name>dfs.ha.namenodes.mycluster</name>
  19. <value>nn1,nn2, nn3</value>
  20. </property>
  21. <!-- namenode地址 设置NameNode的完整监听地址 -->
  22. <property>
  23. <name>dfs.namenode.rpc-address.mycluster.nn1</name>
  24. <value>hadoop102:8020</value>
  25. </property>
  26. <property>
  27. <name>dfs.namenode.rpc-address.mycluster.nn2</name>
  28. <value>hadoop103:8020</value>
  29. </property>
  30. <property>
  31. <name>dfs.namenode.rpc-address.mycluster.nn3</name>
  32. <value>hadoop104:8020</value>
  33. </property>
  34. <!--设置NameNode的HTTP访问地址-->
  35. <property>
  36. <name>dfs.namenode.http-address.mycluster.nn1</name>
  37. <value>hadoop102:9870</value>
  38. </property>
  39. <property>
  40. <name>dfs.namenode.http-address.mycluster.nn2</name>
  41. <value>hadoop103:9870</value>
  42. </property>
  43. <property>
  44. <name>dfs.namenode.http-address.mycluster.nn3</name>
  45. <value>hadoop104:9870</value>
  46. </property>
  47. <!-- 配置qjn集群 设置主从NameNode元数据同步地址,官方推荐将nameservice作为最后的journal ID -->
  48. <property>
  49. <name>dfs.namenode.shared.edits.dir</name>
  50. <value>qjournal://hadoop102:8485;hadoop103:8485;hadoop104:8485/mycluster</value>
  51. </property>
  52. <!-- qjn数据存放目录 配置JournalNode的数据存储目录,需要与上文创建的目录相对应 -->
  53. <property>
  54. <name>dfs.journalnode.edits.dir</name>
  55. <value>${hadoop.data.dir}/jn</value>
  56. </property>
  57. <!-- 代理类 设置HDFS客户端用来连接集群中活动状态NameNode节点的Java类 -->
  58. <property>
  59. <name>dfs.client.failover.proxy.provider.mycluster</name>
  60. <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
  61. </property>
  62. <!-- 隔离方式 为sshfence ssh远程代理 启动fence过程,确保集群高可用性 -->
  63. <property>
  64. <name>dfs.ha.fencing.methods</name>
  65. <value>sshfence</value>
  66. </property>
  67. <!-- ssh私有路径 设置SSH登录的私钥文件地址 -->
  68. <property>
  69. <name>dfs.ha.fencing.ssh.private-key-files</name>
  70. <value>/home/atguigu/.ssh/id_rsa</value>
  71. </property>
  72. <!-- 开启自动切换 设置自动切换活跃节点,保证集群高可用性 -->
  73. <property>
  74. <name>dfs.ha.automatic-failover.enabled</name>
  75. <value>true</value>
  76. </property>
  77. </configuration>

同步

  1. sudo xsync /opt/ha/

临时修改环境变量 因为hdfs.sh 默认根据环境变量来启动的 无法正常格式化ha中的namenode

  1. sudo vim /etc/profile.d/my_env.sh
  2. #修改hadoop路径 临时为ha下的hadoop
  3. export HADOOP_HOME=/opt/ha/hadoop-3.1.3
  4. source /etc/profile.d/my_env.sh
  5. sudo xsync /etc/profile.d/my_env.sh

启动JQM集群

  1. #三台都会启动 jps检查一下三台有没有journalnode
  2. /opt/ha/hadoop-3.1.3/bin/hdfs --workers --daemon start journalnode
  3. #如果不行删除data 和logs文件夹 重新启动 再不行看日志 JQM的数据存储路径必须为绝对路径

格式化nn

  1. #在102节点中格式化nn
  2. hdfs namenode -format
  3. hdfs --daemon start namenode #启动nn
  4. #其他节点通过同步nn1的元数据信息
  5. #切记要在atguigu下 不要root用户下 如果无法启动nn删除data 和logs文件夹 同步
  6. #在103和104中使用
  7. hdfs namenode -bootstrapStandby #同步
  8. hdfs --daemon start namenode #启动

启动zk并初始化HA在Zookeeper中状态

  1. #先启动三台的zookeeper
  2. zkServer.sh start
  3. #格式一台即可以 其他集群会同步
  4. hdfs zkfc -formatZK

启动dfs

  1. #102
  2. start-dfs.sh

3. HA的选举机制

通过查看3台集群的web页面 发现只有一台活动(active状态) 其他都是standby状态, 如果我把active的nn杀掉,那么ha会自动故障转移把某台standby状态的变为active状态

  1. 通过zookeeper选取的
  2. 当我们启动nn时 hadoop会自动向zookeeper上的hadoop-ha/mycluster/ActiveStandbyElectorLock 注册一个临时节点 此节点的值就是active节点名称 先在此临时节点注册的集群则成为active
  3. 如果active宕机 则节点会远程访问active 8020端口 并测试杀掉服务 无响应/杀掉 在zookeeper上的临时节点上注册 (此过程所有节点都会执行 谁先在临时节点注册上就是谁做active)
  4. hadoop-ha/mycluster/ActiveBreadCrumb 此zookeeper节点记录上一个active 名称 如果重新上线则为standby状态
  5. 如果active断网 则会尝试不断的隔离active节点 但无法连接到active 并且在隔离期间standby都无法转换为active 因为我们配置的隔离方法 是sshfence(ssh连接并尝试杀死进程) 我们可以通过逗号配置多value值

    1. shell(脚本文件路径) 自定义脚本方法

4. YARN-HA

hadoop102 hadoop103 hadoop104
NameNode NameNode
JournalNode JournalNode JournalNode
DataNode DataNode DataNode
ZK ZK ZK
ResourceManager ResourceManager
NodeManager NodeManager NodeManager

在配置完HDFS-HA的基础上 修改配置

  1. vim /opt/ha/hadoop-3.1.3/etc/hadoop/yarn-site.xml
  2. #追加
  1. <!--启用resourcemanager ha 开启resourcemanager 的高可用性功能-->
  2. <property>
  3. <name> yarn.resourcemanager.ha.enabled</name>
  4. <value>true</value>
  5. </property>
  6. <!--声明两台resourcemanager的地址 标识集群中的resourcemanager,如果设置该选项,需要确保所有的resourcemanager节点在配置中都有自己的逻辑id-->
  7. <property>
  8. <name>yarn.resourcemanager.cluster-id</name>
  9. <value>cluster-yarn1</value>
  10. </property>
  11. <!--设置resourcemanager节点的逻辑id-->
  12. <property>
  13. <name>yarn.resourcemanager.ha.rm-ids</name>
  14. <value>rm1,rm2</value>
  15. </property>
  16. <!--为每个逻辑id绑定实际的主机名称-->
  17. <property>
  18. <name>yarn.resourcemanager.hostname.rm1</name>
  19. <value>hadoop102</value>
  20. </property>
  21. <property>
  22. <name>yarn.resourcemanager.hostname.rm2</name>
  23. <value>hadoop103</value>
  24. </property>
  25. <!--指定zookeeper集群的地址-->
  26. <property>
  27. <name>yarn.resourcemanager.zk-address</name>
  28. <value>hadoop102:2181,hadoop103:2181,hadoop104:2181</value>
  29. </property>
  30. <!--启用自动恢复-->
  31. <property>
  32. <name>yarn.resourcemanager.recovery.enabled</name>
  33. <value>true</value>
  34. </property>
  35. <!--指定resourcemanager的状态信息存储在zookeeper集群-->
  36. <property>
  37. <name>yarn.resourcemanager.store.class</name> <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
  38. </property>
  1. xsync /opt/ha/hadoop-3.1.3/etc/hadoop/yarn-site.xml

启动yarn

  1. #103中启动
  2. start-yarn.sh

查询当前yarn是standby状态 还是active

  1. yarn rmadmin -getServiceState rm1

yarn在zookeeper下的节点名为yarn-leader-election 两个节点互相独立