IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> Zookeeper——保证HDFS的高可用性 -> 正文阅读

[大数据]Zookeeper——保证HDFS的高可用性

一、Zookeeper ----- 保证HDFS系统的高可用性

1.zookeeper在解决HDFS的NameNode过程中存在的问题

1. NameNode在hdfs系统中只能存在一个存在单点故障风险
2. NameNode备机在检测等待主机挂掉的过程中一直处于空闲状态造成的资源浪费
3. NameNode仍然存在少量数据丢失的问题(在主机挂机的前一刻记录的日志信息还没来得及持久化)
4. NameNode假死和双主问题(当主机只是暂时的失联,zookeeper认为他宕机了,就让备胎上位,然而主机这时候并没有宕机,此时出现双主机问题)
5. NameNode主备自动切换,客户端无法知晓入口地址(因为主机可以和备用机可以不停的自由切换导致无法在代码编写过程中写死地址)

2.针对上面这几个问题的对应解决方案

  1. NameNode单点故障
思路:准备一个NameNode备用机器,在主NameNode挂机的时候自动转换到备用机器运行。
在两个NameNode机器上,各自提供一个zkclient。负责注册节点,并监控节点变化
方案:ZKFC--基于zookeeper实现的故障转移程序(如果主机挂了,怎么自动切换成) 
详解:
1.在部署好分布式环境之后,在刚启动的时候并没有主备之分,
只不过是同时启动,看谁的数据先到zookeeper中注册节点谁就是主机,
第二个去的晚的就只能等着,当备用机,监听主机的状态,当监听到主机挂机之后进行自动切换

2.主机挂了之后,它是怎么实现自动切换的呢。它用到了 ZKFC:zookeeper failover controller(zk故障转移)技术。
	zkfc是一个进程,内置了zookeeper的客户端操作,同时可以远程登录杀死原namenode
7. 启动namenode后,它会检查zookeeper是否已经存在了一个存储一个节点
     如果不存在,则自己注册该节点create -e  /a1 。自己成为namenode主机
     如果存在,  则监听该节点  get /a1 watch 。   成为namenode备机
4.NameNode主机宕机了,则刚创建的临时节点自动消失,zookeeper服务器端会通知其他监听该节点的客户端(NameNode备机)
  NameNode备机接收到通知之后,向zookeeper中注册临时节点
  1. NameNode假死和双主问题
问题:如果namenode并没有挂掉,只是有网络等问题没有及时向zk服务器端发送心跳,
	导致zookeeper服务器认为namenode主机挂掉了,会导致HDFS出现双主机(namenode)的情况。
解决:在备机准备上位的时候,它不管现在的主节点是不是真的挂机了,
	  他都会使用远程登录技术ssh登录到主机上,使用kiillall namenode 杀死它的namenode进程
	  确保它真的死了。有效的防止了出现双主机的问题

3.NameNode备机在检测等待主机挂掉的过程中一直处于空闲状态造成的资源浪费

对于这个问题,zookeeper在部署的时候删除了之前hdfs集群中做chickpoint工作的secondnamenode进程,
并让备用机接替它的工作,既保证了主机切换后备机没有主机元数据的问题,有解决了备机在检测等待主机挂掉
的过程中一直处于空闲状态造成的资源浪费的问题
1.NameNode处于备机状态时,会充当SecondaryName的职责
2.NameNode备机会执行checkpoint操作,所以备机里面存储的有最新的FSImage快照文件,转为主机时可以直接使用
  1. NameNode仍然存在少量数据丢失的问题
