乐趣区

Hadoop-HA

Hadoop HA

什么是 HA

HA 是 High Available 缩写,是双机集群系统简称,指高可用性集群,是保证业务连续性的有效解决方案,一般有两个或两个以上的节点,且分为活动节点及备用节点。通常把正在执行业务的称为活动节点,而作为活动节点的一个备份的则称为备用节点。当活动节点出现问题,导致正在运行的业务(任务)不能正常运行时,备用节点此时就会侦测到,并立即接续活动节点来执行业务。从而实现业务的不中断或短暂中断。

hadoop HA 机制介绍

hadoop2.0 的 HA 机制有两个 namenode,一个是 active namenode,状态是 active;另外一个是 standby namenode,状态是 standby。两者的状态是可以切换的,但不能同时两个都是 active 状态,最多只有 1 个是 active 状态。只有 active namenode 提供对外的服务,standby namenode 是不对外服务的。active namenode 和 standby namenode 之间通过 NFS 或者 JN(journalnode,QJM 方式)来同步数据。
active namenode 会把最近的操作记录写到本地的一个 edits 文件中(edits file),并传输到 NFS 或者 JN 中。standby namenode 定期的检查,从 NFS 或者 JN 把最近的 edit 文件读过来,然后把 edits 文件和 fsimage 文件合并成一个新的 fsimage,合并完成之后会通知 active namenode 获取这个新 fsimage。active namenode 获得这个新的 fsimage 文件之后,替换原来旧的 fsimage 文件。
这样,保持了 active namenode 和 standby namenode 的数据的实时同步,standby namenode 可以随时切换成 active namenode(譬如 active namenode 挂了)。而且还有一个原来 hadoop1.0 的 secondarynamenode,checkpointnode,buckcupnode 的功能:合并 edits 文件和 fsimage 文件,使 fsimage 文件一直保持更新。所以启动了 hadoop2.0 的 HA 机制之后,secondarynamenode,checkpointnode,buckcupnode 这些都不需要了。

搭建 hadoop HA 集群

环境

linux: CentOS-7.5_x64
hadoop: hadoop-3.2.0
zookeeper: zookeeper-3.4.10

机器规划

主机名 IP 安装软件 运行进程
node-1 192.168.91.11 hadoop NameNode,ResourceManager,DFSZKFailoverController
node-2 192.168.91.12 hadoop,zookeeper NameNode,ResourceManager,QuorumPeerMain,DFSZKFailoverController
node-3 192.168.91.13 hadoop,zookeeper QuorumPeerMain,DataNode,NodeManager,JournalNode
node-4 192.168.91.14 hadoop,zookeeper QuorumPeerMain,DataNode,NodeManager,JournalNode

前置准备

四台机器需要 ssh 免密登录,node-2,node-3,node- 4 需要安装 zookeeper、java 环境

集群搭建


# 下载
$ wget http://mirrors.shu.edu.cn/apache/hadoop/common/hadoop-3.1.2/hadoop-3.2.0.tar.gz

# 解压
$ tar -zxvf hadoop-3.2.0.tar.gz

# 配置系统的环境变量
$ vim /etc/profile

export JAVA_HOME=/usr/local/jdk1.8.0_191
export PATH=$PATH:$JAVA_HOME/bin

export HADOOP_HOME=/export/servers/hadoop-3.2.0
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin


# 进入解压目录配置环境变量
$ cd $HADOOP_HOME

# 配置 hadoop-env.sh 添加下面配置(不配置启动会报错)$ vim etc/hadoop/core-site.xml

export JAVA_HOME=/usr/local/jdk1.8.0_191

export HDFS_NAMENODE_USER=root
export HDFS_DATANODE_USER=root
export HDFS_JOURNALNODE_USER=root
export HDFS_SECONDARYNAMENODE_USER=root

export YARN_RESOURCEMANAGER_USER=root
export YARN_NODEMANAGER_USER=root



