【干货】Apache Hadoop 2.8 完全分布式集群搭建超详细过程,实现NameNode HA、ResourceManager HA高可靠性

最近在自己的笔记本电脑上搭建了Apache Hadoop分布式集群,采用了最新的稳定版本2.8,并配置了NameNode、ResourceManager的HA高可用,方便日常对Hadoop的研究与测试工作。详细的搭建过程如下:

1、安装docker,创建docker容器,用于搭建hadoop节点

docker真是个好东西啊,当要在自己的笔记本上搭建分布式集群时,由于CPU、内存、磁盘有限,无法在VMware上虚拟出太多节点,这时使用docker创建几个容器,就能轻松搭建一个分布式集群了。

(1)先在VMware上安装centos6.9,作为宿主机,然后安装docker,具体过程见我另一篇博文:Centos6.9安装docker

(2)然后再docker hub中拉取centos镜像,用于创建分布式集群的节点,推荐在docker中安装centos6(docker中的centos7有坑,被坑过,呜呜),具体过程见我另一篇博文:docker中安装centos6

(3)centos镜像准备好后,就开始创建docker容器,用于搭建hadoop的节点

# 创建4个节点,用于搭建hadoop
docker run -it --name hadoopcentos1 centos:6 /bin/bash
docker run -it --name hadoopcentos2 centos:6 /bin/bash
docker run -it --name hadoopcentos3 centos:6 /bin/bash
docker run -it --name hadoopcentos4 centos:6 /bin/bash

# 启动容器
docker start hadoopcentos1
docker start hadoopcentos2
docker start hadoopcentos3
docker start hadoopcentos4```
注意:这时要把宿主机的防火墙关掉、selinux设为不可用

关掉防火墙

chkconfig iptables off
service iptables stop

设置 selinux 为不可用,在config文件中修改SELINUX配置项

vi /etc/selinux/config

SELINUX=disabled


2、规划hadoop集群

本次共创建了4个hadoop节点,并实现NameNode HA、ResourceManager HA,节点规划如下

hadoop集群节点规划

Docker 容器 ip地址 主机名 节点进程
hadoopcentos1 172.17.0.1 hd1 NameNode(active)、JournalNode、Zookeeper、ZKFC
hadoopcentos2 172.17.0.2 hd2 NameNode(standby)、JournalNode、Zookeeper、ZKFC、NodeManager、DataNode
hadoopcentos3 172.17.0.3 hd3 ResourceManager(active)、JournalNode、Zookeeper、NodeManager、DataNode
hadoopcentos4 172.17.0.4 hd4 ResourceManager(standby)、NodeManager、DataNode
NameNode HA部署在hd1、hd2,ResourceManager HA部署在hd3、hd

4,其它进程见上表

 

3、配置Docker容器基本环境

由于在Docker中拉取的centos 6镜像是精简版本,很多指令没有,因此,先安装一些软件,配置基本环境

进入Docker容器,例如hadoopcentos1

docker exec -it hadoopcentos1 bin/bash
更换yum国内源(每个节点)

curl http://mirrors.aliyun.com/repo/Centos-6.repo > /etc/yum.repos.d/CentOS-Base-6-aliyun.repo
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak
yum clean all
yum makecache`
安装相关的软件(每个节点)

yum install -y net-tools which openssh-clients openssh-server iproute.x86_64```
编辑sshd_config文件,将其中的UsePAM改成no

vi /etc/ssh/sshd_config`
启动ssh(每个节点)

chkconfig sshd on
service sshd start```
创建用于安装apache hadoop的组、账号

groupadd ahadoop
useradd -m -g ahadoop ahadoop`
配置主机名映射表