在主机挂机的前一刻记录的日志信息还没来得及持久化,所以即使备用机器里面存储的有最新的快照,也不能完全恢复到之前主机宕机时的状态。
解决:
	1.在主机工作的时候会使用日志和快照两种机制来进行持久化,那么在主机宕机之前它的一部分工作日志会记录在editslog_inprogress
	日志文件中,还没来得及发给备用机做持久化。
	2.既然这个日志文件实在硬盘上存储的,那就可以将这个日志文件进行实时共享。然后备用机在进行切换的时候拿着自己的最新的快照 ,然后再到
	其他的正常的主机上拿到实时共享的日志文件进行执行,就可以还原到原主机在宕机前的状态了。这就是 :QJN(journal node(共享目录)机制)
  1. NameNode主备自动切换,客户端无法知晓入口地址

	客户端连接HDFS时如何提供入口地址
    非HA做法 fs.defaultFS    hdfs://hadoop11:9000
    HA做法     fs.defaultFS    hdfs://hdfs-cluter

图示:
在这里插入图片描述

二、HA Hadoop(High Available Hadoop) 高可用Hadoop集群安装

1.配置NN主机和NN备机所在节点的免密登录

1. NameNode主节点执行
生成密钥(在namenode主和namenode备生成,将公钥发布其他节点)
[root@hadoop11 ~]# ssh-keygen
 发送公钥(所有NameNode节点都要发送)
[root@hadoop11 ~]# ssh-copy-id hadoop11
[root@hadoop11 ~]# ssh-copy-id hadoop12
[root@hadoop11 ~]# ssh-copy-id hadoop13
2. NameNode备机节点执行
生成密钥(在namenode主和namenode备生成,将公钥发布其他节点)
[root@hadoop12 ~]# ssh-keygen
发送公钥(所有NameNode节点都要发送)
[root@hadoop12 ~]# ssh-copy-id hadoop11
[root@hadoop12 ~]# ssh-copy-id hadoop12
[root@hadoop12 ~]# ssh-copy-id hadoop13

2.安装psmisc

ZKFC远程杀死假死SNN使用的killall namenode命令属于psmisc软件中的。
建议所有节点都安装psmisc
[root@hadoop11 ~]# yum install -y psmisc
[root@hadoop12 ~]# yum install -y psmisc
[root@hadoop13 ~]# yum install -y psmisc

3.安装配置jdk

1. 解压jdk
  [root@hadoop11 modules]# tar zxvf jdk-8u221-linux-x64.tar.gz -C /opt/installs/
2. 改jdk的目录名 :  mv /opt/installs/jdk-1.8 /opt/installs/jdk1.8
3. 配置profile环境变量
  export JAVA_HOME=/opt/installs/jdk1.8
  export PATH=$PATH:$JAVA_HOME/bin  
4.刷新配置的环境变量使其生效: source /etc/profile
4. 同步集群环境:
  1. 其他节点同步JDK的安装
  2. 同步profile配置文件,
  3. 并重新加载其他节点的JDK环境变量

4.安装zookeeper

1. 上传文件到Linux并解压zookeeper
  [root@hadoop11 modules]# tar zxvf zookeeper-3.4.6.tar.gz -C /opt/installs/
2. 改名: mv zookeeper-3.4.6 zookeeper3.4.6
3. 配置zk的环境变量: vim /etc/profile
  最后一行加上下面这行代码
  export PATH=$PATH:/opt/installs/zookeeper3.4.6/bin/
4. 在zookeeper安装目录新建data目录,并编写投票编号myid文件
	mkdir data
	cd data
	echo 11 > myid
5. 初始化zoo.cfg文件
  tickTime=2000
  initLimit=10
  syncLimit=5
  dataDir=/opt/installs/zookeeper3.4.6/data #data文件目录
  clientPort=2181
  server.11=192.168.199.11:2888:3888 # zk主机信息
  server.12=192.168.199.12:2888:3888 # zk主机信息
  server.13=192.168.199.13:2888:3888 # zk主机信息
  
 6. 同步集群环境(需要安装zk的节点)
	scp zookeeper3.4.6 -R root@hadoop12:/opt/installs/
	scp /etc/profile root@hadoop12:/etc/
	.....
	  1. 同步zk的软件包
	  2. 同步zk的profile环境
	  3. 其他节点重新加载profile
	  4. 修改其他节点的myid
