ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Hadoop HDFS-HA

2022-01-11 12:05:26  阅读:199  来源: 互联网

标签:HDFS hadoop102 ranan Hadoop yarn hadoop hadoop103 HA


目录

Hadoop HDFS-HA

HA(High Availablity)

1.高可用:7*24小时不中断服务。
2.实现高可用最关键的策略是消除单点故障(一个节点故障,整个集群不可以使用),HA严格来说应该分成各个组件的HA机制:HDFS的HA和YARN的HA。
3.NameNode主要在以下两个方法影响HDFS集群
NameNode集群发生意外,如宕机,集群将无法使用,直到管理员重启。
NameNode机器需要升级,包括软件、硬件升级,此时集群也将无法使用

HDFS HA 功能通过配置多个NameNodes(1个Active/多个Standby)实现在集群中对NameNode的热备份来解决问题。如果出现故障可以将Standby替换Active。

HDFS-HA 集群搭建

当前HDFS集群的规划

image

HA的主要目的是消除NameNode的单点故障,需要将HDFS集群重新规划,这里规划3个。

image

HDFS-HA 核心问题

1.如何保证三台NameNode的数据一致

Fsimage:需要一台NameNode作为Active生成数据,其他NameNode作为Standby进行同步
Edits:需要引进新的模块JournaNode来保证edtis的文件数据一致性

2.怎么让只有一台nn是active,其他所有是standly

1.手动分配,指定某一台为active,其余为standly
2.自动分配

3.2nn在ha架构中不允许不存在,那么谁负责定期合并Fsimage和Edits?

由standly的nn

4.如果active的nn发生了问题,怎么让其他的nn变成新的active?
a.手动故障转移
b.自动故障转移:依赖框架

HDFS-HA手动配置

1 环境准备

1.修改IP
2.修改主机名和主机名与IP地址的映射
3.关闭防火墙
4.ssh免密登录
5.安装JDK,配置环境变量等

我之前已经配过了,具体流程可以看下面的博客
https://www.cnblogs.com/rananie/p/14802251.html
https://www.cnblogs.com/rananie/p/14897536.html

2 规划集群

image

3 配置HDFS-HA集群

1.在opt目录下创建一个ha文件,103、104同样需要

[ranan@hadoop102 opt]$ sudo mkdir ha
[ranan@hadoop102 opt]$ ll
总用量 0
drwxr-xr-x. 2 root  root   6 1月   5 10:28 ha # 权限属于root用户
drwxr-xr-x. 4 ranan ranan 46 6月  17 2021 module
drwxr-xr-x. 2 ranan ranan 67 7月   8 21:34 software
[ranan@hadoop102 opt]$ sudo chown ranan:ranan ha  # 修改权限
[ranan@hadoop102 opt]$ ll
总用量 0
drwxr-xr-x. 2 ranan ranan  6 1月   5 10:28 ha
drwxr-xr-x. 4 ranan ranan 46 6月  17 2021 module
drwxr-xr-x. 2 ranan ranan 67 7月   8 21:34 software

2.将/opt/module/下的hadoop-3.1.3拷贝到/opt/ha目录下

[ranan@hadoop102 opt]$ cp -r /opt/module/hadoop-3.1.3 /opt/ha/

3.删除/opt/ha/hadoop-3.1.3 下的data和logs文件,删除数据

[ranan@hadoop102 hadoop-3.1.3]$ rm -rf data/ logs/

4.配置/opt/ha/hadoop-3.1.3/etc/hadoop/目录下的core-site.xmlhdfs-site.xml

<!-- core-site.xml -->
<configuration>
  <!-- 指定 NameNode 的地址 -->
<property>
        <name>fs.defaultFS</name>
        <value>hdfs://mycluster</value> <!--不需要单独指定一个节点为NameNode,我们访问的是mycluster,访问代理类来处理访问让访问连接到active节点-->
</property>
   <!-- 指定 hadoop 数据的存储目录 -->
<property>
        <name>hadoop.tmp.dir</name>
        <value>/opt/ha/hadoop-3.1.3/data</value>    
</property>
</configuration>


<!--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>file://${hadoop.tmp.dir}/jn</value>
</property>

     <!-- 完全分布式集群名称 -->
