hadoop搭建高可用集群
问题:现有集群存在哪些问题?HDFS集群,单个NN场景下,如果NN故障了,整个HDFS集群就不可用(中心化集群),解决方案是配置多个NN。
但是问题又来了,多个NN的场景下由哪一台对外提供服务呢?
当HDFS实现多NN的高可用后,但是只有一台NN对外提供服务,其他的NN都是替补,当正在提供服务的NN宕机故障(standby),其他的NN自动切换Active状态
当一台NN故障后,其他NN如果争抢上位
采用高可用集群中的自动故障转移机制来完成切换
2NN在高可用的集群中还要不要
不需要,元数据的维护策略还继续保证原样,但是在高可用集群中,会添加一个新的服务(JournalNode),这个服务本身自己也要搭建成一个集群的状态,他和Zookeeper集群很像,存活机器数量过半,就能正常提供服务。它主要负责编辑日志文件edit的内容共享
手动搭建HA集群
前期准备工作
1. 在/opt/module/下创建文件夹 ha
mkdir /opt/module/ha
2. 将目前的hadoop安装目录拷贝到 /opt/module/ha
cp -r hadoop-3.1.3/ ha/
3. 删除一些多余的目录文件 保证是一个初始化集群的状态(回到最文件状态)
rm -rf data/ logs/ input_smallfile/ output output1 wcinput/ wcoutput/
4. 修改HADOOP_HOME的环境变量 vim /etc/profile.d/my_env.sh
HADOOP_HOME=/opt/module/ha/hadoop-3.1.3
5. 修改完环境变量记得分发哦
my_rsync.sh /etc/profile.d/my_env.sh
正式搭建HA集群
-
修改配置文件 core-site.xml
<configuration> <!-- 把多个NameNode的地址组装成一个集群mycluster --> <property> <name>fs.defaultFS</name> <value>hdfs://mycluster</value> </property> <!-- 指定hadoop数据的存储目录 --> <property> <name>hadoop.tmp.dir</name> <value>/opt/module/ha/hadoop-3.1.3/data</value> </property> <!-- 配置HDFS网页登录使用的静态用户为atguigu --> <property> <name>hadoop.http.staticuser.user</name> <value>atguigu</value> </property> <!-- 配置该atguigu(superUser)允许通过代理访问的主机节点 --> <property> <name>hadoop.proxyuser.atguigu.hosts</name> <value>*</value> </property> <!-- 配置该atguigu(superUser)允许通过代理用户所属组 --> <property> <name>hadoop.proxyuser.atguigu.groups</name> <value>*</value> </property> <!-- 配置该atguigu(superUser)允许通过代理的用户--> <property> <name>hadoop.proxyuser.atguigu.groups</name> <value>*</value> </property> </configuration>
5.修改配置文件 hdfs-site.xml
<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/atguigu/.ssh/id_rsa</value> </property> </configuration>
6.分发刚才修改的两个配置文件core-site.xml,hdfs-site.xml到103,104机器
# pwd = /opt/module/ha/hadoop-3.1.3/etc/hadoop [atguigu@hadoop102 hadoop]$ my_rsync core-site.xml hdfs-site.xml
7.在102、103、104 各个JournalNode节点上,输入以下命令启动journalnode服务
hdfs --daemon start journalnode 此时会发现在/data目录下面生成了一个jn文件夹
8.在 hadoop102的 nn1 上,对其进行格式化,并启动
hdfs namenode -format # 记得要删除之前生成的 /data, /logs文件夹 hdfs --daemon start namenode
9.分别在 hadoop103的nn2 和 hadoop104的nn3上,同步nn1的元数据信息
hdfs namenode -bootstrapStandby 此时会在/data目录下生成/name文件夹,如果没有生成一定要确认命令是否执行成功
10.分别在 hadoop103上启动nn1 和 hadoop104上启动nn2
hdfs --daemon start namenode
11.通过web地址访问nn1 nn2 nn3
http:hadoop102:9870 http:hadoop103:9870 http:hadoop104:9870
12.在每台机器上启动DN
hdfs --daemon start datanode
13.将其中的一个nn切换成Active状态
hdfs haadmin -transitionToActive nn1
14.查看是否Active
hdfs haadmin -getServiceState nn1
至此,手动版的hadoop的高可用集群已经搭建完毕,但是现在想一个问题,目前是nn2是active状态,但是如果nn2宕机了呢?其他的两台机器的nn是否会上位成为active状态呢?经测试,发现不行,并且手动切换nn的状态为active也不行
考虑到102可能假死状态,所以才不让手动切换
重新启动102的hdfs集群,start-dfs.sh,这个时候102又变成了standby状态,又需要重新手动指定哪台机器为active状态。很麻烦,这个时候并不是自动实现故障转移
完整HDFS HA集群
自动故障转移机制原理
自动故障转移为HDFS部署增加了两个新组件:ZooKeeper和ZKFailoverController(ZKFC)进程
ZKFC的功能:当集群启动时候每一台NN的zkfc会到zk指定的节点上写入属于自己的内容,哪一台NN成功写入,相当于争抢上位成功,成为Active,zkfc主要用于监测当前nn的健康状态,通过ping的方式,一旦发现当前nn不可用,就会立刻和zk通信,告知zk当前active状态的nn不可用了,zk把属于之前active机器的内容从节点删除,接下来zk通过通知机制告知其他nn的zkfc进程。大家又来抢着写内容
集群规划
hadoop102 : Namenode Datanode JournalNode ZKFC ZK
hadoop103 : Namenode Datanode JournalNode ZKFC ZK
hadoop104 : Namenode Datanode JournalNode ZKFC ZK
实现HA的故障自动转移
-
在core-site.xml文件中增加
<!-- 指定zkfc要连接的zkServer地址 --> <property> <name>ha.zookeeper.quorum</name> <value>hadoop102:2181,hadoop103:2181,hadoop104:2181</value> </property>
-
在hdfs-site.xml中增加
<!-- 启用nn故障自动转移 --> <property> <name>dfs.ha.automatic-failover.enabled</name> <value>true</value> </property>
-
修改后分发配置文件
my_rsync /opt/module/ha/hadoop-3.1.3/etc/hadoop
-
关闭HDFS集群
stop-dfs.sh
-
启动Zookeeper集群
zk_cluster.sh start
-
初始化HA在Zookeeper中状态
hdfs zkfc -formatZK
-
启动HDFS服务
start-dfs.sh
测试故障自动转移
加入YARN HA集群规划
hadoop102 : Namenode Datanode JournalNode ZKFC ZK ResourceManager NodeManager
hadoop103 : Namenode Datanode JournalNode ZKFC ZK ResourceManager NodeManager
hadoop104 : Namenode Datanode JournalNode ZKFC ZK ResourceManager NodeManager
YARN HA 集群搭建步骤
-
修改yarn-site.xml
<!-- 启用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的配置 ========== --> <!-- 指定rm3的主机名 --> <property> <name>yarn.resourcemanager.hostname.rm3</name> <value>hadoop104</value> </property> <property> <name>yarn.resourcemanager.webapp.address.rm3</name> <value>hadoop104:8088</value> </property> <property> <name>yarn.resourcemanager.address.rm3</name> <value>hadoop104:8032</value> </property> <property> <name>yarn.resourcemanager.scheduler.address.rm3</name> <value>hadoop104:8030</value> </property> <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.ZKRMStateStore</value> </property>
-
将yarn-site.xml文件进行分发
[atguigu@hadoop102 hadoop]$ my_rsync.sh yarn-site.xml
-
在任意的机器上启动yarn
start-yarn.sh # 注意这里的zk已经启动完毕
-
通过访问web地址验证
启动成功,发现每次只能进入一个页面,其他的页面也会自动重定向到Active的机器
-
测试Yarn故障自动转移
ok,至此,hadoop的高可用集群搭建完毕!