7. 验证启动效果,并关闭zk服务器
  zkServer.sh start
  jps
  zkServer.sh stop 

5.HA-HDFS配置文件初始化

省略hadoop软件安装过程
	1. 解压hadoop
	2. 配置hadoop的环境变量
	3. 重新加载profile文件。 

全新的Hadoop集群,要清空data目录。
0. 清空data目录,全部节点都要做
[root@hadoop11 data]# rm -rf /opt/installs/hadoop2.9.2/data
[root@hadoop11 installs]# rm -rf /opt/installs/hadoop2.9.2/logs 

1. 配置hadoop-env.sh
export JAVA_HOME=/opt/installs/jdk1.8/ 

2. 配置core-site.xml
<configuration>
    
    <!--hdfs入口,设置虚拟地址,具体地址后面配置-->
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://hdfs-cluster</value>
    </property>
    <!--hdfs集群的文件位置-->
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/opt/installs/hadoop2.9.2/data</value>
    </property>
    <!--hdfs要访问zookeeper集群-->
    <property>
        <name>ha.zookeeper.quorum</name>
        <value>hadoop11:2181,hadoop12:2181,hadoop13:2181</value>
    </property>
    
</configuration>

3. 配置hdfs-site.xml
<configuration>
    <!-- 副本数 -->
    <property>
        <name>dfs.replication</name>
        <value>3</value>
    </property>
    <!-- 定义dhfs入口的命名服务 -->
    <property>
        <name>dfs.nameservices</name>
        <value>hdfs-cluster</value>
    </property>
    <!-- 定义hdfs入口的命名服务下虚拟ip-->
    <property>
        <name>dfs.ha.namenodes.hdfs-cluster</name>
        <value>nn1,nn2</value>
    </property>
    <!-- 虚拟ip地址1 RPC入口 -->
    <property>
        <name>dfs.namenode.rpc-address.hdfs-cluster.nn1</name>
        <value>hadoop11:9000</value>
    </property>
    <!-- 虚拟ip地址1 HTTP入口 -->
    <property>
        <name>dfs.namenode.http-address.hdfs-cluster.nn1</name>
        <value>hadoop11:50070</value>
    </property>
    <!-- 虚拟ip地址2 PRC入口 -->
    <property>
        <name>dfs.namenode.rpc-address.hdfs-cluster.nn2</name>
        <value>hadoop12:9000</value>
    </property>
    <!-- 虚拟ip地址1 HTTP入口 -->
    <property>
        <name>dfs.namenode.http-address.hdfs-cluster.nn2</name>
        <value>hadoop12:50070</value>
    </property>
    
    <!-- 定义QJN在linux中保存文件磁盘目录 -->
    <property>
        <!-- Journal Edit Files 的存储目录:() -->
        <name>dfs.journalnode.edits.dir</name>
        <value>/opt/installs/journalnode/data/</value>
    </property>
    <!-- namenode要向zk的QJN写入editslog,所以要明确入口地址 -->
    <property>
        <name>dfs.namenode.shared.edits.dir</name>
        <value>qjournal://hadoop11:8485;hadoop12:8485;hadoop13:8485/hdfs-cluster</value>
    </property>

    <!-- 是否开启故障切换 -->
    <property>
        <name>dfs.ha.automatic-failover.enabled</name>
        <value>true</value>
    </property>

    <!-- 基于zookeeper的故障切换的代码类 -->
    <property>
        <name>dfs.client.failover.proxy.provider.hdfs-cluster</name>
    <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
    </property>
    
    
    <!-- 远程杀死namenode方式(防止namenode假死,导致双主出现) -->
    <property>
        <name>dfs.ha.fencing.methods</name>
        <value>sshfence</value>
    </property>
    
    <!-- 指定私钥的文件目录,使用免密登录杀死NN进程 -->
    <property>
        <name>dfs.ha.fencing.ssh.private-key-files</name>
        <value>/root/.ssh/id_rsa</value>
    </property>
    
