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很快的切换到另外一台机器。
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 并启动
sudo mkdir /opt/ha
sudo chown atguigu:atguigu /opt/ha
#将/opt/module/下的 hadoop-3.1.3拷贝到/opt/ha目录下
cp -r /opt/module/hadoop-3.1.3 /opt/ha/
#删除复制后hadoop文件夹中的 data文件夹和logs文件夹
cd /opt/ha/hadoop-3.1.3/
rm -rf data/ logs mapreduce1-1.0-SNAPSHOT.jar
配置core-site
vim etc/hadoop/core-site.xml
#修改以下两个key的值 追加一个zookeeper集群地址
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster</value>
</property>
<!-- hadoop数据存放路径 注意为data.dir 而不tmp.dir -->
<property>
<name>hadoop.data.dir</name>
<value>/opt/ha/hadoop-3.1.3/data</value>
</property>
<!--追加 zookeeper quorum 地址 配置ZooKeeper服务集群,用于活跃NameNode节点的选举-->
<property>
<name>ha.zookeeper.quorum</name>
<value>hadoop102:2181,hadoop103:2181,hadoop104:2181</value>
</property>
</configuration>
配置hdfs-site.xml
vim etc/hadoop/core-site.xml
#覆盖原有配置
<configuration>
<!--配置NameNode的数据存储目录,需要与上文创建的目录相对应-->
<property>
<name>dfs.namenode.name.dir</name>
<value>file://${hadoop.data.dir}/name</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>file://${hadoop.data.dir}/data</value>
</property>
<!-- nameservices名称 自定义的HDFS服务名,在高可用集群中,无法配置单一HDFS服务器入口,所以需要指定一个逻辑上的服务名,当访问服务名时,会自动选择NameNode节点进行访问 -->
<property>
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>
<!-- 三个namenode 定义HDFS服务名所指向的NameNode主机名称 -->
<property>
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2, nn3</value>
</property>
<!-- namenode地址 设置NameNode的完整监听地址 -->
<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>
<!-- 配置qjn集群 设置主从NameNode元数据同步地址,官方推荐将nameservice作为最后的journal ID -->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://hadoop102:8485;hadoop103:8485;hadoop104:8485/mycluster</value>
</property>
<!-- qjn数据存放目录 配置JournalNode的数据存储目录,需要与上文创建的目录相对应 -->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>${hadoop.data.dir}/jn</value>
</property>
<!-- 代理类 设置HDFS客户端用来连接集群中活动状态NameNode节点的Java类 -->
<property>
<name>dfs.client.failover.proxy.provider.mycluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
<!-- 隔离方式 为sshfence ssh远程代理 启动fence过程,确保集群高可用性 -->
<property>
<name>dfs.ha.fencing.methods</name>
<value>sshfence</value>
</property>
<!-- ssh私有路径 设置SSH登录的私钥文件地址 -->
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/home/atguigu/.ssh/id_rsa</value>
</property>
<!-- 开启自动切换 设置自动切换活跃节点,保证集群高可用性 -->
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
</configuration>
同步
sudo xsync /opt/ha/
临时修改环境变量 因为hdfs.sh 默认根据环境变量来启动的 无法正常格式化ha中的namenode
sudo vim /etc/profile.d/my_env.sh
#修改hadoop路径 临时为ha下的hadoop
export HADOOP_HOME=/opt/ha/hadoop-3.1.3
source /etc/profile.d/my_env.sh
sudo xsync /etc/profile.d/my_env.sh
启动JQM集群
#三台都会启动 jps检查一下三台有没有journalnode
/opt/ha/hadoop-3.1.3/bin/hdfs --workers --daemon start journalnode
#如果不行删除data 和logs文件夹 重新启动 再不行看日志 JQM的数据存储路径必须为绝对路径
格式化nn
#在102节点中格式化nn
hdfs namenode -format
hdfs --daemon start namenode #启动nn
#其他节点通过同步nn1的元数据信息
#切记要在atguigu下 不要root用户下 如果无法启动nn删除data 和logs文件夹 同步
#在103和104中使用
hdfs namenode -bootstrapStandby #同步
hdfs --daemon start namenode #启动
启动zk并初始化HA在Zookeeper中状态
#先启动三台的zookeeper
zkServer.sh start
#格式一台即可以 其他集群会同步
hdfs zkfc -formatZK
启动dfs
#102
start-dfs.sh
3. HA的选举机制
通过查看3台集群的web页面 发现只有一台活动(active状态) 其他都是standby状态, 如果我把active的nn杀掉,那么ha会自动故障转移把某台standby状态的变为active状态
- 通过zookeeper选取的
- 当我们启动nn时 hadoop会自动向zookeeper上的hadoop-ha/mycluster/ActiveStandbyElectorLock 注册一个临时节点 此节点的值就是active节点名称 先在此临时节点注册的集群则成为active
- 如果active宕机 则节点会远程访问active 8020端口 并测试杀掉服务 无响应/杀掉 在zookeeper上的临时节点上注册 (此过程所有节点都会执行 谁先在临时节点注册上就是谁做active)
- hadoop-ha/mycluster/ActiveBreadCrumb 此zookeeper节点记录上一个active 名称 如果重新上线则为standby状态
如果active断网 则会尝试不断的隔离active节点 但无法连接到active 并且在隔离期间standby都无法转换为active 因为我们配置的隔离方法 是sshfence(ssh连接并尝试杀死进程) 我们可以通过逗号配置多value值
- 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的基础上 修改配置
vim /opt/ha/hadoop-3.1.3/etc/hadoop/yarn-site.xml
#追加
<!--启用resourcemanager ha 开启resourcemanager 的高可用性功能-->
<property>
<name> yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>
<!--声明两台resourcemanager的地址 标识集群中的resourcemanager,如果设置该选项,需要确保所有的resourcemanager节点在配置中都有自己的逻辑id-->
<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>cluster-yarn1</value>
</property>
<!--设置resourcemanager节点的逻辑id-->
<property>
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2</value>
</property>
<!--为每个逻辑id绑定实际的主机名称-->
<property>
<name>yarn.resourcemanager.hostname.rm1</name>
<value>hadoop102</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>hadoop103</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.ZKRMStateStore</value>
</property>
xsync /opt/ha/hadoop-3.1.3/etc/hadoop/yarn-site.xml
启动yarn
#103中启动
start-yarn.sh
查询当前yarn是standby状态 还是active
yarn rmadmin -getServiceState rm1
yarn在zookeeper下的节点名为yarn-leader-election 两个节点互相独立