HA-Hadoop 部署
HA 概述
- 作用:消除NN,RM单点故障,分为Hdfs和Yarn的高可用
- 实现方式:热备
- 切换组件:zookeeper
- 要求:两个NameNode之间免密,在hdfs-site.xml配置
一. 前置准备
- 配置域名解析:配置文件直接点域名,以后即使更换IP也不用改配置文件
- vim /etc/hosts
- 域名服务器
- hdp用户:一般不用root用户,创建hdp用户
- useradd -m -s /bin/bash -d /home/hdp hdp
- -m: 自动建立用户的登入目录
- -s: 指定用户登入后所使用的shell、默认值为/bin/bash
- -d: 指定用户登入时的起始目录
- 如用root用户部署,在初始化之前记得重新授权
- 如需用root用户运行集群,需要在hadoop-env.sh添加配置
- useradd -m -s /bin/bash -d /home/hdp hdp
- 配置免密登录:Hdfs 使用隔离机制需要SSH免密登录
- ssh-keygen -t rsa --> 连续敲三个空格
- 会在当前家目录生成.ssh隐藏的加密证书文件
- ssh-copy-id -f hdp50(主机ip/域名) (包括本机在内)
- ssh-keygen -t rsa --> 连续敲三个空格
- JDK安装
- Zookeeper安装
- 配置 zoo.cfg
- 配置 ./data/myid
- 服务架构
| Host | hdp50 | hdp51 | hdp52 |
|---|---|---|---|
| Hdfs | DataNode JournalNode |
DataNode NameNode{主} JournalNode ZKFC |
DataNode NameNode{备} JournalNode ZKFC |
| Yarn | NodeManager ResourceManager(主) |
NodeManager |
NodeManager ResourceManager(备) JobHistoryServer |
| Zookeeper | myid=1 | myid=2 | myid=3 |
| Ntpd | server | client | client |
- 部署说明
- tar包位置:/opt/software/hdp_install/hadoop-3.3.1.tar.gz
- 软连接:将带版本的hadoop-3.3.1目录,软连接到当前目录不带版hadoop的目录,方便升级
- hadoop家目录:/opt/module/hadoop
- zk注册hdfs名称:hacluster
- zk注册yarn名称:hayarn --> 配置高可用Spark 任务历史组件要用
二. 部署步骤
1. 解压tar包
# tar -zxvf tar包路径 -C 解压后存放路径
tar -zxvf /opt/software/hdp_install/hadoop-3.3.1.tar.gz -C /opt/module/
# 建立软连接
ln -sf /opt/module/hadoop-3.3.1/ /opt/module/hadoop
2. 创建所需目录
mkdir -p /opt/module/hadoop/tmp
mkdir -p /opt/module/hadoop/dfs/journalnode_data
mkdir -p /opt/module/hadoop/dfs/edits
mkdir -p /opt/module/hadoop/dfs/datanode_data
mkdir -p /opt/module/hadoop/dfs/namenode_data
mkdir -p /opt/module/hadoop/logs
3. hadoop-env.sh
export JAVA_HOME=/opt/module/java
export HADOOP_CONF_DIR=/opt/module/hadoop/etc/hadoop
4. core-site.xml
- zk注册名称 hdfs://hacluster
- 指定tmp目录
- 默认缓存大小
- zk地址
<configuration>
<property>
<!--指定hadoop集群在zookeeper上注册的节点名-->
<name>fs.defaultFS</name>
<value>hdfs://hacluster</value>
</property>
<property>
<!--用来指定hadoop运行时产生文件的存放目录-->
<name>hadoop.tmp.dir</name>
<value>file:///opt/module/hadoop/tmp</value>
</property>
<property>
<!--设置缓存大小,默认4kb-->
<name>io.file.buffer.size</name>
<value>4096</value>
</property>
<property>
<!--指定zookeeper的存放地址 -->
<name>ha.zookeeper.quorum</name>
<value>hdp50:2181,hdp51:2181,hdp52:2181</value>
</property>
</configuration>
5. hdfs-site.xml
- hdp50:主NN (先开,抢占模式)
- hdp52:备NN
<configuration>
<property>
<!--数据块默认大小128M-->
<name>dfs.block.size</name>
<value>134217728</value>
</property>
<property>
<!--副本数量,不配置的话默认为3-->
<name>dfs.replication</name>
<value>3</value>
</property>
<property>
<!--namenode节点数据(元数据)的存放位置-->
<name>dfs.name.dir</name>
<value>file:///opt/module/hadoop/dfs/namenode_data</value>
</property>
<property>
<!--datanode节点数据(元数据)的存放位置-->
<name>dfs.data.dir</name>
<value>file:///opt/module/hadoop/dfs/datanode_data</value>
</property>
<property>
<name>dfs.webhdfs.enabled</name>
<value>true</value>
</property>
<property>
<name>dfs.datanode.max.transfer.threads</name>
<value>4096</value>
</property>
<property>
<!--指定hadoop集群在zookeeper上注册的节点名-->
<name>dfs.nameservices</name>
<value>hacluster</value>
</property>
<property>
<!-- hacluster集群下有两个namenode,分别为nn1,nn2 -->
<name>dfs.ha.namenodes.hacluster</name>
<value>nn1,nn2</value>
</property>
<!-- nn1的rpc、servicepc和http通信 -->
<property>
<name>dfs.namenode.rpc-address.hacluster.nn1</name>
<value>hdp51:9000</value>
</property>
<property>
<name>dfs.namenode.servicepc-address.hacluster.nn1</name>
<value>hdp51:53310</value>
</property>
<property>
<name>dfs.namenode.http-address.hacluster.nn1</name>
<value>hdp51:50070</value>
</property>
<!-- nn2的rpc、servicepc和http通信 -->
<property>
<name>dfs.namenode.rpc-address.hacluster.nn2</name>
<value>hdp52:9000</value>
</property>
<property>
<name>dfs.namenode.servicepc-address.hacluster.nn2</name>
<value>hdp52:53310</value>
</property>
<property>
<name>dfs.namenode.http-address.hacluster.nn2</name>
<value>hdp52:50070</value>
</property>
<property>
<!-- 指定namenode的元数据在JournalNode上存放的位置 -->
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://hdp50:8485;hdp51:8485;hdp52:8485/hacluster</value>
</property>
<property>
<!-- 指定JournalNode在本地磁盘存放数据的位置 -->
<name>dfs.journalnode.edits.dir</name>
<value>/opt/module/hadoop/dfs/journalnode_data</value>
</property>
<property>
<!-- namenode操作日志的存放位置 -->
<name>dfs.namenode.edits.dir</name>
<value>/opt/module/hadoop/dfs/edits</value>
</property>
<property>
<!-- 开启namenode故障转移自动切换 -->
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
<property>
<!-- 配置失败自动切换实现方式 -->
<name>dfs.client.failover.proxy.provider.hacluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
<property>
<!-- 配置隔离机制 -->
<name>dfs.ha.fencing.methods</name>
<value>sshfence</value>
</property>
<property>
<!-- 使用隔离机制需要SSH免密登录 -->
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/home/hdp/.ssh/id_rsa</value>
</property>
<property>
<!--hdfs文件操作权限,false为不验证-->
<name>dfs.permissions</name>
<value>false</value>
</property>
</configuration>
6. mapred-site.xml
- hdp52:任务历史服务器地址
- 通信:10020
- web:19888
<configuration>
<property>
<!--指定mapreduce运行在yarn上-->
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<property>
<!--配置任务历史服务器地址-->
<name>mapreduce.jobhistory.address</name>
<value>hdp52:10020</value>
</property>
<property>
<!--配置任务历史服务器web-UI地址-->
<name>mapreduce.jobhistory.webapp.address</name>
<value>hdp52:19888</value>
</property>
<property>
<!--开启uber模式-->
<name>mapreduce.job.ubertask.enable</name>
<value>true</value>
</property>
<property>
<name>mapreduce.job.complete.cancel.delegation.tokens</name>
<value>false</value>
</property>
</configuration>
7. yarn-site.xml
- hdp50:主RM
- hdp52:备RM
<configuration>
<property>
<!-- 开启Yarn高可用 -->
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>
<property>
<!-- 指定Yarn集群在zookeeper上注册的节点名 -->
<name>yarn.resourcemanager.cluster-id</name>
<value>hayarn</value>
</property>
<property>
<!-- 指定两个ResourceManager的名称 -->
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2</value>
</property>
<property>
<!-- 指定rm1的主机 -->
<name>yarn.resourcemanager.hostname.rm1</name>
<value>hdp50</value>
</property>
<property>
<!-- 指定rm2的主机 -->
<name>yarn.resourcemanager.hostname.rm2</name>
<value>hdp52</value>
</property>
<property>
<!-- 配置zookeeper的地址 -->
<name>yarn.resourcemanager.zk-address</name>
<value>hdp50:2181,hdp51:2181,hdp52:2181</value>
</property>
<property>
<!-- 开启Yarn恢复机制 -->
<name>yarn.resourcemanager.recovery.enabled</name>
<value>true</value>
</property>
<property>
<!-- 配置执行ResourceManager恢复机制实现类 -->
<name>yarn.resourcemanager.store.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
</property>
<property>
<!--指定主resourcemanager的地址-->
<name>yarn.resourcemanager.hostname</name>
<value>hdp50</value>
</property>
<property>
<!--NodeManager获取数据的方式-->
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<!--开启日志聚集功能-->
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<property>
<!--配置日志保留7天-->
<name>yarn.log-aggregation.retain-seconds</name>
<value>604800</value>
</property>
</configuration>
8.workers/slaves
hdp50
hdp51
hdp52
三. 初始化
1. 启动3个ZK
# 如有配置环境变量,否则用绝对路径
zkServer.sh start
2. 启动3个JournalNode
# 旧版本
hadoop-daemon.sh start journalnode
# 新版本
hdfs --daemon start journalnode
3. 格式化NameNode
# 任意一个NameNode执行
hdfs namenode -format
4. 复制元数据到备NameNode
scp -r /opt/module/hadoop/dfs/namenode_data/current hdp@hdp52:/opt/module/hadoop/dfs/namenode_data/
5. 格式化zkfc
# 在任意一个 NameNode执行
hdfs zkfc -formatZK
6. 启动HDFS
# NameNode 主从机制为抢占模式,所以在 主NameNode(hdp51)节点启动
# hdfs全部启动
start-dfs.sh
# 单独启动 namenode
hdfs --daemon start namenode
7.启动YARN相关服务
# 同HDFS, 属于抢占, 在hdp50启动
# 全部启动
start-yarn.sh
# 单独启动 resourcemanager
yarn --daemon start resourcemanager
8. 其它服务
# 任务历史服务器 hdp52
# 旧版
mr-jobhistory-daemon.sh start historyserver
# 新版
mapred --daemon start historyserver
# 备RM hdp52
# 旧版
yarn-daemon.sh start resourcemanager
# 新版
yarn --daemon start resourcemanager
四.查看集群
# 1、jps查看
# 2、hdfs haadmin
[hdp@docker ~]$ hdfs haadmin -getServiceState nn1
active
[hdp@docker ~]$ hdfs haadmin -getServiceState nn2
standby
[hdp@docker ~]$ yarn rmadmin -getServiceState rm1
active
[hdp@docker ~]$ yarn rmadmin -getServiceState rm2
standby
# 3. web查看
# 主NN
http://192.168.126.51:50070/
# 备NN
http://192.168.126.52:50070/
# 主RM
http://192.168.126.50:8088/
# 备RM
http://192.168.126.52:8088/
五. 日常启停
-
ZooKeeper 全部启动
-
主NameNode节点 [hdp51] 启动HDFS:start-dfs.sh
- 该命令会启动所有高可用相关服务:
- NameNode
- DataNode
- JournalNode
- DFSZKFailoverController
- 该命令会启动所有高可用相关服务:
-
主ResourceManager节点 [hdp50] 启动yarn:start-yarn.sh
-
单独启动备RM(新旧命令2选1):
- yarn-daemon.sh start resourcemanager
- yarn --daemon start resourcemanager
-
单独启动任务历史服务器:
- mr-jobhistory-daemon.sh start historyserver
- mapred --daemon start historyserver
六. 常见问题
-
PATH=$PATH:/sbin:/usr/sbin fuser -v -k -n tcp 9000 via ssh: bash: fuser: 未找到命令
- NameNode节点上安装上psmisc即可
- sudo yum -y install psmisc
- 内网就下载RPM包:yumdownload --resolve psmisc
-
存在两个NameNode都不干活,均处于standby
- 方法1:强制转换
- hdfs haadmin -transitionToActive nn1 --forcemanual
- 方法2:重启zkfc
- hdfs --daemon stop zkfc (新版)
- hdfs --daemon start zkfc;
- hadoop-daemon.sh stop zkfc (旧版)
- hadoop-daemon.sh start zkfc;
- 方法1:强制转换
-
开启ZKFC后,手动切换NameNode失败:
- NN1本来是active的,服务挂了重启后,状态变为standby;
- 使用 hdfs haadmin -transitionToActive --forcemanual nn1 无效;
- 解决方法:既然开启了自动切换,不能将NN1变为active,那先将NN2变成standby后,NN1不就自动切换成active了;
- 将NN2切换成standby:hdfs haadmin -transitionToStandby --forcemanual nn2;
-
NN切换和RM切换日志:
- 在备机查看:只要一切换该日志就会产生记录, tail -f 后敲几个空格, 然后等待记录
- NN日志:$HADOOP_HOME/logs/hadoop-hdp-zkfc-zookeeper.log
- RM日志:$HADOOP_HOME/hadoop-root-resourcemanager-zookeeper.log
- 在备机查看:只要一切换该日志就会产生记录, tail -f 后敲几个空格, 然后等待记录
ending
浙公网安备 33010602011771号