</configuration>

# 4. 配置slaves
  hadoop11
  hadoop12
  hadoop13

# 5. 同步以上配置到其他节点
  [root@hadoop11 etc]# scp -r hadoop/ root@hadoop12:/opt/installs/hadoop2.9.2/etc/
  [root@hadoop11 etc]# scp -r hadoop/ root@hadoop13:/opt/installs/hadoop2.9.2/etc/

6.HA-HDFS初次启动

启动顺序:
1.zookeeper
2. 格式化zkfc
3. 启动QJN
4. 启动hdfs(zkfc qjn namenode datanode)
5. 声明hadoop12的namenode为备机
6. 启动nn备机

1. 启动zkserver集群
[root@hadoop11 etc]# zkServer.sh start
[root@hadoop12 etc]# zkServer.sh start
[root@hadoop13 etc]# zkServer.sh start

2. 初始化ZKFC在zk中的Znode信息【第一次启动需要做】
[root@hadoop11 etc]# hdfs zkfc -formatZK 

3. 格式化hdfs的namenode主机(在namenode主节点)【第一次启动需要做】
	1. 先启动journalnode(3)(QJN将作为NameNode存储持久化文件的空间,要先启动才能格式化)
	[root@hadoop11 etc]# hadoop-daemon.sh start journalnode
	[root@hadoop12 etc]# hadoop-daemon.sh start journalnode
	[root@hadoop13 etc]# hadoop-daemon.sh start journalnode
	  
	2. 格式化namenode主机(在NN主机节点)
	[root@hadoop11 etc]# hdfs namenode -format
	
	3. 格式化hdfs的namenode备机(namenode standby备节点)【第一次启动需要做】
		1. 先启动主namenode主机(启动整个namenode集群)
		  [root@hadoop11 etc]# start-dfs.sh
		2. 在格式化namenode备机(第一次启动)
		  [root@hadoop12 ~]# hdfs namenode -bootstrapStandby
		3. 启动namenode备机
		  [root@hadoop12 ~]# hadoop-daemon.sh start namenode
	  
	4. 以后HAHadoop启动和关闭,在NN主机节点执行命令。
	     zk集群还是要单独启动和关闭的
		[root@hadoop11 etc]# start-dfs.sh
		该命令会自动依次启动:
			    NameNode主机 
			    NameNode备机
			    DataNode有节点
			    启动所有journal node
			    启动所有zkfc
  
# 同理,在namenode主机上执行stop-dfs.sh
  会将上述所有进程都停止。 

三、Yarn-HA安装

1.修改mapred-site.xm文件:
vim /opt/installs/hadoop2.9.2/etc/hadoop/mapred-site.xml

<property>
  <!--指定 mapreduce 作业运行在 yarn 上-->
  <name>mapreduce.framework.name</name>
  <value>yarn</value>
</property>

<!-- 设置日志服务器的远程传输日志信息的端口和地址 -->
<property>
  <name>mapreduce.jobhistory.address</name>
  <value>hadoop11:10020</value>
</property>

<!-- 设置日志服务器的web访问的地址和端口 -->
<property>
  <name>mapreduce.jobhistory.webapp.address</name>
  <value>hadoop11:19888</value>
</property> 

2.修改yarn-site.xml
vim /opt/installs/hadoop2.9.2/etc/hadoop/mapred-site.xml

<!--指定yarn上允许运行的分布式代码为mapreduce-->
<property>
    <name>yarn.nodemanager.aux-services</name>
    <value>mapreduce_shuffle</value>
</property>
<!-- 开启日志聚合:将各个节点上的日志文件集中到HDFS中,便于管理 -->
<property>
  <name>yarn.log-aggregation-enable</name>
  <value>true</value>
</property>
<!-- 设置日志保存时间 -->
<property>
  <name>yarn.log-aggregation.retain-seconds</name>
  <value>106800</value>