vi /etc/hosts
172.17.0.1    hd1.hdsite    hd1
172.17.0.2  hd2.hdsite  hd2
172.17.0.3  hd3.hdsite  hd3
172.17.0.4  hd4.hdsite  hd4
172.17.0.1    31d48048cb1e
172.17.0.2    1620d6ed305d
172.17.0.3    ed3702f8924e
172.17.0.4    ee8319514df6```
其中,最后4行的随机字符串,就是docker容器自动生成的主机名了,每生成一个docker容器就会自动生成一个主机名

 

4、安装 JDK

从oracle的官网上面下载 JDK 1.8 Linux x64

创建java目录,并解压安装(使用root用户,方便以后别的程序也可以用)

mkdir /usr/java
cd /usr/java
tar -zxvf jdk-8u131-linux-x64.tar.gz


5、下载 apache hadoop

从apache hadoop的官网上面下载最新的稳定版本 apache hadoop 2.8

切换到 ahadoop 用户,将hadoop 2.8放于 /home/ahadoop 目录中,并解压

su ahadoop
cd /home/ahadoop
tar -zxvf hadoop-2.8.0.tar.gz


6、配置zookeeper

要实现hadoop namenode HA高可用,且实现故障的自动切换,则要借助于zookeeper

注意:如果只是实现namenode HA高可用,是可以不用zookeeper的,只要配置hadoop的journalnode节点即可实现高可用。而配置zookeeper集群,主要是为了监控心跳,实现故障时自动切换,这才是我们配置HA高可用的重要目标。

(1)下载zookeeper

到apache zookeeper官方下载最新版本的 zookeeper-3.4.10.tar.gz

(2)配置zookeeper

配置之前,建议阅读下apache zookeeper官方的配置安装介绍

zookeeper集群只能配置奇数个节点,例如3、5、7……,至少要3个及以上,这跟zookeeper的保障机制有关,要确保大多数节点可用,即(n-1)/2,因此节点数必须是奇数

解压zookeeper(hd1,hd2,hd3)

cd /home/ahadoop
tar -zxvf zookeeper-3.4.10.tar.gz `
创建zookeeper数据文件(hd1,hd2,hd3),其中不同的节点使用myid进行区分,一般使用1、2、3……

mkdir /home/ahadoop/zookeeper-data
echo '1' > /home/ahadoop/zookeeper-data/myid
echo '2' > /home/ahadoop/zookeeper-data/myid
echo '3' > /home/ahadoop/zookeeper-data/myid```
配置zoo.cfg配置文件

vi /home/ahadoop/zookeeper-3.4.10/conf/zoo.cfg
dataDir=/home/ahadoop/zookeeper-data # 修改zookeeper数据目录
clientPort=2181 # 默认端口
server.1=hd1:2888:3888
server.2=hd2:2888:3888
server.3=hd3:2888:3888`
其中 server.1、server.2、server.3 里面的 server.x 最后的序号则是不同节点的myid文件里面的id

到此,zookeeper已经配置完毕,使用 zkServer.sh start 命令在每个节点启动zookeeper(hd1,hd2,hd3)

使用 zkServer.sh status 即可查看节点的状态,最后的Mode表示该节点在集群中的角色,一个zookeeper集群只有一个leader,其它都是follower

[ahadoop@31d48048cb1e ~]$ zkServer.sh start &
[1] 6855
[ahadoop@31d48048cb1e ~]$ ZooKeeper JMX enabled by default
Using config: /home/ahadoop/zookeeper-3.4.10/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

[1]+  Done                    zkServer.sh start
[ahadoop@1620d6ed305d ~]$
[ahadoop@1620d6ed305d ~]$
[ahadoop@1620d6ed305d ~]$ zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /home/ahadoop/zookeeper-3.4.10/bin/../conf/zoo.cfg
Mode: leader

7、配置hadoop的配置文件

配置hadoop集群前,建议先阅读下apache hadoop官网的集群配置说明,虽然是英文文档,但是简单易懂,有助于进一步了解hadoop集群知识,官方的配置介绍如下(p.s. 参照官网里面的配置说明进行配置,发现有小部分错误,直到实际配置时才发现,下面会介绍):

apache hadoop 单节点配置官方介绍

apache hadoop 集群配置官方介绍

apache hadoop namenode HA(基于QJM)配置官方介绍

apache hadoop resourcemanager HA 配置官方介绍

(1)创建相应的文件夹(每个节点)