# 配置 core-site.xml
$ vim etc/hadoop/core-site.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<!--
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License. See accompanying LICENSE file.
-->

<!-- Put site-specific property overrides in this file. -->

<configuration>

    <!-- HA 配置指定 hdfs 的 nameService 为 ns -->
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://ns</value>
    </property>

    <!-- HA 配置,指定 zookeeper 地址 -->
    <property>
        <name>ha.zookeeper.quorum</name>
        <value>node-2:2181,node-3:2181,node-4:2181</value>
    </property>

    <property>   
        <name>hadoop.tmp.dir</name>   
        <value>/export/data/hadoop/temp</value>
    </property>

    <property>
        <name>hadoop.proxyuser.root.hosts</name>
        <value>*</value>
    </property>

    <property>
        <name>hadoop.proxyuser.root.groups</name>
        <value>*</value>
    </property>

</configuration>



# 配置 hdfs-site.xml
$ vim etc/hadoop/hdfs-site.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<!--
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License. See accompanying LICENSE file.
-->

<!-- Put site-specific property overrides in this file. -->

<configuration>

    <!-- 指定 hdfs 的 nameservice 为 ns,需要和 core-site.xml 中的保持一致 -->
    <property>
        <name>dfs.nameservices</name>
        <value>ns</value>
    </property>

    <!-- bi 下面有两个 NameNode,分别是 nn1,nn2 -->
    <property>
        <name>dfs.ha.namenodes.ns</name>
        <value>nn1,nn2</value>
    </property>

    <!-- nn1 的 RPC 通信地址 -->
    <property>
        <name>dfs.namenode.rpc-address.ns.nn1</name>
        <value>node-1:9000</value>
    </property>

    <!-- nn1 的 http 通信地址 -->
    <property>
        <name>dfs.namenode.http-address.ns.nn1</name>
        <value>node-1:50070</value>
    </property>

    <!-- nn2 的 RPC 通信地址 -->
    <property>
        <name>dfs.namenode.rpc-address.ns.nn2</name>
        <value>node-2:9000</value>
    </property>

    <!-- nn2 的 http 通信地址 -->
    <property>
        <name>dfs.namenode.http-address.ns.nn2</name>
        <value>node-2:50070</value>
    </property>

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

    <!-- 指定 JournalNode 在本地磁盘存放数据的位置 -->
    <property>
        <name>dfs.journalnode.edits.dir</name>
        <value>/export/data/hadoop/journaldata</value>
    </property>

    <!-- 开启 NameNode 失败自动切换 -->
    <property>
        <name>dfs.ha.automatic-failover.enabled</name>
        <value>true</value>
    </property>

    <!-- 配置失败自动切换实现方式 -->
    <property>
        <name>dfs.client.failover.proxy.provider.bi</name>
        <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
    </property>

    <!-- 配置隔离机制方法,多个机制用换行分割,即每个机制暂用一行 -->
    <property>
        <name>dfs.ha.fencing.methods</name>
        <value>
            sshfence
            shell(/bin/true)
        </value>
    </property>

    <!-- 使用 sshfence 隔离机制时需要 ssh 免登陆 -->
    <property>
        <name>dfs.ha.fencing.ssh.private-key-files</name>
        <value>/root/.ssh/id_rsa</value>
    </property>

    <!-- 配置 sshfence 隔离机制超时时间 -->
    <property>
        <name>dfs.ha.fencing.ssh.connect-timeout</name>
        <value>30000</value>
    </property>

    <property>
        <name>dfs.ha.namenodes.jn</name>
        <value>node-3,node-4</value>
    </property>

</configuration>

# 配置 mapred-site.xml
$ vim etc/hadoop/mapred-site.xml

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<!--
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License. See accompanying LICENSE file.
-->

<!-- Put site-specific property overrides in this file. -->

