第一章 Hadoop HA 高可用

HA 概述

  • 所谓 HA(High Availablity),即高可用(7*24 小时不中断服务)。
  • 实现高可用最关键的策略是消除单点故障。HA 严格来说应该分成各个组件的 HA机制:HDFS 的 HA 和 YARN 的 HA。
  • NameNode 主要在以下两个方面影响 HDFS 集群
    HDFS HA 功能通过配置多个 NameNodes(Active/Standby)实现在集群中对 NameNode 的热备来解决上述问题。如果出现故障,如机器崩溃或机器需要升级维护,这时可通过此种方式将 NameNode 很快的切换到另外一台机器。

HDFS-HA 集群搭建

HDFS-HA 核心问题

  1. 怎么保证三台 namenode 的数据一致
    • Fsimage:让一台 nn 生成数据,让其他机器 nn 同步
    • Edits:需要引进新的模块 JournalNode 来保证 edtis 的文件的数据一致性
  2. 怎么让同时只有一台 nn 是 active,其他所有是 standby 的
    • 手动分配
    • 自动分配
  3. 2nn 在 ha 架构中并不存在,定期合并 fsimage 和 edtis 的活谁来干
    由 standby 的 nn 来干
  4. 如果 nn 真的发生了问题,怎么让其他的 nn 上位干活
    • 手动故障转移
    • 自动故障转移

HDFS-HA 手动模式

环境准备

  • 修改 IP
  • 修改主机名及主机名和 IP 地址的映射
  • 关闭防火墙
  • ssh 免密登录
  • 安装 JDK,配置环境变量等

规划集群

配置 HDFS-HA 集群

  1. 详情请查看官方文档:
    1
    https://hadoop.apache.org/
    点击图片跳转链接 https://hadoop.apache.org/
  2. 在 opt 目录下创建一个 ha 文件夹
    1
    2
    3
    [Jermyn@hadoop102 ~]$ cd /opt
    [Jermyn@hadoop102 opt]$ sudo mkdir ha
    [Jermyn@hadoop102 opt]$ sudo chown Jermyn:Jermyn /opt/ha
  3. 将/opt/module/下的 hadoop-3.1.3 拷贝到/opt/ha 目录下(记得删除 data 和 log 目录)
    1
    [Jermyn@hadoop102 opt]$ cp -r /opt/module/hadoop-3.1.3 /opt/ha/
  4. 配置 core-site.xml
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <configuration>

    <!-- 把多个 NameNode 的地址组装成一个集群 mycluster -->
    <property>
    <name>fs.defaultFS</name>
    <value>hdfs://mycluster</value>
    </property>

    <!-- 指定 hadoop 运行时产生文件的存储目录 -->
    <property>
    <name>hadoop.tmp.dir</name>
    <value>/opt/ha/hadoop-3.1.3/data</value>
    </property>

    </configuration>
  5. 配置 hdfs-site.xml
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    <configuration>

    <!-- NameNode 数据存储目录 -->
    <property>
    <name>dfs.namenode.name.dir</name>
    <value>file://${hadoop.tmp.dir}/name</value>
    </property>

    <!-- DataNode 数据存储目录 -->
    <property>
    <name>dfs.datanode.data.dir</name>
    <value>file://${hadoop.tmp.dir}/data</value>
    </property>

    <!-- JournalNode 数据存储目录 -->
    <property>
    <name>dfs.journalnode.edits.dir</name>
    <value>${hadoop.tmp.dir}/jn</value>
    </property>

    <!-- 完全分布式集群名称 -->
    <property>
    <name>dfs.nameservices</name>
    <value>mycluster</value>
    </property>

    <!-- 集群中 NameNode 节点都有哪些 -->
    <property>
    <name>dfs.ha.namenodes.mycluster</name>
    <value>nn1,nn2,nn3</value>
    </property>

    <!-- NameNode 的 RPC 通信地址 -->
    <property>
    <name>dfs.namenode.rpc-address.mycluster.nn1</name>
    <value>hadoop102:8020</value>
    </property>
    <property>
    <name>dfs.namenode.rpc-address.mycluster.nn2</name>
    <value>hadoop103:8020</value>
    </property>
    <property>
    <name>dfs.namenode.rpc-address.mycluster.nn3</name>
    <value>hadoop104:8020</value>
    </property>

    <!-- NameNode 的 http 通信地址 -->
    <property>
    <name>dfs.namenode.http-address.mycluster.nn1</name>
    <value>hadoop102:9870</value>
    </property>
    <property>
    <name>dfs.namenode.http-address.mycluster.nn2</name>
    <value>hadoop103:9870</value>
    </property>
    <property>
    <name>dfs.namenode.http-address.mycluster.nn3</name>
    <value>hadoop104:9870</value>
    </property>

    <!-- 指定 NameNode 元数据在 JournalNode 上的存放位置 -->
    <property>
    <name>dfs.namenode.shared.edits.dir</name>
    <value>qjournal://hadoop102:8485;hadoop103:8485;hadoop104:8485/mycluster</value>
    </property>

    <!-- 访问代理类:client 用于确定哪个 NameNode 为 Active -->
    <property>
    <name>dfs.client.failover.proxy.provider.mycluster</name>
    <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
    </property>

    <!-- 配置隔离机制,即同一时刻只能有一台服务器对外响应 -->
    <property>
    <name>dfs.ha.fencing.methods</name>
    <value>sshfence</value>
    </property>

    <!-- 使用隔离机制时需要 ssh 秘钥登录-->
    <property>
    <name>dfs.ha.fencing.ssh.private-key-files</name>
    <value>/home/Jermyn/.ssh/id_rsa</value>
    </property>

    </configuration>
  6. 分发 /opt/ha