<property>
        <name>dfs.nameservices</name>
        <value>mycluster</value>  <!--与core-site.xml里面的fs.defaultFS设置一致-->
</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> <!--与上述设置的集群中的namenode一致-->
        <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> <!--与上述设置的集群中的namenode一致-->
        <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,客户端访问mycluster集群,并不知道哪个节点是active,由代理类帮客户连接到active-->
<property>
<name>dfs.client.failover.proxy.provider.mycluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>

<!-- 配置隔离机制,即同一时刻只能有一个NameNode对外响应 -->
<property>
<name>dfs.ha.fencing.methods</name>
<value>sshfence</value>
</property>

<!-- 使用隔离机制时需要 ssh 无秘钥登录,自动故障转移时用到-->
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/home/ranan/.ssh/id_rsa</value>
</property>

</configuration>

5.分发配置信息

[ranan@hadoop102 opt]$ xsync ha/hadoop-3.1.3

4 启动HDFS-HA集群

1 修改3台节点的环境配置信息,关于hadoop的配置信息,我的在/etc/profile.d/my_env.sh

[ranan@hadoop103 hadoop-3.1.3]$ cd /etc/profile.d
[ranan@hadoop103 profile.d]$ sudo vim my_env.sh 
[ranan@hadoop102 profile.d]$ source /etc/profile  # 会重新加载profile脚本,该脚本里会加载profile.d

image

2 在各个JournalNode节点上,启动JournalNode服务

[ranan@hadoop102 hadoop-3.1.3]$  hdfs --daemon start journalnode
[ranan@hadoop103 hadoop-3.1.3]$  hdfs --daemon start journalnode
[ranan@hadoop104 hadoop-3.1.3]$  hdfs --daemon start journalnode
[ranan@hadoop102 hadoop]$ jpsall
=============== hadoop102 ===============
4005 Jps
3933 JournalNode
=============== hadoop103 ===============
3738 Jps
3679 JournalNode
=============== hadoop104 ===============
3699 JournalNode
3757 Jps

3 在启动集群之前,需要格式化namenode,但是现在三台节点都是namenode,我们可以随便选择一个节点格式化,其他节点同步该信息,namenode需要一致

在nn1,对其格式化,并启动

[ranan@hadoop102 hadoop]$ hadfs namenode -farmat
[ranan@hadoop102 hadoop]$  hdfs --daemon start namenode

查看是否启动成功:http://hadoop102:9870/

image

在nn2和nn3上,同步nn1的元数据信息

[ranan@hadoop103 hadoop-3.1.3]$ hdfs namenode -bootstrapStandby
[ranan@hadoop104 hadoop-3.1.3]$ hdfs namenode -bootstrapStandby
[ranan@hadoop103 hadoop-3.1.3]$ hdfs --daemon start namenode
[ranan@hadoop104 hadoop-3.1.3]$ hdfs --daemon start namenode

查看是否启动成功:http://hadoop103:9870/,http://hadoop104:9870/
image
image

4 修改其中一个节点为Active节点
因为这是我们手动配置的,所以所有节点都是standby,我们需要手动的修改其中一个为Active节点

先在所有节点上,启动datanode,将HDFS启动起来

[ranan@hadoop102 hadoop-3.1.3]$ hdfs --daemon start datanode
[ranan@hadoop103 hadoop-3.1.3]$ hdfs --daemon start datanode
[ranan@hadoop104 hadoop-3.1.3]$ hdfs --daemon start datanode
[ranan@hadoop102 hadoop]$ jpsall
=============== hadoop102 ===============
4200 NameNode
4570 DataNode
4747 Jps
3933 JournalNode
=============== hadoop103 ===============
3976 NameNode
4408 Jps
4238 DataNode
3679 JournalNode
=============== hadoop104 ===============
3699 JournalNode
4259 DataNode
3990 NameNode
4427 Jps

将nn1切换为Active

[ranan@hadoop102 hadoop]$ hdfs haadmin -transitionToActive nn1

image

5 假设nn1挂掉了

kill nn1