mkdir /home/ahadoop/hadoop-data
mkdir /home/ahadoop/hadoop-data/name
mkdir /home/ahadoop/hadoop-data/data
mkdir /home/ahadoop/hadoop-data/checkpoint
mkdir /home/ahadoop/hadoop-data/tmp
mkdir /home/ahadoop/hadoop-data/log
mkdir /home/ahadoop/hadoop-data/journalnode```
主文件夹为hadoop-data,其中:

name:存放namenode的数据

data:存放datanode的数据

checkpoint:存在namenode的checkpoint数据

tmp:临时文件

log:存放日志

journalnode:存在jounalnode的数据

(2)配置core-site.xml配置文件

官方提供了默认的 core-default.xml 配置文件可供参考,但内容很多,我们可根据需要进行配置


<name>fs.defaultFS</name>
<value>hdfs://hdcluster</value>


<name>dfs.journalnode.edits.dir</name>
<value>/home/ahadoop/hadoop-data/journalnode</value>


<name>hadoop.tmp.dir</name>
<value>/home/ahadoop/hadoop-data/tmp</value>


<name>fs.trash.interval</name>
<value>1440</value>


<name>io.file.buffer.size</name>
<value>65536</value>


<name>ha.zookeeper.quorum</name>
<value>hd1:2181,hd2:2181,hd3:2181</value>


`
其中,

fs.defaultFS:表示集群namenode的地址,对于namenode HA来说,需要取一个cluster id来作区分,以便于区分跟hadoop联邦的其它namenode,这里取hdcluster作为该集群的ID

dfs.journalnode.edits.dir、hadoop.tmp.dir:表示journalnode的数据文件路径、临时文件路径

fs.trash.interval:表示回收站的保留时间(分钟),也即hdfs的文件删除后,在回收站里面保留的时长

io.file.buffer.size:表示读取文件的字节数(byte)

ha.zookeeper.quorum:表示zookeeper集群的主机与端口

(3)配置hdfs-site.xml配置文件

官方提供了默认的 hdfs-default.xml 配置文件 可供参考,根据需要进行配置如下

<configuration>
  <property>
    <name>dfs.replication</name>
    <value>3</value>
  </property>
  <property>
    <name>dfs.namenode.name.dir</name>
    <value>/home/ahadoop/hadoop-data/name</value>
  </property>
  <property>
    <name>dfs.blocksize</name>
    <value>67108864</value>
  </property>
  <property>
    <name>dfs.datanode.data.dir</name>
    <value>/home/ahadoop/hadoop-data/data</value>
  </property>
  <property>
    <name>dfs.namenode.checkpoint.dir</name>
    <value>/home/ahadoop/hadoop-data/checkpoint</value>
  </property>
  <property>
    <name>dfs.namenode.handler.count</name>
    <value>10</value>
  </property>
  <property>
    <name>dfs.datanode.handler.count</name>
    <value>10</value>
  </property>
  <property>
    <name>dfs.nameservices</name>
    <value>hdcluster</value>
  </property>
  <property>
    <name>dfs.ha.namenodes.hdcluster</name>
    <value>nn1,nn2</value>
  </property>
  <property>
    <name>dfs.namenode.rpc-address.hdcluster.nn1</name>
    <value>hd1:9000</value>
  </property>
  <property>
    <name>dfs.namenode.rpc-address.hdcluster.nn2</name>
    <value>hd2:9000</value>
  </property>
  <property>
    <name>dfs.namenode.http-address.hdcluster.nn1</name>
    <value>hd1:50070</value>
  </property>
  <property>
    <name>dfs.namenode.http-address.hdcluster.nn2</name>
    <value>hd2:50070</value>
  </property>
  <property>
    <name>dfs.namenode.shared.edits.dir</name>
    <value>qjournal://hd1:8485;hd2:8485;hd3:8485/hdcluster</value>
  </property>
  <property>
    <name>dfs.client.failover.proxy.provider.hdcluster</name>
    <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
  </property>
  <property>
    <name>dfs.ha.automatic-failover.enabled.hdcluster</name>
    <value>true</value>
  </property>
  <property>
    <name>dfs.ha.fencing.methods</name>
    <value>shell(/bin/true)</value>
  </property>