启动 HDFS-HA 集群

  1. 将 HADOOP_HOME 环境变量更改到 HA 目录(三台机器)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    [Jermyn@hadoop102 ~]$ sudo vim /etc/profile.d/my_env.sh

    将 HADOOP_HOME 部分改为如下
    #HADOOP_HOME
    export HADOOP_HOME=/opt/ha/hadoop-3.1.3
    export PATH=$PATH:$HADOOP_HOME/bin
    export PATH=$PATH:$HADOOP_HOME/sbin

    去三台机器上 source 环境变量
    [Jermyn@hadoop102 ~]$xcall source /etc/profile
  2. 在各个 JournalNode 节点上,输入以下命令启动 journalnode 服务
    1
    2
    3
    4
    5
    6
    [Jermyn@hadoop102 opt]$ hdfs --daemon start journalnode
    WARNING: /opt/ha/hadoop-3.1.3/logs does not exist. Creating.
    [Jermyn@hadoop103 opt]$ hdfs --daemon start journalnode
    WARNING: /opt/ha/hadoop-3.1.3/logs does not exist. Creating.
    [Jermyn@hadoop104 opt]$ hdfs --daemon start journalnode
    WARNING: /opt/ha/hadoop-3.1.3/logs does not exist. Creating.
  3. 在[nn1]上,对其进行格式化,并启动
    1
    2
    [Jermyn@hadoop102 ~]$ hdfs namenode -format
    [Jermyn@hadoop102 ~]$ hdfs --daemon start namenode
  4. 在[nn2]和[nn3]上,同步 nn1 的元数据信息
    1
    2
    [Jermyn@hadoop103 ~]$ hdfs namenode -bootstrapStandby
    [Jermyn@hadoop104 ~]$ hdfs namenode -bootstrapStandby
  5. 启动[nn2]和[nn3]
    1
    2
    [Jermyn@hadoop103 ~]$ hdfs --daemon start namenode
    [Jermyn@hadoop104 ~]$ hdfs --daemon start namenode
  6. 查看 web 页面显示
    http://hadoop102:9870/dfshealth.html#tab-overview
  7. 在所有节点上,启动 datanode
    1
    2
    3
    [Jermyn@hadoop102 ~]$ hdfs --daemon start datanode
    [Jermyn@hadoop103 ~]$ hdfs --daemon start datanode
    [Jermyn@hadoop104 ~]$ hdfs --daemon start datanode
  8. 将[nn1]切换为 Active
    1
    [Jermyn@hadoop102 ~]$ hdfs haadmin -transitionToActive nn1
  9. 查看是否 Active
    1
    [Jermyn@hadoop102 ~]$ hdfs haadmin -getServiceState nn1

