Zookeeper(二)之底层原理及HAHadoop集群搭建

Zookeeper(二)之底层原理及HAHadoop集群搭建

监听通知工作机制

在这里插入图片描述

zookeeper读写数据工作流程

在这里插入图片描述

zkServer投票选主流程

选主结果与以下几个方面有关:

1:启动顺序

2:myid(权重,即级别,级别高能够获得到级别低的zk机器的投票)

3:每个机器启动,会给自己投票

主机不固定,动态选举,保证主机的可靠性,选举过程中主从之间有通信

# 假设有5台服务器,编号1,2,3,4,5。
服务器1启动,给自己投票,然后发投票信息,由于其它机器还没有启动所以它收不到反馈信息,服务器1的状态一直属于(选举状态)。
服务器2启动,给自己投票,同时与之前启动的服务器1交换结果,由于服务器2的编号大所以服务器2胜出,但此时投票数没有大于半数,所以两个服务器的状态依然是(选举状态)
服务器3启动,给自己投票,同时与之前启动的服务器1,2交换信息,由于服务器3的编号最大所以服务器3胜出,此时投票数正好大于半数,所以服务器3成为leader,服务器1,2成为follower。
服务器4启动,已经有leader,服务器4只能成为follower。
服务器5启动,后面的逻辑同服务器4成为follower。

HadoopHA(高可用)集群搭建

背景:规避数据及服务器单点故障问题

# 目前Hadoop分布式集群的问题
	1. editslog无法做到100%持久化,如果NameNode宕机会导致少量数据丢失。
	2. 一旦NameNode宕机,整个Hadoop集群还是会停止对外服务。
	3. 如果启动2个NameNode,缺乏自动切换,即使NameNode可以自动切换,客户端访问的ip地址也无法确定。
# HAHadoop集群架构设计
# QJM(Quorum Journal Manager)是Hadoop专门为Namenode共享存储基于zookeeper开发的组件
	1: 引入了监控NameNode状态的ZookeeperFailController(简称ZKFC),ZKFC一般运行在NameNode的宿主机器上,与Zookeeper集群协作完成故障的自动转移。
	2: 提供了Journal Node,每个QJN暴露一个RPC接口(远程调用),可以接受NameNode(主机)写入editslog的请求,也可以接受NameNode(备机)读取editslog的请求。而且写入数据,也遵循了zk投票机制,安全可靠。
# NameNode(备机)
	还充当了SecondaryNameNode的职责,完成CheckPoint,FsImage数据的合并的职责。

在这里插入图片描述

在这里插入图片描述

集群规划—搭建思路

在这里插入图片描述

准备工作

# 0.准备四台主机
1. 设置ip
2. 关闭防火墙
3. 设置hostname
4. 设置hosts(4台彼此之间集群互通)

安装必备软件

# 1.安装必备软件
1. 解压jdk
[root@centos8 modules]# tar zxvf jdk-8u221-linux-x64.tar.gz -C /opt/installs/
2. 解压hadoop
[root@centos8 modules]# tar zxvf hadoop-2.9.2.tar.gz -C /opt/installs/
3. 解压zookeeper
[root@centos8 modules]# tar zxvf zookeeper-3.4.14.tar.gz -C /opt/installs/
4. 安装psmisc
[root@centos8 modules]# yum install -y psmisc
# 2.统一配置如上的环境变量
1. ----------------/etc/profile-----------------------------
#JAVA
export JAVA_HOME=/opt/installs/jdk1.8
export PATH=$PATH:$JAVA_HOME/bin
# HADOOP
export HADOOP_HOME=/opt/installs/hadoop2.9.2/
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
# zookeeper
export PATH=$PATH:/opt/installs/zookeeper3.4.14/bin/
2. 加载配置文件
source /etc/profile
# 3. 同步4台主机的其他配置
0. 设置ip
1. 远程拷贝安装软件
2. 加载配置文件 /etc/profile
3. 设置hostname(4个主机)
hostnamectl set-hostname xxxx
4. 设置hosts映射
192.168.199.10 hadoop10
192.168.199.11 hadoop11
192.168.199.12 hadoop12
192.168.199.13 hadoop13
5. 配置免密登录
# 生成密钥
[root@hadoop10 ~]# ssh-keygen
[root@hadoop11 ~]# ssh-keygen
[root@hadoop12 ~]# ssh-keygen
# 发送公钥(所有NameNode节点都要发送)
[root@hadoop10 ~]# ssh-copy-id hadoop10
[root@hadoop10 ~]# ssh-copy-id hadoop11
[root@hadoop10 ~]# ssh-copy-id hadoop12
[root@hadoop10 ~]# ssh-copy-id hadoop13

[root@hadoop11 ~]# ssh-copy-id hadoop10
[root@hadoop11 ~]# ssh-copy-id hadoop11
[root@hadoop11 ~]# ssh-copy-id hadoop12
[root@hadoop11 ~]# ssh-copy-id hadoop13

zookeeper配置(3台)

# 1. 在zookeeper目录下创建data文件夹
# 2. 在zk的data文件下创建myid文件,并指定一个zk主机编号,一般用ip为编号
例如:10
# 3. 在conf目录下通过拷贝的方式创建zoo.cfg文件
tickTime=2000
initLimit=10
syncLimit=5
#data文件目录
dataDir=/opt/installs/zookeeper3.4.14/data
clientPort=2181
# zk主机信息
server.10=192.168.199.10:2888:3888
server.11=192.168.199.11:2888:3888
server.12=192.168.199.12:2888:3888
# 4. 拷贝配置信息到其他主机
[root@hadoop10 conf]# scp zoo.cfg root@hadoop11:/opt/installs/zookeeper3.4.14/conf/
[root@hadoop10 conf]# scp zoo.cfg root@hadoop12:/opt/installs/zookeeper3.4.14/conf/
# 5. 修改每个主机的myid
# 6. 启动zkServer验证是否成功
1. 启动3台zk主机
zkServer.sh start
2. 查看状态
zkServer.sh status
3. 关闭zkServer

