大数据专栏 | ||
---|---|---|
上一篇 | 主目录 | 下一篇 |
目录
【前言】
搭建hadoop的HA(High Available)集群
1 Hadoop HA原理
为什么会有 hadoop HA 机制呢?
HA:High Available,高可用
在Hadoop 2.0之前,在HDFS 集群中NameNode 存在单点故障 (SPOF:A Single Point of Failure)。对于只有一个 NameNode 的集群,如果 NameNode 机器出现故障(比如宕机或是软件、硬件升级),那么整个集群将无法使用,直到 NameNode 重新启动。
那如何解决呢?HDFS 的 HA 功能通过配置 Active/Standby 两个 NameNodes 实现在集群中对 NameNode 的热备来解决上述问题。如果出现故障,如机器崩溃或机器需要升级维护,这时可通过此种方式将 NameNode 很快的切换到另外一台机器。在一个典型的 HDFS(HA) 集群中,使用两台单独的机器配置为 NameNodes 。在任何时间点,确保 NameNodes 中只有一个处于Active 状态,其他的处在 Standby 状态。其中ActiveNameNode 负责集群中的所有客户端操作,StandbyNameNode 仅仅充当备机,保证一旦 ActiveNameNode 出现问题能够快速切换。为了能够实时同步 Active 和 Standby 两个 NameNode 的元数据信(实际上 editlog),需提供一个共享存储系统,可以是 NFS
、QJM(Quorum Journal Manager)
或者 Zookeeper
,Active Namenode 将数据写入共享存储系统,而 Standby 监听该系统,一旦发现有新数据写入,则读取这些数据,并加载到自己内存中,以保证自己内存状态与 Active NameNode 保持基本一致,如此这般,在紧急情况下 standby 便可快速切为 active namenode。为了实现快速切换,Standby 节点获取集群的最新文件块信息(最新文件块信息在NameNode的内存中,其他元数据在磁盘)也是很有必要的。为了实现这一目标,DataNode 需要配置 NameNodes 的位置,并同时给他们发送文件块信息以及心跳检测。
2 集群规划
我用了五台服务器:hadoop01,hadoop02,hadoop03,hadoop04,hadoop05
规划如下(表中缺失zkfc:同NameNode):
【注】其他类型的规划(可自行规划):
3 安装和配置
$JAVA_HOME=/usr/java/jdk1.8.0_161
3.1 安装zookeeper集群
hadoop HA 集群的搭建依赖于 zookeeper,需要先安装zookeeper
具体见:zookeeper安装
3.2 卸载已安装的hadoop
没有就省略这一步
要卸载01~05的所有hadoop-2.7.3(安装包)和历史数据(hadoopdata),以01为例:
[hadoop@hadoop01 apps]$ rm -rf hadoop-2.7.3
[hadoop@hadoop01 ~]$ rm -rf hadoopdata
3.3 解压文件
[hadoop@hadoop01 ~]$ tar -zxvf hadoop-2.7.3.tar.gz -C apps/
3.4 修改配置文件
进入/home/hadoop/apps/hadoop-2.7.3/etc/hadoop
目录,修改配置文件:
hadoop-env.sh
[hadoop@hadoop01 hadoop]$ vim hadoop-env.sh
#修改
export JAVA_HOME=/usr/java/jdk1.8.0_161
core-site.xml
[hadoop@hadoop01 hadoop]$ vim core-site.xml
#修改
<configuration>
<!-- 指定 hdfs 的 nameservice 为 myha01 -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://myha01/</value>
</property>
<!-- 指定 hadoop 工作目录 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/home/hadoop/hadoopdata/</value>
</property>
<!-- 指定 zookeeper 集群访问地址 -->
<property>
<name>ha.zookeeper.quorum</name>
<value>hadoop01:2181,hadoop02:2181,hadoop03:2181,hadoop04:2181</value>
</property>
</configuration>
hdfs-site.xml
[hadoop@hadoop01 hadoop]$ vim hdfs-site.xml
#修改
<configuration>
<!-- 指定副本数 -->
<property>
<name>dfs.replication</name>
<value>2</value>
</property>
<!--指定 hdfs 的 nameservice 为 myha01,需要和 core-site.xml 中保持一致 -->
<property>
<name>dfs.nameservices</name>
<value>myha01</value>
</property>
<!-- myha01 下面有两个 NameNode,分别是 nn1,nn2 -->
<property>
<name>dfs.ha.namenodes.myha01</name>
<value>nn1,nn2</value>
</property>
<!-- nn1 的 RPC 通信地址 -->
<property>
<name>dfs.namenode.rpc-address.myha01.nn1</name>
<value>hadoop01:9000</value>
</property>
<!-- nn1 的 http 通信地址 -->
<property>
<value>hadoop01:50070</value>
</property>
<!-- nn2 的 RPC 通信地址 -->
<property>
<name>dfs.namenode.rpc-address.myha01.nn2</name>
<value>hadoop02:9000</value>
</property>
<!-- nn2 的 http 通信地址 -->
<property>
<name>dfs.namenode.http-address.myha01.nn2</name>
<value>hadoop02:50070</value>
</property>
<!-- 指定 NameNode 的 edits 元数据在 JournalNode 上的存放位置 -->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://hadoop02:8485;hadoop03:8485;hadoop04:8485/myha01</value>
</property>
<!-- 指定 JournalNode 在本地磁盘存放数据的位置 -->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/home/hadoop/journaldata</value>
</property>
<!-- 开启 NameNode 失败自动切换 -->
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
<!-- 配置失败自动切换实现方式 -->
<!-- 配置失败自动切换实现方式 -->
<!-- 此处配置在安装的时候切记检查不要换行 -->
<property>
<name>dfs.client.failover.proxy.provider.myha01</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>/home/hadoop/.ssh/id_rsa</value>
</property>
<!-- 配置 sshfence 隔离机制超时时间 -->
<property>
<name>dfs.ha.fencing.ssh.connect-timeout</name>
<value>30000</value>
</property>
</configuration>
mapred-site.xml
[hadoop@hadoop01 hadoop]$ vim mapred-site.xml
#修改
<configuration>
<!-- 指定 mr 框架为 yarn 方式 -->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<!-- 设置 mapreduce 的历史服务器地址和端口号 -->
<property>
<name>mapreduce.jobhistory.address</name>
<value>hadoop01:10020</value>
</property>
<!-- mapreduce 历史服务器的 web 访问地址 -->
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>hadoop01:19888</value>
</property>
</configuration>
yarn-site.xml
[hadoop@hadoop01 hadoop]$ vim yarn-site.xml
<configuration>
<!-- 开启 RM 高可用 -->
<property>
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>
<!-- 指定 RM 的 cluster id -->
<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>yrc</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>hadoop03</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>hadoop04</value>
</property>
<!-- 指定 zk 集群地址 -->
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>hadoop01:2181,hadoop02:2181,hadoop03:2181,hadoop04:2181</value>
</property>
<!-- 要运行 MapReduce 程序必须配置的附属服务 -->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!-- 开启 YARN 集群的日志聚合功能 -->
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<!-- YARN 集群的聚合日志最长保留时长 -->
<property>
<name>yarn.log-aggregation.retain-seconds</name>
<value>86400</value>
</property>
<property>
<name>yarn.resourcemanager.store.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
</property>
</configuration>
slaves
[hadoop@hadoop01 hadoop]$ vim slaves
#修改
hadoop01
hadoop02
hadoop03
hadoop04
hadoop05
3.5 分发安装包
从01发送到02、03、04、05.
[hadoop@hadoop01 apps]$ scp -r hadoop-2.7.3/ hadoop@hadoop02:$PWD
[hadoop@hadoop01 apps]$ scp -r hadoop-2.7.3/ hadoop@hadoop03:$PWD
[hadoop@hadoop01 apps]$ scp -r hadoop-2.7.3/ hadoop@hadoop04:$PWD
[hadoop@hadoop01 apps]$ scp -r hadoop-2.7.3/ hadoop@hadoop05:$PWD
3.6 配置环境变量
[hadoop@hadoop01 apps]$ vim ~/.bashrc
#添加
export HADOOP_HOME=/home/hadoop/apps/hadoop-2.7.3
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
3.7 集群初始化
(记住:严格按照以下步骤执行)
3.7.1 启动zookeeper集群
启动:
zkServer.sh start
检查启动是否正常:
zkServer.sh status
3.7.2 启动 journalnode
分别在每个 zookeeper(也就是规划的三个 journalnode 节点,不一定跟 zookeeper节点一样)节点上启动 journalnode 进程(02、03、04)
[hadoop@hadoop02 ~]$ hadoop-daemon.sh start journalnode
[hadoop@hadoop03 ~]$ hadoop-daemon.sh start journalnode
[hadoop@hadoop04 ~]$ hadoop-daemon.sh start journalnode
然后用 jps
命令查看是否各个datanode 节点上都启动了journalnode 进程
【注】停止命令:hadoop-daemon.sh stop journalnode
3.7.3 格式化namenode
在第一个 namenode 上执行格式化操作(wode namenode有两个:01、02)
在hadoop01上:
[hadoop@hadoop01 ~]$ hadoop namenode -format
然后会在 core-site.xml 中配置的临时目录中生成一些集群的信息<name>hadoop.tmp.dir</name><value>/home/hadoop/hadoopdata/</value>
两个 namenode 节点该目录中的数据结构是一致的,需要将生成的hadoopdata/文件夹发送到hadoop02的家目录:
[hadoop@hadoop01 ~]$ scp -r hadoopdata/ hadoop@hadoop02:$PWD
3.7.4 格式化 ZKFC
在01上执行即可
[hadoop@hadoop01 ~]$ hdfs zkfc -formatZK
3.7.5 启动 HDFS
[hadoop@hadoop01 ~]$ start-dfs.sh
【注】停止的命令:stop-dfs.sh
3.7.6 启动 YARN
在主备 resourcemanager (03、04)中随便选择一台进行启动
[hadoop@hadoop03 ~]$ start-yarn.sh
若备用节点的 resourcemanager 没有启动起来,则手动启动起来
[hadoop@hadoop04 ~]$ yarn-daemon.sh start resourcemanager
3.7.7 查看是否成功
规划(表中缺失zkfc:同NameNode):
jps查看各节点的java进程:
NameNode:01、02
DataNode:每个节点都有
ResourceManager:03、04
NodeManager:每个节点都有
QuorumPeerMain(zookeeper):01、02、03、04(observer)
JournalNode:02、03、04
DFSZKFailoverController(zkfc)(同NameNode):01、02
hadoop01:6个( QuorumPeerMain NodeManager DFSZKFailoverController DataNode NameNode Jps)
hadoop02:7个
hadoop03:6个
hadoop04:6个
hadoop05:3个
输入http://192.168.65.101:50070/
或者http://192.168.65.102:50070/
查看NameNode信息(因为有两个NameNode):
输入http://192.168.65.103:8088/
或者http://192.168.65.104:8088/
查看Applications信息(http://192.168.65.104:8088/是standby resourcemanager,会自动跳转到 http://192.168.65.103:8088/)
3.7.8 查看服务器信息
查看各主节点的状态(在每个节点上都可以查)
HDFS:
[hadoop@hadoop01 ~]$ hdfs haadmin -getServiceState nn1
[hadoop@hadoop01 ~]$ hdfs haadmin -getServiceState nn2
YARN:
[hadoop@hadoop01 ~]$ yarn rmadmin -getServiceState rm1
[hadoop@hadoop01 ~]$ yarn rmadmin -getServiceState rm2
3.7.9 启动mapreduce任务历史服务器
[hadoop@hadoop01 ~]$ mr-jobhistory-daemon.sh start historyserver
按照配置文件配置的历史服务器的 web 访问地址去访问:http://hadoop01:19888
3.7.10 集群启动测试
-
干掉 active namenode
重新启动NameNode后的状态(不变):
-
在上传文件的时候干掉 active namenode
standby namenode会切换active namenode,仍能够成功上传 -
干掉 active resourcemanager
-
在执行任务的时候干掉 active resourcemanager
3.8 集群关闭
- 注:不是第一次启动集群时,总命令如下:
[hadoop@hadoop01 ~]$ zkServer.sh start#01、02、03、04
[hadoop@hadoop01 ~]$ start-dfs.sh
[hadoop@hadoop03 ~]$ start-yarn.sh
[hadoop@hadoop04 ~]$ yarn-daemon.sh start resourcemanager
[hadoop@hadoop01 ~]$ mr-jobhistory-daemon.sh stop historyserver
先开的后关
[hadoop@hadoop01 ~]$ mr-jobhistory-daemon.sh stop historyserver
[hadoop@hadoop04 ~]$ yarn-daemon.sh stop resourcemanager
[hadoop@hadoop03 ~]$ stop-yarn.sh
[hadoop@hadoop01 ~]$ stop-dfs.sh
[hadoop@hadoop01 ~]$ zkServer.sh stop#01、02、03、04