HDFS-HA 自动模式

HDFS-HA 自动故障转移工作机制

自动故障转移为 HDFS 部署增加了两个新组件:ZooKeeper 和 ZKFailoverController(ZKFC)进程,如图所示。ZooKeeper 是维护少量协调数据,通知客户端这些数据的改变和监视客户端故障的高可用服务。

HDFS-HA 自动故障转移的集群规划

配置 HDFS-HA 自动故障转移

  1. 具体配置
    • 在 hdfs-site.xml 中增加
      1
      2
      3
      4
      5
      <!-- 启用 nn 故障自动转移 -->
      <property>
      <name>dfs.ha.automatic-failover.enabled</name>
      <value>true</value>
      </property>
    • 在 core-site.xml 文件中增加
      1
      2
      3
      4
      5
      <!-- 指定 zkfc 要连接的 zkServer 地址 -->
      <property>
      <name>ha.zookeeper.quorum</name>
      <value>hadoop102:2181,hadoop103:2181,hadoop104:2181</value>
      </property>
  2. 修改后分发配置文件
    1
    2
    3
    [Jermyn@hadoop102 etc]$ pwd
    /opt/ha/hadoop-3.1.3/etc
    [Jermyn@hadoop102 etc]$ xsync hadoop/
  3. 启动
    • 关闭所有 HDFS 服务:
      1
      [Jermyn@hadoop102 ~]$ stop-dfs.sh
    • 启动 Zookeeper 集群:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      [Jermyn@hadoop102 etc]$ zkServer start
      -----------------------Current User Is:Jermyn,Hostname Is:hadoop102-----------------------
      --> Excute Command "/opt/module/zookeeper-3.5.7/bin/zkServer.sh start"
      ZooKeeper JMX enabled by default
      Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg
      Starting zookeeper ... STARTED
      -----------------------Current User Is:Jermyn,Hostname Is:hadoop103-----------------------
      --> Excute Command "/opt/module/zookeeper-3.5.7/bin/zkServer.sh start"
      ZooKeeper JMX enabled by default
      Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg
      Starting zookeeper ... STARTED
      -----------------------Current User Is:Jermyn,Hostname Is:hadoop104-----------------------
      --> Excute Command "/opt/module/zookeeper-3.5.7/bin/zkServer.sh start"
      ZooKeeper JMX enabled by default
      Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg
      Starting zookeeper ... STARTED
      Excute Successfully!
      [Jermyn@hadoop102 etc]$
    • 启动 Zookeeper 以后,然后再初始化 HA 在 Zookeeper 中状态:
      1
      [Jermyn@hadoop102 ~]$ hdfs zkfc -formatZK
    • 启动 HDFS 服务:
      1
      [Jermyn@hadoop102 ~]$ start-dfs.sh

YARN-HA 配置

YARN-HA 工作机制

  1. 官方文档:https://hadoop.apache.org/docs/r2.7.2/hadoop-yarn/hadoop-yarn-site/ResourceManagerHA.html
    点击图片跳转链接 https://hadoop.apache.org/docs/r2.7.2/hadoop-yarn/hadoop-yarn-site/ResourceManagerHA.html
  2. YARN-HA 工作机制