</configuration>```
其中:

dfs.replication:表示hdfs的数据块备份数量,默认是3

dfs.namenode.name.dir,dfs.datanode.data.dir,dfs.namenode.checkpoint.dir:表示namenode、datanode、checkpoint的数据路径

dfs.blocksize:表示数据块的大小,默认为64M,可根据需要改为128M,甚至256M

dfs.namenode.handler.count、dfs.datanode.handler.count:表示在namenode、datanode的进程数

dfs.nameservices:表示集群namenode的ID,这里命名为hdcluster,注意要跟 core-size.xml 里面的配置项 fs.defaultFS 中的集群ID一致

dfs.ha.namenodes.hdcluster:表示namenode的id,这里有两个namenode节点,因此使用nn1,nn2命名

dfs.namenode.rpc-address.hdcluster.nn1,dfs.namenode.rpc-address.hdcluster.nn2:表示nn1、nn2的远程调用主机和端口

dfs.namenode.http-address.hdcluster.nn1,dfs.namenode.http-address.hdcluster.nn2:表示 nn1、nn2的所在节点http服务和端口

dfs.namenode.shared.edits.dir:表示namenode共享的元数据路径,在配置HA时,使用journalnode来保存元数据,维持namenode元数据的一致性

dfs.client.failover.proxy.provider.hdcluster:表示HDFS客户端连接到Active NameNode的一个java类(默认)

dfs.ha.automatic-failover.enabled.hdcluster:表示当namenode ha的active namenode出现故障时,是否自动切换(当然要设置为true了,^^)

dfs.ha.fencing.methods:表示故障时自动切换使用的方法

【敲黑板,注意了同学们,以下是重点】官方给的例子配置值是sshfence,但经试验,使用这种方式根本就不会自动切换,而是namenode active故障时,namenode standby仍旧是standby,只有我们登陆到namenode active故障节点,再将故障的namenode重新恢复启动后,原先的namenode standby才会自动切换为namenode active,(心中突然万马奔腾啊……),这根本不是我们配置高可用的目的啊

经研究,fencing的方法目前有两种:sshfence和shell。其中:

sshfence方法:是指通过ssh登陆到active namenode节点杀掉namenode进程,所以还需要设置ssh无密码登陆,还要保证有杀掉namenode进程的权限
shell方法:是指运行一个shell脚本/命令来防止两个namenode同时处于active,脚本需要自己写。但其实QJM模式本身就有fencing功能,能保证只有一个namenode能往journalnode上写edits文件,所以是不需要设置fencing的方法就能实现的。但是,在发生failover的时候,原来的active namenode可能还在接受客户端的读请求,这样客户端很可能读到一些过时的数据(因为新的active namenode的数据已经实时更新了)。因此,还是建议设置fencing方法。如果确实不想设置fencing方法,可以设置一个能返回成功(没有fencing作用)的方法,如“shell(/bin/true)”。这个纯粹为了fencing方法能够成功返回,并不需要真的有fencing作用。这样可以提高系统的可用性,即使在fencing机制失败的时候还能保持系统的可用性。
(4)配置mapred-site.xml

官方提供了默认的 mapred-default.xml 配置文件 可供参考,我们的配置如下


<name>mapreduce.framework.name</name>
<value>yarn</value>


`
该配置表示使用yarn框架

(5)配置yarn-site.xml

官方提供了默认的 yarn-default.xml 配置文件 可供参考,再结合 ResourceManager HA 的官方介绍,配置如下

<configuration>
  <property>
    <name>yarn.nodemanager.aux-services</name>
    <value>mapreduce_shuffle</value>
  </property>
  <property>
    <name>yarn.resourcemanager.ha.enabled</name>
    <value>true</value>
  </property>
  <property>
    <name>yarn.resourcemanager.cluster-id</name>
    <value>hdcluster</value>
  </property>
  <property>
    <name>yarn.resourcemanager.ha.rm-ids</name>
    <value>rm1,rm2</value>
  </property>
  <property>
    <name>yarn.resourcemanager.hostname.rm1</name>
    <value>hd3</value>
  </property>
  <property>
    <name>yarn.resourcemanager.hostname.rm2</name>
    <value>hd4</value>
  </property>
  <property>
    <name>yarn.resourcemanager.webapp.address.rm1</name>
    <value>hd3:8088</value>
  </property>
  <property>
    <name>yarn.resourcemanager.webapp.address.rm2</name>
    <value>hd4:8088</value>
  </property>
  <property>
    <name>yarn.resourcemanager.zk-address</name>
    <value>hd1:2181,hd2:2181,hd3:2181</value>
  </property>