</property>

<!--配置resourcemanager的HA-->
<property>
    <name>yarn.resourcemanager.ha.enabled</name>
    <value>true</value>
</property>
<!-- RM 集群标识 -->
<property>
    <name>yarn.resourcemanager.cluster-id</name>
    <value>yarn-cluster</value>
</property> 
 <!-- RM 的逻辑 ID 列表 -->
<property>
    <name>yarn.resourcemanager.ha.rm-ids</name>
    <value>rm1,rm2</value>
</property> 
<!-- RM1 的主机地址 -->
<property>
    <name>yarn.resourcemanager.hostname.rm1</name>
    <value>hadoop11</value>
</property>
<!-- RM1 的主机web管理界面地址 --> 
<property>
    <name>yarn.resourcemanager.webapp.address.rm1</name>
    <value>hadoop11:8088</value>
</property>
<!-- RM2 的主机地址 -->
<property>
    <name>yarn.resourcemanager.hostname.rm2</name>
    <value>hadoop12</value>
</property> 
<!-- RM2 的主机web管理界面地址 -->  
<property>
    <name>yarn.resourcemanager.webapp.address.rm2</name>
    <value>hadoop12:8088</value>
</property>
<!-- ZooKeeper 集群的地址 -->  
<property>
    <name>yarn.resourcemanager.zk-address</name>
    <value>hadoop11:2181,hadoop12:2181,hadoop13:2181</value>
</property> 
<!-- 启用自动恢复 --> 
<property>
    <name>yarn.resourcemanager.recovery.enabled</name>
    <value>true</value>
</property> 
<!-- 用于yarn故障转移持久化zk的类 -->
<property>
    <name>yarn.resourcemanager.store.class</name>
    <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
</property>  

3.同步配置文件到另外两台服务器

# 同步mapred-site.xml
[root@hadoop11 hadoop]# scp  mapred-site.xml root@hadoop12:/opt/installs/hadoop2.9.2/etc/hadoop/
[root@hadoop11 hadoop]# scp  mapred-site.xml root@hadoop13:/opt/installs/hadoop2.9.2/etc/hadoop/
# 同步yarn-site.xml
[root@hadoop11 hadoop]# scp  yarn-site.xml root@hadoop12:/opt/installs/hadoop2.9.2/etc/hadoop/
[root@hadoop11 hadoop]# scp  yarn-site.xml root@hadoop13:/opt/installs/hadoop2.9.2/etc/hadoop/ 

4.启动yarn集群

1. rm主节点执行(启动后需要等一会NodeManager才能注册到RM中)
[root@hadoop11 hadoop]# start-yarn.sh
2. rm备机节点执行启动备机
[root@hadoop12 hadoop]# yarn-daemon.sh start resourcemanager

四.编写Java代码测试部署的Hadoop HA和Yarn-HA

1.导入Linux中的四个配置文件到项目的resource文件夹中:

core-site.xml
hdfs-site.xml
mapred-site.xml
yarn-site.xml

2.在编写类的时候不再固定写死路径,而是通过 导入配置文件,自己不再手动写死

 public int run(String[] strings) throws Exception {
        //1.创建配置类对象
        Configuration conf = new Configuration();
        conf.addResource("core-site.xml");
        conf.addResource("hdfs-site.xml");
        conf.addResource("mapred-site.xml");
        conf.addResource("yarn-site.xml");
        //2.创建Job对象
        Job job = Job.getInstance(conf);
        job.setJarByClass(WordCountJob.class);
        ......

3.浏览器中打开8088和50070查看服务器集群中的状态
然后在程序执行过程中分别强制杀死NamoNode进程和ReduceManager进程
可以看到主机的自动切换和即使运行到一半他还会再重新找到另一个ReduceManager继续前面的任务执行,得到最终结果

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2021-07-09 17:33:49  更:2021-07-09 17:34:02 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/4 16:54:54-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码