[ranan@hadoop102 hadoop]$ jpsall
=============== hadoop102 ===============
4200 NameNode
4570 DataNode
19355 Jps
3933 JournalNode
=============== hadoop103 ===============
3976 NameNode
18923 Jps
4238 DataNode
3679 JournalNode
=============== hadoop104 ===============
3699 JournalNode
4259 DataNode
3990 NameNode
19033 Jps
[ranan@hadoop102 hadoop]$ kill -kill 4200
[ranan@hadoop102 hadoop]$ jpsall
=============== hadoop102 ===============
4570 DataNode
3933 JournalNode
19422 Jps
=============== hadoop103 ===============
18992 Jps
3976 NameNode
4238 DataNode
3679 JournalNode
=============== hadoop104 ===============
3699 JournalNode
4259 DataNode
3990 NameNode
19103 Jps

假设此时我们把nn2设置为active,报错102拒绝连接

[ranan@hadoop103 hadoop-3.1.3]$ hdfs haadmin -transitionToActive nn2
2022-01-11 10:10:18,292 INFO ipc.Client: Retrying connect to server: hadoop102/192.168.10.102:8020. Already tried 0 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=1, sleepTime=1000 MILLISECONDS)
Unexpected error occurred  Call From hadoop103/192.168.10.103 to hadoop102:8020 failed on connection exception: java.net.ConnectException: 拒绝连接; For more details see:  http://wiki.apache.org/hadoop/ConnectionRefused
Usage: haadmin [-ns <nameserviceId>] [-transitionToActive [--forceactive] <serviceId>]

重启nn1,发现nn1变成了standby,现在没有active了,可以重新选取节点成为新的active

[ranan@hadoop102 hadoop]$ hdfs --daemon start namenode

image

手动模式下,需要所有namenode启动才可以将某个节点转成Active

Active需要知道其他namenode是存活状态,因为一个集群中只能由一个Active,如果联系不上,不知道该节点是否是active。

HDFS-HA自动模式

HDFS-HA 自动故障转移工作机制

主要需要解决的问题:当要提升某个节点为Active的时候,如果确定其他节点不是Active

ZooKeeper 是维护少量协调数据,通知客户端这些数据的改变和监视客户端故障的高可用服务
自动故障增加了两个新组件:Zookeeper和ZKFailoverController(ZKFC)进程,该进程监控节点是否挂掉,如果监控到挂点了,再次发送kill命令真正杀死节点,防止出现脑裂。

image

HDFS-HA 自动故障转移的集群规划

image

配置HDFS-HA 自动故障转移

1 在hdfs-site.xml里面打开自动转移

<!--打开自动转移-->
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>

2 在core-site.xml里面添加zookeeper信息

<property>
<name>ha.zookeeper.quorum</name>
<value>hadoop102:2181,hadoop103:2181,hadoop104:2181</value>
</property>

3 分发节点

[ranan@hadoop102 hadoop]$ xsync core-site.xml hdfs-site.xml

4 保持集群关闭状态下,启动Zookeeper集群,再初始化HA在Zookeeper中状态

# 启动zookeep
[ranan@hadoop102 zookeeper-3.4.10]# zkServer.sh start
[ranan@hadoop103 zookeeper-3.4.10]# zkServer.sh start
[ranan@hadoop104 zookeeper-3.4.10]# zkServer.sh start

# 初始化HA在Zookeeper中的状态
[ranan@hadoop102 zookeeper-3.4.10]# hdfs zkfc -formatZK

5 启动集群

[ranan@hadoop102 hadoop]# start-dfs.sh

image

6 可以去zkCli.sh客户端查看NameNode节点内容

哪台机器先启动DFSZK Failover Controller,哪个机器的NameNode就是Active NameNode

[ranan@hadoop102 zookeeper]# bin/zkcli.sh

get -s /hadoop-ha/mycluster/ActiveStandbyElectorLock
mycluster nn2 hadoop103  # 这里是hadoop103节点

image

7 杀死Hadoop103,观察Active是否转移

Active切换到hadoop102后,如果hadoop103重新启动,hadoop103不再是Active而是Standby

[ranan@hadoop103 zookeeper]# kill -9 4897

# zkcli.sh客户端查看
get -s /hadoop-ha/mycluster/ActiveStandbyElectorLock
mycluster nn1 hadoop102  # 这里切换到了hadoop102了

注意如果写代码上传到比如根目录使用hdfs://mycluster/
在上传过程中会去找active,所以可能在尝试中会连接到standby,有报错但是没关系。

YARN-HA配置

YARN-HA 工作机制

image