</configuration>```
其中,

yarn.nodemanager.aux-services:NodeManager上运行的附属服务,需配置成mapreduce_shuffle,才可运行MapReduce程序,否则会报错

yarn.resourcemanager.ha.enabled:表示启动resourcemanager HA高可用

yarn.resourcemanager.cluster-id:表示resourcemanager的集群ID,不要与别的集群混淆即可,这里命名为hdcluster

yarn.resourcemanager.ha.rm-ids:表示resourcemanager的节点id,这里有两个节点,使用rm1,rm2作为ID

yarn.resourcemanager.hostname.rm1,yarn.resourcemanager.hostname.rm2:表示rm1,rm2的主机,这里取hd3、hd4

yarn.resourcemanager.webapp.address.rm1,yarn.resourcemanager.webapp.address.rm2:表示rm1,rm2的网页访问地址和端口,也即通过该地址和端口可访问作业情况

yarn.resourcemanager.zk-address:表示使用zookeeper来协助管理resourcemanager主备的zookeeper集群主机与端口

(6)配置slave节点主机

配置hadoop分布式集群的slaves节点主机列表,也即datanode运行的节点,这里取hd2、hd3、hd4

vi /home/ahadoop/hadoop-2.8.0/etc/hadoop/slaves

配置slave主机

hd2
hd3
hd4`
(7)配置log4j日志 log4j.properties

根据需要修改log4j的日志保存路径,以及日志输出的粒度

vi /home/ahadoop/hadoop-2.8.0/etc/hadoop/log4j.properties

# 修改日志的路径
hadoop.log.dir=/home/ahadoop/hadoop-data/log```
(8)配置bash的环境变量

编辑.bash_profile文件,配置环境变量,方便日常执行命令

vi /home/ahadoop/.bash_profile

在 .bash_profile 末尾增加以下配置

export JAVA_HOME=/usr/java/jdk1.8.0_131
export CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin

export HADOOP_HOME=/home/ahadoop/hadoop-2.8.0
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin

export ZOOKEEPER_HOME=/home/ahadoop/zookeeper-3.4.10
export PATH=$PATH:$ZOOKEEPER_HOME/bin`
配置后,使用source命令使其生效

source /home/ahadoop/.bash_profile

8、格式hadoop namenode,并启动hadoop分布式集群

通过以上的配置文件,已完成了hadoop集群的配置。在首次运行hadoop集群时,须先进行namenode的格式化,然后再启动整个集群。

注意:只有第一次运行,才需要格式化namenode哦,以后就不用了,否则一格式化将会清空整个集群的元数据和数据块

hadoop的sbin目录里面提供了便捷的启动脚本

最简单的有start-all.sh、stop-all.sh脚本,可直接启动/终止整个hadoop集群,使用这两个命令,必须实现集群节点ssh免密码登录,如在hd1主机执行这些命令,则须实现hd1免密码登录到hd2、hd3、hd4。在生产环境中,不推荐使用start-all.sh、stop-all.sh来维护整个集群,可能启动/终止过程会出现什么问题,影响到整个集群。在个人测试环节,则请便,怎么6、怎么来。
另外,还提供了start-dfs.sh、stop-dfs.sh来启动/终止hdfs,start-yarn.sh、stop-yarn.sh来启动/终止yarn,同样需要实现集群节点的ssh免密码登录,在生产环境,也不推荐使用这种方式。在个人测试环节,则请便,怎么6、怎么来。
第三,还提供了hadoop-daemon.sh,yarn-daemon.sh来启动/终止hdfs、yarn,使用方法如下,当执行hadoop-daemon.sh start namenode,则是启动namenode(secondaryname、datanode、journalnode等类似),使用stop则是终止;当执行yarn-daemon.sh start resourcemanager,则是启动resourcemanager(nodemanager类似),使用stop则是终止。使用这种启动方式,需要各个节点,逐一启动相应的进程,无须实现ssh免密码登录。这种方式的好处在于,某个节点的进程启动/终止,如果有问题,不会影响到整个集群,但管理员必须对整个集群的节点功能分布非常清楚。
第四,hadoop新版本还提供了hdfs、yarn的进程启动/终止方式(位于hadoop的bin目录),使用方法如下,hdfs namenode,则是启动namenode(secondaryname、datanode、journalnode等类似),那如果要终止呢???kill吧,kill 相应的进程会自动调用终止程序;yarn resourcemanager,则是启动resourcemanager(nodemanager类似),如果要终止,同样kill就好。使用这种方式,对于初学者来说,可以更好的搞清楚整个集群节点的启动顺序。
在本测试中,便是使用hdfs、yarn来启动节点

