- 1、目的
本文主要是HDFS高可用性(HA)功能以及如何使用Quorum Journal Manager(QJM)功能配置和管理HA HDFS群集。
- 2、背景
在Hadoop 2.0.0之前,NameNode是HDFS集群中的单点故障(SPOF)。每个群集都有一个NameNode,如果该机器或 进程变得不可用,整个群集将无法使用,直到NameNode重新启动或在单独的计算机上启动。
这在两个主要方面影响了HDFS集群的总体可用性:
对于计划外事件(例如计算机崩溃),在操作员重新启动NameNode之前,群集将不可用。
计划维护事件(如NameNode计算机上的软件或硬件升级)将导致群集停机时间窗口。
HDFS高可用性功能通过提供在具有热备用的主动/被动配置中的同一群集中运行两个冗余NameNode的选项来解决上述问 题。这样,在机器崩溃的情况下,可以快速故障转移到新的NameNode,或者为了计划维护,可以进行正常的管理员启动 的故障转移。
- 3、架构
故障自动切换:zookeeper集群 ZKFC
namenode数据最终一致性:JN集群(journal node)
- 4、虚拟机角色分配
使用4个虚拟机节点以及角色:
hadoop01(192.168.92.66)
hadoop02(192.168.92.67)
hadoop03(192.168.92.68)
hadoop04(192.168.92.69)
- 5、安装文件
jdk-7u67-linux-x64.rpm
hadoop-2.6.5.tar.gz
zookeeper-3.4.6.tar.gz
- 6、操作系统环境准备
6.1、依赖软件
yum install -y ssh rsync
6.2、ssh免密
现在检查您是否可以在没有密码的情况下ssh到localhost:
$ ssh localhost
如果在没有密码短语的情况下无法ssh到localhost,请执行以下命令:
[root@hadoop01 .ssh]# ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa
[root@hadoop01 .ssh]# cat id_dsa.pub >> ~/.ssh/authorized_keys
将hadoop01中的公钥分发到其他节点并将公钥添加到authorized_keys中,下面以hadoop02为例,其他操作一样
[root@hadoop01 .ssh]# scp id_dsa.pub root@hadoop02:`pwd`/hadoop01.pub
登录hadoop02
[root@hadoop02 opt]# cd ~/.ssh
[root@hadoop02 .ssh]# cat hadoop01.pub >> ~/.ssh/authorized_keys
hadoop03和hadoop04做同样操作
注意:需要配置 hadoop01(namenode) 需要免密登录自己和其他所有的datanode节点
此外 hadoop01和hadoop02要互相免密,还需要将公钥添加到自己和hadoop01
因此hadoop02需要额外做如下操作
[root@hadoop02 .ssh]# ssh-keygen -t dsa -P '' -f /root/.ssh/id_dsa
[root@hadoop02 .ssh]# cat id_dsa.pub >> authorized_keys
[root@hadoop02 .ssh]# scp id_dsa.pub root@hadoop01:`pwd`/hadoop02.pub
登录hadoop01将hadoop02.pub添加到 authorized_keys中
[root@hadoop01 .ssh]# cat hadoop02.pub >> authorized_keys
6.3、 jdk安装并配置环境变量
使用rz命令将jdk安装包上传到每个节点 /opt目录下
cd /opt
安装jdk
[root@hadoop01 opt]# rpm -ivh jdk-7u67-linux-x64.rpm
配置环境变量
vi /etc/profile
追加两行
export JAVA_HOME=/usr/java/jdk1.7.0_67
export PATH=$PATH:$JAVA_HOME/bin
重新引入一下配置文件 source /etc/profile
注意 hadoop01 hadoop02 hadoop03 hadoop04都是同样的
6.4、 时间同步
[root@hadoop01 opt]# date
Mon Oct 29 19:27:14 CST 2018
验证每台虚拟机中的时间是否同步,如果不同步话需要执行下面操作将时间统一
https://blog.csdn.net/chuanxincui/article/details/83543669
6.5、 虚拟机主机名以及hosts文件配置(以hadoop01为例 其他节点操作相同)
修改主机名
[root@hadoop01 opt]# vi /etc/sysconfig/network
修改/etc/hosts文件如下
三、
- 7、hadoop安装配置环境变量
7.1、 安装hadoop
使用rz命令上传安装包到/opt目录
cd /opt
解压hadoop安装包
[root@hadoop01 opt]# tar -zxvf hadoop-2.6.5.tar.gz
将解压后文件复制到安装目录
[root@hadoop01 opt]# cp -r hadoop-2.6.5 /usr/local
7.2、 配置环境变量
[root@hadoop01 hadoop-2.6.5]# vi /etc/profile
修改如下:
修改完毕后重新引入配置文件
source /etc/profile
- 8、zookeeper安装并配置环境变量
登陆haddop02节点
rz命令上传安装包到/opt目录下,
解压到当前目录,然后将解压后安装包复制到/usr/local/目录下
[root@hadoop02 opt]# tar -zxvf zookeeper-3.4.6.tar.gz
[root@hadoop02 opt]# cp -r zookeeper-3.4.6 /usr/local/
切换到zookeeper安装目录
[root@hadoop02 opt]# cd /usr/local/zookeeper-3.4.6/
修改配置文件:
[root@hadoop02 zookeeper-3.4.6]# cd conf/
[root@hadoop02 conf]# cp zoo_sample.cfg zoo.cfg
[root@hadoop02 conf]# vi zoo.cfg
创建zookeeper数据存放目录,并在该目录下面创建一个myid文件将zoo.cfg中的集群机器的id追加到该文件中(hadoop02 hadoop03和hadoop04做同样操作),下面以hadoop02为例
[root@hadoop02 conf]# mkdir /var/sxt/zookeeper
[root@hadoop02 conf]# cd /var/sxt/zookeeper/
[root@hadoop02 zookeeper]# echo 2 > myid
创建完数据存放目录后,将hadoop02中的zookeeper安装包分发到hadoop03和hadoop04(这样03和04就不用再配置一遍了)
[root@hadoop02 local]# cd /usr/local/
[root@hadoop02 local]# scp -r zookeeper-3.4.6 root@hadoop03:`pwd`
[root@hadoop02 local]# scp -r zookeeper-3.4.6 root@hadoop04:`pwd`
配置zookeeper环境变量(02 03 04都要配置)
[root@hadoop02 zookeeper-3.4.6]# vi /etc/profile
重新加载配置文件 [root@hadoop02 zookeeper-3.4.6]# source /etc/profile
启动zookeeper服务端,验证(启动顺序为 hadoop02 hadoop03 hadoop04,并验证选举机制)
[root@hadoop02 opt]# zkServer.sh start
[root@hadoop03 zookeeper]# zkServer.sh start
[root@hadoop04 zookeeper]# zkServer.sh start
通过查看3台机器zookeeper状态,验证选举机制
- 9、hdfs配置部署(以hadoop01为例,其他3台机器只要分发一下即可)
9.1、切换到hadoop01机器进行hdfs配置
9.2、配置hdfs-site.html
[root@hadoop01 hadoop]# vi hdfs-site.xml
<!-- 设置副本数 -->
<property>
<name>dfs.replication</name>
<value>2</value>
</property>
<!-- 设置服务逻辑名称 -->
<property>
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>
<!-- 设置nameservice中的节点标识 -->
<property>
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2</value>
</property>
<!-- 设置节点的物理地址 -->
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1</name>
<value>hadoop01:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>hadoop02:8020</value>
</property>
<!-- 设置客户端浏览器访问 -->
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>hadoop01:50070</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>hadoop02:50070</value>
</property>
<!-- 配置journal node -->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://hadoop01:8485;hadoop02:8485;hadoop03:8485/mycluster</value>
</property>
<!-- 配置journal node edit存放目录 -->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/var/sxt/hadoop/jn</value>
</property>
<!-- 免密配置类型 -->
<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>
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/root/.ssh/id_dsa</value>
</property>
<!-- 自动化主备切换 -->
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
9.3、core-site.html配置文件修改 新增
[root@hadoop01 hadoop]# vi core-site.xml
<property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/var/sxt/hadoop/ha</value>
</property>
<!-- 设置自动故障转移对应的:zk -->
<property>
<name>ha.zookeeper.quorum</name>
<value>hadoop02:2181,hadoop03:2181,hadoop04:2181</value>
</property>
9.4、修改datanode节点
[root@hadoop01 hadoop]# vi slaves
9.5、修改环境jdk环境变量
前面我们已经配置了环境变量,为什么此处还要修改呢?
主要原因是如果一台机器直接通过ssh命令免密登录另一台机器时,默认是不会加载配置文件的,因此也就无法获取到jdk 环境变量,因此需要配置 hadoop
[root@hadoop01 hadoop]# vi hadoop-env.sh
9.6、创建必要的目录
hadoop临时目录
[root@hadoop01 hadoop]# mkdir /var/sxt/hadoop/ha
journal node数据存放目录
[root@hadoop01 hadoop]# mkdir /var/sxt/hadoop/jn
9.7、安装包分发到其他3台机器(hadoop02 hadoop03 hadoop04)
[root@hadoop01 local]# scp -r hadoop-2.6.5 root@hadoop02:`pwd`
[root@hadoop01 local]# scp -r hadoop-2.6.5 root@hadoop03:`pwd`
[root@hadoop01 local]# scp -r hadoop-2.6.5 root@hadoop04:`pwd`
10、启动
10.1、启动journal node
注意必须要先启动JN才能格式化,为什么?
因为journal node 集群是为了处理两个nomenode节点之间数据最终一致性,而引入的。如果直接格式化namenode,仅仅只是格式化了fsimage,此时同步的话也只是同步了fsimage,对于增量edit中的内容并没有同步,因此必须要先格式化journal node,然后启动一台namenode机器(hadoop01),执行格式化,然后再将hadoop01中的数据同步到另一台namenode机器(hadoop02)
[root@hadoop01 local]# hadoop-daemon.sh start journalnode
[root@hadoop02 local]# hadoop-daemon.sh start journalnode
[root@hadoop03 local]# hadoop-daemon.sh start journalnode
10.2、格式化namenode(hadoop01)
[root@hadoop01 local]# hdfs namenode -format
启动hadoop01
[root@hadoop01 local]# hadoop-daemon.sh start namenode
10.3、切换到另一台namenode执行同步操作
[root@hadoop02 local]# hdfs namenode -bootstrapStandby
输出一下内容表示同步成功
10.4、格式化zookeeper
[root@hadoop01 current]# hdfs zkfc -formatZK
10.5、验证zookeeper格式化是否成功
登录任意一台(hadoop02 hadoop03 hadoop04)机器
执行命令
[root@hadoop04 local]# zkCli.sh
10.6、启动整个集群
以后再启动的话,只需要启动ZK和start-dfs.sh就可以了
- 11 验证