配置 YARN-HA 集群

  1. 环境准备
    • 修改 IP
    • 修改主机名及主机名和 IP 地址的映射
    • 关闭防火墙
    • ssh 免密登录
    • 安装 JDK,配置环境变量等
    • 配置 Zookeeper 集群
  2. 规划集群
  3. 具体配置
    • yarn-site.xml
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      88
      89
      90
      91
      92
      93
      94
      95
      96
      97
      98
      99
      100
      101
      102
      103
      104
      105
      106
      107
      108
      109
      110
      111
      112
      113
      114
      115
      116
      117
      118
      119
      120
      121
      122
      123
      124
      125
      126
      127
      128
      129
      130
      131
      132
      133
      <configuration>

      <!-- Site specific YARN configuration properties -->
      <property>
      <name>yarn.nodemanager.aux-services</name>
      <value>mapreduce_shuffle</value>
      </property>

      <!-- 启用 resourcemanager ha -->
      <property>
      <name>yarn.resourcemanager.ha.enabled</name>
      <value>true</value>
      </property>

      <!-- 声明 resourcemanager 的地址 -->
      <property>
      <name>yarn.resourcemanager.cluster-id</name>
      <value>cluster-yarn1</value>
      </property>

      <!--指定 resourcemanager 的逻辑列表-->
      <property>
      <name>yarn.resourcemanager.ha.rm-ids</name>
      <value>rm1,rm2,rm3</value>
      </property>

      <!-- ========== rm1 的配置 ========== -->
      <!-- 指定 rm1 的主机名 -->
      <property>
      <name>yarn.resourcemanager.hostname.rm1</name>
      <value>hadoop102</value>
      </property>

      <!-- 指定 rm1 的 web 端地址 -->
      <property>
      <name>yarn.resourcemanager.webapp.address.rm1</name>
      <value>hadoop102:8088</value>
      </property>

      <!-- 指定 rm1 的内部通信地址 -->
      <property>
      <name>yarn.resourcemanager.address.rm1</name>
      <value>hadoop102:8032</value>
      </property>

      <!-- 指定 AM 向 rm1 申请资源的地址 -->
      <property>
      <name>yarn.resourcemanager.scheduler.address.rm1</name>
      <value>hadoop102:8030</value>
      </property>

      <!-- 指定供 NM 连接的地址 -->
      <property>
      <name>yarn.resourcemanager.resource-tracker.address.rm1</name>
      <value>hadoop102:8031</value>
      </property>

      <!-- ========== rm2 的配置 ========== -->
      <!-- 指定 rm2 的主机名 -->
      <property>
      <name>yarn.resourcemanager.hostname.rm2</name>
      <value>hadoop103</value>
      </property>
      <property>
      <name>yarn.resourcemanager.webapp.address.rm2</name>
      <value>hadoop103:8088</value>
      </property>
      <property>
      <name>yarn.resourcemanager.address.rm2</name>
      <value>hadoop103:8032</value>
      </property>
      <property>
      <name>yarn.resourcemanager.scheduler.address.rm2</name>
      <value>hadoop103:8030</value>
      </property>
      <property>
      <name>yarn.resourcemanager.resource-tracker.address.rm2</name>
      <value>hadoop103:8031</value>
      </property>

      <!-- ========== rm3 的配置 ========== -->
      <!-- 指定 rm1 的主机名 -->
      <property>
      <name>yarn.resourcemanager.hostname.rm3</name>
      <value>hadoop104</value>
      </property>
      <!-- 指定 rm1 的 web 端地址 -->
      <property>
      <name>yarn.resourcemanager.webapp.address.rm3</name>
      <value>hadoop104:8088</value>
      </property>
      <!-- 指定 rm1 的内部通信地址 -->
      <property>
      <name>yarn.resourcemanager.address.rm3</name>
      <value>hadoop104:8032</value>
      </property>
      <!-- 指定 AM 向 rm1 申请资源的地址 -->
      <property>
      <name>yarn.resourcemanager.scheduler.address.rm3</name>
      <value>hadoop104:8030</value>
      </property>
      <!-- 指定供 NM 连接的地址 -->
      <property>
      <name>yarn.resourcemanager.resource-tracker.address.rm3</name>
      <value>hadoop104:8031</value>
      </property>

      <!-- 指定 zookeeper 集群的地址 -->
      <property>
      <name>yarn.resourcemanager.zk-address</name>
      <value>hadoop102:2181,hadoop103:2181,hadoop104:2181</value>
      </property>

      <!-- 启用自动恢复 -->
      <property>
      <name>yarn.resourcemanager.recovery.enabled</name>
      <value>true</value>
      </property>

      <!-- 指定 resourcemanager 的状态信息存储在 zookeeper 集群 -->
      <property>
      <name>yarn.resourcemanager.store.class</name>
      <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateSt
      ore</value>
      </property>

      <!-- 环境变量的继承 -->
      <property>
      <name>yarn.nodemanager.env-whitelist</name>
      <value>JAVA_HOME,HADOOP_COMMON_HOME,HADOOP_HDFS_HOME,HADOOP_CONF_DIR,CLAS SPATH_PREPEND_DISTCACHE,HADOOP_YARN_HOME,HADOOP_MAPRED_HOME</value>
      </property>

      </configuration>