首次使用hadoop分布式集群时,需要格式化namenode,并同步ha状态到zookeeper,启动的顺序如下:

# 首次格式化启动顺序

# 启动 zookeeper(hd1,hd2,hd3)
zkServer.sh start &

# 启动 journalnode(hd1,hd2,hd3)
hdfs journalnode &

# 格式化 namenode(hd1)
hdfs namenode -format

# 初始化 HA 状态到 zk(hd1)
hdfs zkfc -formatZK &

# 启动 namenode active(hd1)
hdfs namenode &

# 同步 namenode(hd2)
hdfs namenode -bootstrapStandby

# 启动 namenode standby(hd2)
hdfs namenode &

# 启动ZookeeperFailoverController(hd1,hd2)
hdfs zkfc &

# 启动 datanode(hd2,hd3,hd4)
hdfs datanode &

# 启动 resourcemanager(hd3,hd4)
yarn resourcemanager &

# 启动 nodemanager(hd2,hd3,hd4)
yarn nodemanager &```
启动后,使用jps在各个节点,查看进程的启动情况

hd1

[ahadoop@31d48048cb1e ~]$ jps
8976 NameNode
8803 JournalNode
9172 Jps
9092 DFSZKFailoverController
8750 QuorumPeerMain

hd2

[ahadoop@1620d6ed305d ~]$ jps
7428 QuorumPeerMain
7636 NameNode
8021 Jps
7719 DFSZKFailoverController
7784 DataNode
7884 NodeManager
7487 JournalNode

hd3

[ahadoop@ed3702f8924e ~]$ jps
4320 QuorumPeerMain
4451 DataNode
4900 Jps
4772 NodeManager
4373 JournalNode
4540 ResourceManager

hd4

[ahadoop@ee8319514df6 ~]$ jps
4578 NodeManager
4707 Jps
4489 DataNode
4508 ResourceManager`
至今,整个集群就成功启动了

如果以后使用时,就不用再格式化namenode了(否则数据会完蛋),那么正常情况下,集群启动的顺序为

# 日常使用的启动顺序

# 启动 zookeeper(hd1,hd2,hd3)
zkServer.sh start &

# 启动 journalnode(hd1,hd2,hd3)
hdfs journalnode &

# 启动 namenode active(hd1)
hdfs namenode &

# 启动 namenode standby(hd2)
hdfs namenode &

# 启动ZookeeperFailoverController(hd1,hd2)
hdfs zkfc &

# 启动 datanode(hd2,hd3,hd4)
hdfs datanode &

# 启动 resourcemanager(hd3,hd4)
yarn resourcemanager &

# 启动 nodemanager(hd2,hd3,hd4)
yarn nodemanager &

9、hadoop集群测试

集群启动后,在浏览器输入以下网址查看namenode、resourcemanager的状态

输入网址 172.17.0.1:50070 查看 namenode(active)节点信息

输入网址 172.17.0.2:50070 查看 namenode(standby)节点信息

输入网址172.17.0.3:8088 查看 resourcemanager 节点信息

使用官网的例子,测试集群的map-reduce

这个例子是使用了hadoop自带的map-reduce jar包,对etc/hadoop的xml配置文件里面的配置项进行数量统计(类似于经典的wordcount测试)