配置YARN-HA集群

1 集群规划

image

2 核心问题
a.如果当前active rm挂了,其他rm怎么上位
核心原理和hdfs一样,利用了zk的临时节点

b.当前rm上有很多的计算程序在等待运行,其他rm怎么将这些程序接手过来继续跑

rm会将当前的所有计算程序的状态存储在zk中,其他rm上位后会去读取,然后接着跑

3 修改yarn-site.xml,修改之后分发yarn-site.xml

<configuration>
<!--读取数据的方式-->
<property>
	<name>yarn.nodemanager.aux-services</name>
	<value>mapreduce_shuffle</value>
</property>

<!--启用 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>
<property>
	<name>yarn.resourcemanager.ha.rm-ids</name>
	<value>rm1,rm2,rm3</value>
</property>
<!--rm1的配置-->
<property>
	<name>yarn.resourcemanager.hostname.rm1</name>
	<value>hadoop102</value><!--指定rm1 的主机名-->
</property>
<property>
	<name>yarn.resourcemanager.webapp.address.rm1</name>
	<value>hadoop102:8088</value><!--指定rm1的web端地址-->
</property>	
<property>
	<name>yarn.resourcemanager.address.rm1</name>
	<value>hadoop102:8032</value><!--指定rm1的内部通信地址-->
</property>
<property>
<name>yarn.resourcemanager.scheduler.address.rm1</name>
	<value>hadoop102:8030</value><!--指定AM向rm1申请资源的地址-->
</property>
<property>
<name>yarn.resourcemanager.resource-tracker.address.rm1</name>
	<value>hadoop102:8031</value><!--指定供NM连接的地址-->
</property>	
<!--rm2的配置-->
<property>
	<name>yarn.resourcemanager.hostname.rm1</name>
	<value>hadoop103</value><!--指定rm2 的主机名-->
</property>
<property>
	<name>yarn.resourcemanager.webapp.address.rm1</name>
	<value>hadoop103:8088</value><!--指定rm2的web端地址-->
</property>	
<property>
	<name>yarn.resourcemanager.address.rm1</name>
	<value>hadoop103:8032</value><!--指定rm2的内部通信地址-->
</property>
<property>
<name>yarn.resourcemanager.scheduler.address.rm1</name>
	<value>hadoop103:8030</value><!--指定AM向rm2申请资源的地址-->
</property>
<property>
<name>yarn.resourcemanager.resource-tracker.address.rm1</name>
	<value>hadoop103:8031</value><!--指定供NM连接的地址-->
</property>	
<!--rm3的配置-->
<property>
	<name>yarn.resourcemanager.hostname.rm1</name>
	<value>hadoop104</value><!--指定rm3 的主机名-->
</property>
<property>
	<name>yarn.resourcemanager.webapp.address.rm1</name>
	<value>hadoop104:8088</value><!--指定rm3的web端地址-->
</property>	
<property>
	<name>yarn.resourcemanager.address.rm1</name>
	<value>hadoop104:8032</value><!--指定rm3的内部通信地址-->
</property>
<property>
<name>yarn.resourcemanager.scheduler.address.rm1</name>
	<value>hadoop104:8030</value><!--指定AM向rm3申请资源的地址-->
</property>
<property>
<name>yarn.resourcemanager.resource-tracker.address.rm1</name>
	<value>hadoop104:8031</value><!--指定供NM连接的地址-->
</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>

<property><!--环境变量的继承-->
<name>yarn.nodemanager.env-whitelist</name>
<value>JAVA_HOME,HADDOP_COMMON_HOME,HADOOP_HDFS_HOME,HADDOP_CONF_DIR,CLASSPATH_PREPEND_DISTCACHE,HADOOP_YARN_HOME,HADOOP_MAORED_HOME</value>
</property>
</configuration>

4 启动yarn

[ranan@hadoop102 hadoop]$ start-yarn.sh

# 查看服务状态
[ranan@hadoop102 hadoop]$ yarn rmadmin -getServiceState rm1
standby

image

访问hadoop102:8088发现直接跳到了hadoop103:8088,因为这里hadoop103:8088是Active。

标签:HDFS,hadoop102,ranan,Hadoop,yarn,hadoop,hadoop103,HA
来源: https://www.cnblogs.com/rananie/p/15763722.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有