HAHadoop配置(HDFS)

# 0. data文件夹
1. 如果新安装的Hadoop需要创建data文件夹
2. 如果是已经安装过的,之前旧的,需要删除data文件夹下的文件
# 1. 配置hadoop-env.sh 
export JAVA_HOME=/opt/installs/jdk1.8/
# 2. 配置core-site.xml
<configuration>
    <!--hdfs入口,设置虚拟地址,具体地址后面配置-->
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://ns</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>hadoop10:2181,hadoop11:2181,hadoop12:2181</value>
    </property>
</configuration>
# 3. 配置hdfs-site.xml
<configuration>
    <!-- 副本数 -->
    <property>
        <name>dfs.replication</name>
        <value>3</value>
    </property>
    <!-- 定义hdfs入口的命名服务 -->
    <property>
        <name>dfs.nameservices</name>
        <value>ns</value>
    </property>
    <!-- 定义hdfs入口的命名服务下虚拟ip-->
    <property>
        <name>dfs.ha.namenodes.ns</name>
        <value>nn1,nn2</value>
    </property>
    <!-- 虚拟ip地址1 RPC入口 -->
    <property>
        <name>dfs.namenode.rpc-address.ns.nn1</name>
        <value>hadoop10:9000</value>
    </property>
    <!-- 虚拟ip地址1 HTTP入口 -->
    <property>
        <name>dfs.namenode.http-address.ns.nn1</name>
        <value>hadoop10:50070</value>
    </property>
    <!-- 虚拟ip地址2 PRC入口 -->
    <property>
        <name>dfs.namenode.rpc-address.ns.nn2</name>
        <value>hadoop11:9000</value>
    </property>
    <!-- 虚拟ip地址1 HTTP入口 -->
    <property>
        <name>dfs.namenode.http-address.ns.nn2</name>
        <value>hadoop11:50070</value>
    </property>
    <!-- namenode要向zk的QJN写入editslog,所以要明确入口地址 -->
    <property>
        <name>dfs.namenode.shared.edits.dir</name>
        <value>qjournal://hadoop10:8485;hadoop11:8485;hadoop12:8485/ns</value>
    </property>
    <!-- 是否开启故障切换 -->
    <property>
        <name>dfs.ha.automatic-failover.enabled</name>
        <value>true</value>
    </property>
    <!-- 基于zookeeper的故障切换的代码类 -->
    <property>
        <name>dfs.client.failover.proxy.provider.ns</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@hadoop10 etc]# scp -r hadoop/ root@hadoop11:/opt/installs/hadoop2.9.2/etc/
[root@hadoop10 etc]# scp -r hadoop/ root@hadoop12:/opt/installs/hadoop2.9.2/etc/
[root@hadoop10 etc]# scp -r hadoop/ root@hadoop13:/opt/installs/hadoop2.9.2/etc/

HAHadoop启动

启动顺序:先启动zkServer,再启动hdfs。

# 1. 启动zookeeper(3台)
[root@hadoop10 etc]# zkServer.sh start
[root@hadoop11 etc]# zkServer.sh start
[root@hadoop12 etc]# zkServer.sh start
# 2. 初始化ZKFS故障切换进程(在NameNode主节点)【第一次启动需要做】
[root@hadoop10 etc]# hdfs zkfc -formatZK
# 3. 启动JournalNode进程(3台)
	启动后可以查看JournalNode节点进程
[root@hadoop10 etc]# hadoop-daemon.sh start journalnode
[root@hadoop11 etc]# hadoop-daemon.sh start journalnode
[root@hadoop12 etc]# hadoop-daemon.sh start journalnode
# 4. 格式化hdfs主机NameNode(在NameNode主节点)【第一次启动需要做】
hdfs namenode -format ns
# 5. 启动hdfs集群(NameNode主节点)
# 因为配置了HA-HDFS的zkfc,所以会自动启动zkfc故障切换进程
start-dfs.sh
# 6. 格式化hdfs的NameNode备机(NameNode standby备节点)【第一次启动需要做】
[root@hadoop11 ~]# hdfs namenode -bootstrapStandby
# 7. 启动hdfs的NameNode备机(NameNode standby备节点)
[root@hadoop11 ~]# hadoop-daemon.sh start namenode

进程图

在这里插入图片描述

验证

# 1. 查看两个NameNode状态
	一个处于active状态,另一个处于standby状态
# 2. kill掉active
	active失效,standby转为active
# 3. 重启NameNode,发现启动后变成standby
	hadoop-daemon.sh start namenode
# 4. 测试NameNode主机添加文件数据后,杀死,查看另一个NameNode也有文件数据,即HA高可用实现

Java程序访问

public void testHAHadoop() throws IOException {
    
    
        Configuration configuration = new Configuration();
        configuration.addResource("/core-site.xml");
        configuration.addResource("/hdfs-site.xml");
        FileSystem fileSystem = FileSystem.get(configuration);
        FileStatus[] files = fileSystem.listStatus(new Path("/"));
        Arrays.stream(files).forEach(x-> System.out.println(x));
    }

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44191814/article/details/121273513