具体步骤如下:

# 创建 hdfs 目录
hdfs dfs -mkdir /user
hdfs dfs -mkdir /user/ahadoop
hdfs dfs -mkdir input

# 上传 etc/hadoop 的 xml 配置文件
hdfs dfs -put /home/ahadoop/hadoop-2.8.0/etc/hadoop/*.xml input

# 执行自带的 map reduce jar程序
hadoop jar /home/ahadoop/hadoop-2.8.0/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.8.0.jar grep input output 'dfs[a-z.]+'

# 获取执行结果
hdfs dfs -get output output

# 查看执行结果
cat output/*```
执行后,结果如下





从上图可看出,使用map reduce统计了配置项的数量结果

 

10、hadoop 集群的 HA 测试

hadoop 集群的 HA 高可用性是本次搭建集群的重要目标,下面将对 hadoop 集群的 namenode ha、resourcemanager ha 进行测试

(1)namenode ha 测试

目前 hd1 的 namenode 是 active 状态,hd2 的 namenode 是 standby 状态,简单粗暴地对 hd1 的 namenode 进行 kill 掉,也就是使 hd1 的 namenode 发生故障,这时再看 hd2 的 namenode ,会发现已自动切换为 active 状态



说明 namenode ha 故障自动切换成功

(2)resourcemanager ha 测试

hd3、hd4的resourcemanager ha,打开网页后并没有看到 active、standby 状态,这时如果 hd3 是 active状态,输入 http://172.17.0.3:8088 可看到resourcemanger页面。而输入 http://172.17.0.4:8088 时,则会自动切换回 htttp://172.17.0.3:8088 页面。

这里通过后台可查看两个resourcemanager的状态,命令如下

查看 resourcemanager 状态

[ahadoop@ed3702f8924e ~]$ yarn rmadmin -getServiceState rm1
active

[ahadoop@ed3702f8924e ~]$ yarn rmadmin -getServiceState rm2
standby`
在测试resourcemanager ha时,将active节点的resourcemanager进行kill掉,这时再查看rm2状态,会发现已经变量 active 状态

[ahadoop@ed3702f8924e ~]$ yarn rmadmin -getServiceState rm2
active
可通过以下指令进行 active、standby 状态切换(--forcemanual 表示强制)

# 切换 resourcemanager 主备

# 切换为 standby 状态
yarn rmadmin -transitionToStandby --forcemanual rm2

# 切换为 active 状态
yarn rmadmin -transitionToActive --forcemanual rm1```
注意,这里如果是active状态的强制切换为standby,是可以成功切换,也就是说两个节点都是standby状态。但如果已经有一个active状态的,这时再将另一个standby状态切换为active状态,则无法进行切换,系统提示已经有一个active状态的节点了。

[ahadoop@ee8319514df6 ~]$ yarn rmadmin -transitionToActive --forcemanual rm2
You have specified the --forcemanual flag. This flag is dangerous, as it can induce a split-brain scenario that WILL CORRUPT your HDFS namespace, possibly irrecoverably.

It is recommended not to use this flag, but instead to shut down the cluster and disable automatic failover if you prefer to manually manage your HA state.

You may abort safely by answering 'n' or hitting ^C now.

Are you sure you want to continue? (Y or N) Y
17/06/18 16:53:01 WARN ha.HAAdmin: Proceeding with manual HA state management even though
automatic failover is enabled for org.apache.hadoop.yarn.client.RMHAServiceTarget@3444d69d
17/06/18 16:53:02 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
transitionToActive: Node rm1 is already active
Usage: rmadmin [-transitionToActive [--forceactive] ]


11、hadoop分布式集群简单搭建

上面的配置是针对namenode ha、resourcemanager ha进行配置,会比较复杂,如果只是要简单地搭建一个hadoop分布式集群,暂时不用配置namenode ha、resourcemanager ha的,则配置会简单很多,以下给出hadoop分布式集群简单搭建的相关配置,如下

(1)core-site.xml


<name>fs.defaultFS</name>
<value>hdfs://hd1:9000</value>


<name>hadoop.tmp.dir</name>
<value>/home/ahadoop/hadoop-data/tmp</value>


<name>fs.trash.interval</name>
<value>1440</value>


<name>io.file.buffer.size</name>
<value>65536</value>


`
(2)hdfs-site.xml

<configuration>
  <property>
    <name>dfs.replication</name>
    <value>3</value>
  </property>
  <property>
    <name>dfs.namenode.name.dir</name>
    <value>/home/ahadoop/hadoop-data/name</value>
  </property>
  <property>
    <name>dfs.blocksize</name>
    <value>67108864</value>
  </property>
  <property>
    <name>dfs.datanode.data.dir</name>
    <value>/home/ahadoop/hadoop-data/data</value>
  </property>
  <property>
    <name>dfs.namenode.checkpoint.dir</name>
    <value>/home/ahadoop/hadoop-data/checkpoint</value>
  </property>
  <property>
    <name>dfs.namenode.handler.count</name>
    <value>10</value>
  </property>
  <property>
    <name>dfs.datanode.handler.count</name>
    <value>10</value>
  </property>
</configuration>```
(3)mapred-site.xml


<name>mapreduce.framework.name</name>
<value>yarn</value>


`
(4)yarn-site.xml

<configuration>
  <property>
    <name>yarn.resourcemanager.hostname</name>
    <value>hd3</value>
  </property>
  <property>
    <name>yarn.nodemanager.aux-services</name>
    <value>mapreduce_shuffle</value>
  </property>
</configuration>```
(5)slaves

hd2
hd3
hd4`
(6).bash_profile

# 设置环境变量
vi /home/ahadoop/.bash_profile
export JAVA_HOME=/usr/java/jdk1.8.0_131
export CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin

export HADOOP_HOME=/home/ahadoop/hadoop-2.8.0
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin```
(7)格式化namenode,启动hadoop集群

格式化 namenode(hd1)

hdfs namenode -format

启动 namenode(hd1)

hdfs namenode &

启动 secondarynamenode(hd2)

hdfs secondarynamenode &

启动 datanode(hd2、hd3、hd4)

hdfs datanode &

启动 resourcemanager(hd2)

yarn resoucemanager &

启动 nodemanager(hd2、hd3、hd4)

hdfs nodemanager &`
(8)访问namenode、resourcemanager页面

访问 namenode 页面
http://172.17.0.1:50070

访问 resourcemanager 页面
http://172.17.0.2:8088

12、apache hadoop官方配置文档的一些问题

(1)官网给的namenode ha配置说明文档,里面关于自动切换故障的配置,官网给的配置是(hdfs-site.xml)

 <property>
   <name>dfs.ha.automatic-failover.enabled</name>
   <value>true</value>
 </property>```
而实际在配置时,后面还要加上集群ID,本测试的集群ID是hdcluster,因此正常的配置是


dfs.ha.automatic-failover.enabled.hdcluster
true
`
(2)关于启动命令的问题

官网给的hadoop集群配置的说明文档,里面关于节点进程的启动命令为:

[hdfs]$ $HADOOP_HOME/bin/hdfs --daemon start namenode

[hdfs]$ $HADOOP_HOME/bin/hdfs --daemon start datanode

[yarn]$ $HADOOP_HOME/bin/yarn --daemon start resourcemanager

[yarn]$ $HADOOP_HOME/bin/yarn --daemon start nodemanager

但实际无法执行(也有可能是3.0 beta版的指令,没试过),执行会提示

[ahadoop@31d48048cb1e ~]$ hdfs --daemon start namenode
Unrecognized option: --daemon
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.```
不支持 --daemon 这个参数,因此,实际在启动这些节点进程时,启动命令为

[hdfs]$ $HADOOP_HOME/bin/hdfs namenode

[hdfs]$ $HADOOP_HOME/bin/hdfs datanode

[yarn]$ $HADOOP_HOME/bin/yarn resourcemanager

[yarn]$ $HADOOP_HOME/bin/yarn nodemanager

上一篇:3、带你一步一步学习ASP.NET Core中的配置之Configuration


下一篇:$.ajax 调用 Asp.Net Core Razor Page 后台代码