<configuration>

    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>

    <property>
        <name>yarn.app.mapreduce.am.env</name>
        <value>HADOOP_MAPRED_HOME=${HADOOP_HOME}</value>
    </property>

    <property>
        <name>mapreduce.map.env</name>
        <value>HADOOP_MAPRED_HOME=${HADOOP_HOME}</value>
    </property>

    <property>
        <name>mapreduce.reduce.env</name>
        <value>HADOOP_MAPRED_HOME=${HADOOP_HOME}</value>
    </property>

</configuration>


# 配置 yarn-site.xml
$ vim etc/hadoop/yarn-site.xml

<?xml version="1.0"?>
<!--
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License. See accompanying LICENSE file.
-->
<configuration>
<!-- Site specific YARN configuration properties -->

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

    <!-- 指定 RM 的 cluster id -->
    <property>
        <name>yarn.resourcemanager.cluster-id</name>
        <value>yarn-ha</value>
    </property>

    <!-- 指定 RM 的名字 -->
    <property>
        <name>yarn.resourcemanager.ha.rm-ids</name>
        <value>rm1,rm2</value>
    </property>

    <!-- 分别指定 RM 的地址 -->
    <property>
        <name>yarn.resourcemanager.hostname.rm1</name>
        <value>node-1</value>
    </property>

    <property>
        <name>yarn.resourcemanager.hostname.rm2</name>
        <value>node-2</value>
    </property>

    <!-- 指定 zk 集群地址 -->
    <property>
        <name>yarn.resourcemanager.zk-address</name>
        <value>node-2:2181,node-3:2181,node-4:2181</value>
    </property>

    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>

</configuration>


# 配置 workers 节点
$ vim $HADOOP_HOME/etc/hadoop/workers

node-3
node-4

# 拷贝 hadoop 到其他节点(node-2,node-3,node-4)$ scp -r hadoop-3.2.0 root@node-2:/xxx/xxx/

hdfs HA 配置

# 启动 zookeeper 集群
$ $ZOOKEEPER_HOME/bin/zkServer.sh start

# 查看 zookeeper 状态
$ $ZOOKEEPER_HOME/bin/zkServer.sh status

# 启动 JournalNode 集群 分别在 node-3、node-4 上执行以下命令
$ hdfs --daemon start journalnode

# 格式化 ZooKeeper 集群
$ hdfs zkfc -formatZK

# 格式化集群的 NameNode (在 node-1 上执行)
$ hdfs namenode -format

# 启动刚格式化的 NameNode (在 node-1 上执行)
$ hdfs --daemon start namenode

# 同步 NameNode1 元数据到 NameNode2 上 (在 node-2 上执行)  
$ hdfs namenode -bootstrapStandby

# 启动 NameNode2 (在 node-2 上执行)
$ hdfs --daemon start namenode

# 启动集群中所有的 DataNode (在 node-1 上执行)  
$ sbin/start-dfs.sh

# 启动 ZKFC 进程 (在 node-1 和 node-2 的主机上分别执行如下命令)
$ hdfs --daemon start zkfc

# 验证 ha(在 node- 1 节点停掉 namenode 进程)
$ hafs --daemon stop namenode

resourceManager HA 配置

# 在 RM1 启动 YARN (在 node-1 上执行)
$ yarn --daemon start resourcemanager

# 在 RM2 启动 YARN (在 node-2 上执行)
$ yarn --daemon start resourcemanager

# 在任意节点执行获取 resourceManager 状态(active)$ yarn rmadmin -getServiceState rm1

# 在任意节点执行获取 resourceManager 状态(standby)$ yarn rmadmin -getServiceState rm2

# 验证 yarn 的 ha(在 node- 1 节点执行)standby 的 resourcemanager 则会转换为 active
$ yarn --daemon stop resourcemanager

# 在任意节点执行获取 resourceManager 状态(active)$ yarn rmadmin -getServiceState rm2

总结

搭建 hadoop HA 过程中遇到了很多各种各样的问题上述步骤都是经过验证的如在安装过程中遇到问题可以留言,谢谢!

退出移动版