前言:
1)Vmware网络模式介绍。参考:http://blog.csdn.net/collection4u/article/details/14127671
2)Hadoop部署模式有:本地模式(Local(或Standalone)Mode)、伪分布模式、完全分布式模式、HA完全分布式模式。
区分的依据是NameNode、DataNode、ResourceManager、NodeManager等模块运行在几个JVM进程、几个机器。
本地模式是最简单的模式,所有模块都运行与一个JVM进程中,使用的本地文件系统,而不是HDFS,本地模式主要是用于本地开发过程中的运行调试用。下载hadoop安装包后不用任何设置,默认的就是本地模式。
摘抄(关于本地模式(Local Mode)或独立模式(Standalone Mode)):
默认的模式,无需运行任何守护进程(daemon),所有程序都在单个JVM上执行。由于在本机模式下测试和调试MapReduce程序较为方便,因此,这种模式适宜用在开发阶段。
使用本地文件系统,而不是分布式文件系统。Hadoop不会启动NameNode、DataNode、JobTracker、TaskTracker等守护进程,Map()和Reduce()任务作为同一个进程的不同部分来执行的。
用于对MapReduce程序的逻辑进行调试,确保程序的正确。
所谓默认模式,及安装完jdk及hadoop,配置好相应的环境,及本地模式配置完成。
默认的模式,无需运行任何守护进程(daemon),所有程序都在单个JVM上执行。由于在本机模式下测试和调试MapReduce程序较为方便,因此,这种模式适宜用在开发阶段。
使用本地文件系统,而不是分布式文件系统。
Hadoop不会启动NameNode、DataNode、JobTracker、TaskTracker等守护进程,Map()和Reduce()任务作为同一个进程的不同部分来执行的。
用于对MapReduce程序的逻辑进行调试,确保程序的正确。
所谓默认模式,及安装完jdk及hadoop,配置好相应的环境,及本地模式配置完成。
伪分布式模式是在一台机器的各个进程上运行Hadoop的各个模块,伪分布式的意思是虽然各个模块是在各个进程上分开运行的,但是只是运行在一个操作系统上的,并不是真正的分布式。
完全分布式模式才是生产环境采用的模式,Hadoop运行在服务器集群上,生产环境一般都会做HA,以实现高可用。
HA是指高可用,为了解决Hadoop单点故障问题,生产环境一般都做HA部署。
NAT 配置:
NAT是网络地址转换,是在宿主机和虚拟机之间增加一个地址转换服务,负责外部和虚拟机之间的通讯转接和IP转换。
我们部署Hadoop集群,这里选择NAT模式,各个虚拟机通过NAT使用宿主机的IP来访问外网。
当您将 Workstation Pro 安装到 Windows 或 Linux 主机系统时,系统会设置一个 NAT 模式网络 (VMnet8:不管有多少台虚拟机,只能设置一个NAT网络模式的网卡(主机系统,即宿主机系统中只存在一个这样的虚拟网卡[即虚拟网络交换机]),默认是VMnet8)。在您使用新建虚拟机向导创建典型虚拟机时,该向导会将虚拟机配置为使用默认 NAT 模式网络。
虚拟机和主机系统共享一个网络标识,此标识在外部网络中不可见。NAT 工作时会将虚拟机在专用网络中的 IP 地址转换为主机系统的 IP 地址。当虚拟机发送对网络资源的访问请求时,它会充当网络资源,就像请求来自主机系统一样。
主机系统在 NAT 网络上具有虚拟网络适配器。借助该适配器,主机系统可以与虚拟机相互通信。NAT 设备可在一个或多个虚拟机与外部网络之间传送网络数据,识别用于每个虚拟机的传入数据包,并将它们发送到正确的目的地。
使用 NAT 模式网络时,虚拟机在外部网络中不必具有自己的 IP 地址。主机系统上会建立单独的专用网络。在默认配置中,虚拟机会在此专用网络中通过 DHCP 服务器获取地址。我们的要求是集群中的各个虚拟机有固定的IP、可以访问外网,所以进行如下设置:
1)
2)为机器设置一个子网网段,默认是192.168.132网段,将来各个虚拟机Ip就为 192.168.132.*。
3)点击NAT设置按钮,打开对话框,可以修改网关地址和DNS地址。这里我们为NAT指定DNS地址。
。。。。。。这是一个过程,不再累赘。
1)配置IP、子网掩码、网关(和NAT设置的一样)、DNS等参数
[hadoop@bigdata-senior01 ~]$ systemctl restart network #重启network
2)永久修改Hostname
[hadoop@python5 ~]$ sudo vim /etc/sysconfig/network
3)配置Host,即添加主机映射
[hadoop@python5 etc]$ sudo vim /etc/hosts
4)关闭防火墙(切换到root用户下) 备注:在CentOS 7或RHEL 7或Fedora中防火墙由firewalld来管理
学习环境可以直接把防火墙关闭掉。
临时关闭:systemctl stop firewalld
永久关闭:systemctl disable firewalld #需要重启才能生效
查看状态:systemctl status firewalld
5)关闭selinux(切换到root用户下)
selinux是Linux一个子安全机制,学习环境可以将它禁用。
临时关闭:setenforce 0
永久关闭:vi /etc/selinux/config #需要重启才能生效
修改 SELINUX =disabled
getenforce:查看状态
1)查看是否安装了JDK
2)如果没有安装则最好安装Oracle的Java JDK
tar:压缩、解压缩
tar -xzf 文件名 -C 目录
[root@python5 ~]# tar -zxvf /home/hadoop/jdk-8u172-linux-x64.tar.gz -C /home/hadoop/opt
3)添加环境变量
设置JDK的环境变量 JAVA_HOME。需要修改配置文件/etc/profile 或 当前用户主目录下的.bashrc文件,追加
export JAVA_HOME=/home/hadoop/opt/jdk1.8.0_172
PATH=$PATH:$JAVA_HOME/bin
修改完毕后,执行 source /etc/porfile 或 source 当前用户名/.bashrc 来更新环境文件。
4)再次执行 java -version,可以看到已经成功安装。
1)解压缩
[root@python5 ~]# tar -zxvf /home/hadoop/hadoop-2.9.0.tar.gz -C /home/hadoop
2)添加环境变量(HADOOP_HOME 、HADOOP_CONF_DIR(备注:/home/hadoop/hadoop-2.9.0/etc/hadoop/hadoop-env.sh文件用到此变量)、PATH)
[root@python5 ~]# echo export HADOOP_HOME=/home/hadoop/hadoop-2.9.0 >> /home/hadoop/.bashrc #配置HADOOP_HOME
[root@python5 ~]# echo export HADOOP_CONF_DIR=/home/hadoop/hadoop-2.9.0/etc/hadoop >> /home/hadoop/.bashrc #配置HADOOP_CONF_DIR
[root@python5 ~]# echo export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin #追加PATH
3)[root@python5 ~]# source /home/hadoop/.bashrc #更新文件
4)[root@python5 ~]# hadoop #输入hadoop测试是否配置成功
1)配置core-site.xml
[hadoop@python5 hadoop]$ vim ${HADOOP_CONF_DIR}/core-site.xml
fs.defaultFS
hdfs://python5:9000
fs.defaultFS参数配置的是HDFS的地址
hadoop.tmp.dir
/home/hadoop/opt/tmp
hadoop.tmp.dir配置的是Hadoop临时目录,比如HDFS的NameNode数据默认都存放这个目录下,查看*-default.xml
等默认配置文件,就可以看到很多依赖${hadoop.tmp.dir}的配置。
默认的hadoop.tmp.dir是/tmp/hadoop-${user.name},此时有个问题就是NameNode会将HDFS的元数据存储在
这个/tmp目录下,如果操作系统重启了,系统会清空/tmp目录下的东西,导致NameNode元数据丢失,是个非常严重的问题,
所有我们应该修改这个路径。于是我们创建了目录:/home/hadoop/opt/tmp,并将目录的所有者修改为hadoop,
且把此目录作为Hadoop的临时目录。
dfs.namenode.name.dir
file://${hadoop.tmp.dir}/dfs/name
配置名字节点的目录
dfs.datanode.data.dir
file://${hadoop.tmp.dir}/dfs/data
配置数据节点的目录
2)配置hdfs-site.xml
[hadoop@python5 hadoop]$ vim ${HADOOP_CONF_DIR}/hdfs-site.xml
dfs.replication
1
dfs.replication配置的是HDFS存储时的备份数量,因为这里是伪分布式环境只有一个节点,所以这里设置为1。
dfs.namenode.http-address
python5:50070
配置namenode的Web访问地址和端口
3)格式化HDFS
[hadoop@python5 bin]$ ${HADOOP_HOME}/bin/hdfs --config ${HADOOP_HOME}/etc/hadoop namenode -format -cluserid pseudo
格式化是对HDFS这个分布式文件系统中的DataNode进行分块,统计所有分块后的初始元数据的存储在NameNode中。
格式化后,查看core-site.xml里hadoop.tmp.dir(本例是/home/hadoop/opt/tmp目录)指定的目录下是否有了dfs目录,如果有,说明格式化成功。
注意:
(1) 格式化时,这里注意hadoop.tmp.dir目录的权限问题,应该hadoop普通用户有读写权限才行,可以将/home/hadoop/opt/tmp的所有者改为hadoop。
[hadoop@python5 opt]$ sudo chown -R hadoop:hadoop /home/hadoop/opt/tmp
(2) 查看NameNode格式化后的目录。
[hadoop@python5 opt]$ ll /home/hadoop/opt/tmp/dfs/name/current/
fsimage是NameNode元数据在内存满了后,持久化保存到的文件。
fsimage*.md5
是校验文件,用于校验fsimage的完整性。
seen_txid
是hadoop的版本。
VERSION文件里保存:
namespaceID:NameNode的唯一ID。
clusterID:集群ID,NameNode和DataNode的集群ID应该一致,表明是一个集群。
4)启动NameNode
[hadoop@python5 opt]$ ${HADOOP_HOME}/sbin/hadoop-daemon.sh start namenode
starting namenode, logging to /home/hadoop/hadoop-2.9.0/logs/hadoop-hadoop-namenode-python5.out
最好:(注意:本文中类似的地方不再提示)
[hadoop@python5 opt]$ ${HADOOP_HOME}/sbin/hadoop-daemon.sh --config ${HADOOP_CONF_DIR} --script ${HADOOP_HOME}/bin/hdfs start namenode
5)启动DataNode
[hadoop@python5 opt]$ ${HADOOP_HOME}/sbin/hadoop-daemon.sh start datanode
starting datanode, logging to /home/hadoop/hadoop-2.9.0/logs/hadoop-hadoop-datanode-python5.out
6)启动SecondaryNameNode
[hadoop@python5 opt]$ ${HADOOP_HOME}/sbin/hadoop-daemon.sh start secondarynamenode
starting secondarynamenode, logging to /home/hadoop/hadoop-2.9.0/logs/hadoop-hadoop-secondarynamenode-python5.out
7)JPS命令查看是否已经启动成功
[hadoop@python5 opt]$ jps
8593 SecondaryNameNode
8372 NameNode
8484 DataNode
8653 Jps
8)HDFS上测试创建目录,上传和下载文件
[hadoop@python5 ~]$ hdfs dfs -mkdir -p /user/hadoop #创建目录
[hadoop@python5 ~]$ hdfs dfs -copyFromLocal /home/hadoop/wordcount.csv hdfs://192.168.132.110:9000/user/hadoop #上传文件
或者:
[hadoop@python5 ~]$ hdfs dfs -copyFromLocal /home/hadoop/wordcount.csv /user/hadoop #上传文件
或者:
[hadoop@python5 ~]$ hdfs dfs -put /hadoop/wordcount.csv hdfs://192.168.132.110:9000/user/hadoop #上传文件
[hadoop@python5 ~]$ hdfs dfs -copyToLocal hdfs://192.168.132.110:9000/user/hadoop/wordcount.csv /home/hadoop/wordcount #下载文件
或者:
[hadoop@python5 ~]$ hdfs dfs -copyToLocal /user/hadoop/wordcount.csv /home/hadoop/wordcount #下载文件
或者:
[hadoop@python5 ~]$ hdfs dfs -get hdfs://192.168.132.110:9000/user/hadoop/wordcount.csv /home/hadoop/wordcount #下载文件
9)配置,启动yarn
(1)配置mapred-site.xml
默认没有mapred-site.xml文件,但是有个mapred-site.xml.template配置模板文件。复制模板生成mapred-site.xml。
[hadoop@python5 ~]$ cp ${HADOOP_CONF_DIR}/mapred-site.xml.template ${HADOOP_CONF_DIR}/mapred-site.xml
添加配置如下:
mapreduce.framework.name
yarn
mapreduce.framework.name
yarn
指定mapreduce运行yarn框架上
(2) 配置yarn-site.xml
添加配置如下:
yarn.resourcemanager.hostname
python5
yarn.nodemanager.aux-services
mapreduce_shuffle
yarn.resourcemanager.hostname指定了Resourcemanager运行在哪个节点上。
yarn.nodemanager.aux-services配置了yarn的默认混洗方式,选择为mapreduce的默认混洗算法。
yarn.resourcemanager.hostname
python5
指定ResourceManager运行在哪个节点上
yarn.nodemanager.aux-services
mapreduce_shuffle
配置了yarn的默认混洗方式,选择为mapreduce的默认混洗算法。
10)启动resourcemanager和nodemanager
[hadoop@python5 bin]$ ${HADOOP_HOME}/sbin/yarn-daemon.sh start resourcemanager
starting resourcemanager, logging to /home/hadoop/hadoop-2.9.0/logs/yarn-hadoop-resourcemanager-python5.out
[hadoop@python5 bin]$ ${HADOOP_HOME}/sbin/yarn-daemon.sh start nodemanager
starting nodemanager, logging to /home/hadoop/hadoop-2.9.0/logs/yarn-hadoop-nodemanager-python5.out
查看是否启动成功:
[hadoop@python5 bin]$ jps
8593 SecondaryNameNode
8372 NameNode
8484 DataNode
9604 NodeManager #有了
9338 ResourceManager #有了
9758 Jps
yarn的web界面:
11)运行mapreduce job。备注:用Hadoop自带的wordcount例子在伪分布模式下运行mapreduce。
运行过程如下:
[hadoop@python5 hadoop]$ ${HADOOP_HOME}/bin/yarn jar ${HADOOP_HOME}/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.9.0.jar wordcount hdfs://192.168.132.110:9000/user/hadoop/wordcount.csv hdfs://192.168.132.110:9000/user/hadoop/output
18/11/04 11:27:02 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
- 18/11/04 11:27:07 INFO client.RMProxy: Connecting to ResourceManager at python5/192.168.132.110:8032
- 18/11/04 11:27:13 INFO input.FileInputFormat: Total input files to process : 1
- 18/11/04 11:27:14 INFO mapreduce.JobSubmitter: number of splits:1
- 18/11/04 11:27:14 INFO Configuration.deprecation: yarn.resourcemanager.system-metrics-publisher.enabled is deprecated. Instead, use yarn.system-metrics-publisher.enabled
- 18/11/04 11:27:15 INFO mapreduce.JobSubmitter: Submitting tokens for job: job_1541300559012_0001
- 18/11/04 11:27:17 INFO impl.YarnClientImpl: Submitted application application_1541300559012_0001
- 18/11/04 11:27:18 INFO mapreduce.Job: The url to track the job: http://python5:8088/proxy/application_1541300559012_0001/
- 18/11/04 11:27:18 INFO mapreduce.Job: Running job: job_1541300559012_0001
- 18/11/04 11:27:54 INFO mapreduce.Job: Job job_1541300559012_0001 running in uber mode : false
- 18/11/04 11:27:54 INFO mapreduce.Job: map 0% reduce 0%
- 18/11/04 11:28:27 INFO mapreduce.Job: map 100% reduce 0%
- 18/11/04 11:28:38 INFO mapreduce.Job: map 100% reduce 100%
- 18/11/04 11:28:40 INFO mapreduce.Job: Job job_1541300559012_0001 completed successfully
- 18/11/04 11:28:40 INFO mapreduce.Job: Counters: 49
File System Counters
FILE: Number of bytes read=1159
FILE: Number of bytes written=406165
FILE: Number of read operations=0
FILE: Number of large read operations=0
FILE: Number of write operations=0
HDFS: Number of bytes read=875
HDFS: Number of bytes written=805
HDFS: Number of read operations=6
HDFS: Number of large read operations=0
HDFS: Number of write operations=2
Job Counters
Launched map tasks=1
Launched reduce tasks=1
Data-local map tasks=1
Total time spent by all maps in occupied slots (ms)=28638
Total time spent by all reduces in occupied slots (ms)=9273
Total time spent by all map tasks (ms)=28638
Total time spent by all reduce tasks (ms)=9273
Total vcore-milliseconds taken by all map tasks=28638
Total vcore-milliseconds taken by all reduce tasks=9273
Total megabyte-milliseconds taken by all map tasks=29325312
Total megabyte-milliseconds taken by all reduce tasks=9495552
Map-Reduce Framework
Map input records=6
Map output records=113
Map output bytes=1209
Map output materialized bytes=1159
Input split bytes=118
Combine input records=113
Combine output records=87
Reduce input groups=87
Reduce shuffle bytes=1159
Reduce input records=87
Reduce output records=87
Spilled Records=174
Shuffled Maps =1
Failed Shuffles=0
Merged Map outputs=1
GC time elapsed (ms)=332
CPU time spent (ms)=2440
Physical memory (bytes) snapshot=401817600
Virtual memory (bytes) snapshot=4247883776
Total committed heap usage (bytes)=229638144
Shuffle Errors
BAD_ID=0
CONNECTION=0
IO_ERROR=0
WRONG_LENGTH=0
WRONG_MAP=0
WRONG_REDUCE=0
File Input Format Counters
Bytes Read=757
File Output Format Counters
Bytes Written=805
查看输出结果目录:
[hadoop@python5 hadoop]$ hdfs dfs -ls hdfs://192.168.132.110:9000/user/hadoop/output/
18/11/04 12:38:49 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Found 2 items
-rw-r--r-- 1 hadoop supergroup 0 2018-11-04 11:28 hdfs://192.168.132.110:9000/user/hadoop/output/_SUCCESS
-rw-r--r-- 1 hadoop supergroup 805 2018-11-04 11:28 hdfs://192.168.132.110:9000/user/hadoop/output/part-r-00000
- output目录中有两个文件,_SUCCESS文件是空文件,有这个文件说明Job执行成功。
- part-r-00000文件是结果文件,其中-r-说明这个文件是Reduce阶段产生的结果,mapreduce程序执行时,可以没有reduce阶段,但是肯定会有map阶段,如果没有reduce阶段这个地方有是-m-。
- 一个reduce会产生一个part-r-开头的文件。
查看输出文件内容:(结果是按key首字母(如果首字母相同者第二个字母,依此类推)升序排序的键值对)
[hadoop@python5 hadoop]$ hdfs dfs -cat hdfs://192.168.132.110:9000/user/hadoop/output/part-r-00000
18/11/04 12:42:44 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
(HDFS) 1
-yet. 1
Both 1
Distributed 1
File 1
Hadoop 5
In 1
Map/Reduce, 1
MapReduce 1
System 1
The 1
These 1
Useful 1
a 2
across 1
addition, 1
aggregate 1
and 2
any 1
application 1
applications 1
are 4
automatically 1
bandwidth 1
be 1
both 1
but 1
by 1
cluster. 2
codebase 1
computational 1
computenodes, 1
data 2
designed 1
distributed 1
divided 1
each 1
executed 1
failures 1
file 1
for 1
fragments 1
framework 1
framework. 1
handled 1
high 1
implements 1
in 2
independent 1
integrated 1
into 1
is 1
it 1
languages. 1
main 1
many 1
may 1
modules 1
motion. 1
named 1
node 2
not 1
of 2
on 2
or 1
other 1
paradigm 1
programming 1
project 1
provides 2
providing 1
re-executed 1
reliability 1
small 1
so 1
stores 1
system 1
that 3
the 8
tightly 1
transparently 1
using 1
very 1
where 1
which 1
with 2
work, 1
12)Hadoop各个功能模块的理解
(1) HDFS模块
HDFS负责大数据的存储,通过将大文件分块后进行分布式存储方式,突破了服务器硬盘大小的限制,解决了单台机器无法存储大文件的问题,HDFS是个相对独立的模块,可以为YARN提供服务,也可以为HBase等其他模块提供服务。
(2) YARN模块
YARN是一个通用的资源协同和任务调度框架,是为了解决Hadoop1.x中MapReduce里NameNode负载太大和其他问题而创建的一个框架。
YARN是个通用框架,不止可以运行MapReduce,还可以运行Spark、Storm等其他计算框架。
(3) MapReduce模块
MapReduce是一个计算框架,它给出了一种数据处理的方式,即通过Map阶段、Reduce阶段来分布式地流式处理数据。它只适用于大数据的离线处理,对实时性要求很高的应用不适用。
13)开启历史服务 (备注:必须要启动namenode进程才能通过web访问JobHistory页面)
(1)历史服务介绍
Hadoop开启历史服务可以在web页面上查看Yarn上执行job情况的详细信息。可以通过历史服务器查看已经运行完的Mapreduce作业记录,比如用了多少个Map、用了多少个Reduce、作业提交时间、作业启动时间、作业完成时间等信息。
(2)开启历史服务
[hadoop@python5 ~]$ ${HADOOP_HOME}/sbin/mr-jobhistory-daemon.sh start histroyserver
starting historyserver, logging to /home/hadoop/hadoop-2.9.0/logs/mapred-hadoop-historyserver-python5.out
开启后,可以通过Web页面查看历史服务器:
http://192.168.132.110:19888/
点开job_1541300559012_0001:
从集群页面查看jobhistory:
访问:http://192.168.132.110:8088/
历史服务器的Web端口默认是19888,可以查看Web界面。
但是在上面所显示的某一个Job任务页面的最下面,Map和Reduce个数的链接上,点击进入Map的详细信息页面,再查看某一 个Map或者Reduce的详细日志是看不到的,是因为没有开启日志聚集服务。
14)开启日志聚集
(1)日志聚集介绍:
MapReduce是在各个机器上运行的,在运行过程中产生的日志存在于各个机器上,为了能够统一查看各个机器的运行日志,将日志 集中存放在HDFS上,这个过程就是日志聚集。
(2)开启日志聚集
配置日志聚集功能:Hadoop默认是不启用日志聚集的。在yarn-site.xml文件里配置启用日志聚集。添加如下内容:
yarn.log-aggregation-enable
true
yarn.log-aggregation-retain-seconds
3600
yarn.log-aggregation-enable:是否启用日志聚集功能。
yarn.log-aggregation.retain-seconds:设置日志保留时间,单位是秒。
(3)重启yarn进程和HistroyServer进程
(4)测试日志聚集
运行一个demo MapReduce,使之产生日志;运行Job后,就可以在历史服务器Web页面查看各个Map和Reduce的日志 了。
完全分部式是真正利用多台Linux主机来进行部署Hadoop,对Linux机器集群进行规划,使得Hadoop各个模块分别部署在不同的多台机器上。
1)环境准备
(1)克隆两个虚拟机器,虚拟机名称分别为:bigdata02,bigdata03。备注:我这里没有克隆,因为之前就安装了3个,另外一个名称是ibigdata01。
(2)配置网络
修改网络参数:
bigdata01虚拟机:
IPADDR=192.168.132.200
NETMASK=255.255.255.0
GATEWAY=192.168.132.2
DNS1=202.106.196.115
DNS2=202.106.195.68
DNS3=202.106.0.20bigdata02虚拟机:
IPADDR=192.168.132.210
NETMASK=255.255.255.0
GATEWAY=192.168.132.2
DNS1=202.106.196.115
DNS2=202.106.195.68
DNS3=202.106.0.20bigdata03虚拟机:
IPADDR=192.168.132.220
NETMASK=255.255.255.0
GATEWAY=192.168.132.2
DNS1=202.106.196.115
DNS2=202.106.195.68
DNS3=202.106.0.20
(3)配置hostname
bigdata01虚拟机:bigdata-senior01.chybinmy.com
bigdata02虚拟机:bigdata-senior02.chybinmy.com
bigdata02虚拟机:bigdata-senior03.chybinmy.com
2)服务器功能规划
3)在第一台机器上安装新的Hadoop
为了和之前Classroom机器上安装伪分布式Hadoop区分开来,我们将Classroom上的Hadoop服务都停止掉,然后在一个新的目录/opt/modules/app下安装另外一个Hadoop。
我们采用先在第一台机器上解压、配置Hadoop,然后再分发到其他两台机器上的方式来安装集群。
(1)解压Hadoop目录
[hadoop@bigdata-senior01 app]$ tar -zxvf hadoop-2.9.0.tar.gz -C /opt/modules/app
(2)修改变量HADOOP_HOME和HADOOP_CONF_DIR
[hadoop@bigdata-senior01 ~]$ cat /home/hadoop/.bashrc
修改为:
export HADOOP_HOME=/opt/modules/app/hadoop-2.9.0
export HADOOP_CONF_DIR=/opt/modules/app/hadoop-2.9.0/etc/hadoop
(3)配置core-site.xml
[hadoop@bigdata-senior01 hadoop]$ vim ${HADOOP_CONF_DIR}/core-site.xml
fs.defaultFS
hdfs://bigdata-senior01.chybinmy.com:9000
hadoop.tmp.dir
/opt/modules/app/hadoop-2.9.0/data/tmp
fs.defaultFS为NameNode的地址。
hadoop.tmp.dir为hadoop临时目录的地址,默认情况下,NameNode和DataNode的数据文件都会存在这个目录下的对应子目录下。应该保证此目录是存在的,如果不存在,先创建。
(4)配置hdfs-site.xml (备注:本集群搭建完毕后,执行start-dfs.sh时,过程中没有启动secondarynamenode,并且各节点命令行执行hdfs getconf -secondarynamenodes时,都报错:Does not contain a valid host:port authority: bigdata-senior03.chybinmy.com:50090,原来hdfs-site.xml中新增的关于secondarynamenode的配置是剪切复制的,有bug,手打就好了,奶奶滴!)
[hadoop@bigdata-senior01 hadoop]$ vim ${HADOOP_CONF_DIR}/hdfs-site.xml
dfs.namenode.secondary.http-address
bigdata-senior03.chybinmy.com:50090
dfs.namenode.secondary.http-address是指定secondaryNameNode的http访问地址和端口号,因为在规划中,我们将BigData03规划为SecondaryNameNode服务器。
所以这里设置为:bigdata-senior03.chybinmy.com:50090
(5)配置slaves
[hadoop@bigdata-senior01 hadoop]$ vi ${HADOOP_CONF_DIR}/slaves
bigdata-senior01.chybinmy.com
bigdata-senior02.chybinmy.com
bigdata-senior03.chybinmy.com
slaves文件是指定HDFS上有哪些DataNode节点。
(6)配置yarn-site.xml
[hadoop@bigdata-senior01 hadoop]$ vi ${HADOOP_CONF_DIR}/yarn-site.xml
yarn.resourcemanager.hostname
bigdata-senior02.chybinmy.com
yarn.nodemanager.aux-services
mapreduce_shuffle
yarn.log-aggregation-enable
true
yarn.log-aggregation-retain-seconds
3600
根据规划yarn.resourcemanager.hostname
这个指定resourcemanager服务器指向bigdata-senior02.chybinmy.com
。
yarn.log-aggregation-enable
是配置是否启用日志聚集功能。
yarn.log-aggregation.retain-seconds
是配置聚集的日志在HDFS上最多保存多长时间。
(7)配置mapred-site.xml
从mapred-site.xml.template复制一个mapred-site.xml文件。
[hadoop@bigdata-senior01 hadoop]$ cp mapred-site.xml.template mapred-site.xml
[hadoop@bigdata-senior01 hadoop]$ vim ${HADOOP_CONF_DIR}/mapred-site.xml
mapreduce.framework.name
yarn
mapreduce.jobhistory.address
bigdata-senior01.chybinmy.com:10020
mapreduce.jobhistory.webapp.address
bigdata-senior01.chybinmy.com:19888
mapreduce.framework.name设置mapreduce任务运行在yarn上。
mapreduce.jobhistory.address是设置mapreduce的历史服务器安装在bigdata01机器上。
mapreduce.jobhistory.webapp.address是设置历史服务器的web页面地址和端口号。
(8)设置SSH无密码登录
Hadoop集群中的各个机器间会相互地通过SSH访问,每次访问都输入密码是不现实的,所以要配置各个机器间的
SSH是无密码登录的。
a. 在bigdata01上生成公钥
[hadoop@bigdata-senior01 hadoop]$ ssh-keygen -t rsa
一路回车,都设置为默认值,然后再当前用户的Home目录下的.ssh
目录中会生成公钥文件(id_rsa.pub)
和私钥文件(id_rsa)
。
b. 分发公钥(备注:此过程中有时候需要输入要连接的主机用户的登录密码)
[hadoop@bigdata-senior01 .ssh]$ ssh-copy-id bigdata-senior01.chybinmy.com
[hadoop@bigdata-senior01 .ssh]$ ssh-copy-id bigdata-senior02.chybinmy.com
[hadoop@bigdata-senior01 .ssh]$ ssh-copy-id bigdata-senior03.chybinmy.com
c. 设置bigdata02、bigdata03到其他机器的无密钥登录
同样的在bigdata02、bigdata03上生成公钥和私钥后,将公钥分发到三台机器上。
4)分发Hadoop文件
(1)首先在其他两台机器上创建存放Hadoop的目录
[hadoop@bigdata-senior02 ~]$ mkdir /opt/modules/app
[hadoop@bigdata-senior03 ~]$ mkdir /opt/modules/app
备注:我是用scp命令来实现的
(2)通过Scp分发
Hadoop根目录下的share/doc目录是存放的hadoop的文档,文件相当大,建议在分发之前将这个目录删除掉,可以节省硬盘空间并 能提高分发的速度。
[hadoop@bigdata-senior01 tmp]$ du -sh /opt/modules/app/hadoop-2.9.0/share/doc
464M /opt/modules/app/hadoop-2.9.0/share/doc[hadoop@bigdata-senior01 hadoop-2.9.0]$ scp -r /opt/modules/app/hadoop-2.9.0/ bigdata- senior02.chybinmy.com:/opt/modules/app
[hadoop@bigdata-senior01 hadoop-2.9.0]$ scp -r /opt/modules/app/hadoop-2.9.0/ bigdata-senior03.chybinmy.com:/opt/modules/app
或者在命令行执行:
[hadoop@bigdata-senior03 modules]$ nodes=`tail -n 2 hadoopfull/hadoop-2.9.0/etc/hadoop/slaves` ; \
> for node in ${nodes} ; do scp -r hadoopfull/ hadoop@${node} ; done
5)格式化namenode
在NameNode机器上执行格式化:
[hadoop@bigdata-senior01 hadoop-2.9.0]$ /opt/modules/app/hadoop-2.9.0/bin/hdfs namenode –format
注意:
如果需要重新格式化NameNode,需要先将原来NameNode和DataNode下的文件全部删除,不然会报错,NameNode和DataNode所在目录是在core-site.xml
中hadoop.tmp.dir
、dfs.namenode.name.dir
、dfs.datanode.data.dir
属性配置的。
hadoop.tmp.dir
/opt/data/tmp
dfs.namenode.name.dir
file://${hadoop.tmp.dir}/dfs/name
dfs.datanode.data.dir
file://${hadoop.tmp.dir}/dfs/data
因为每次格式化,默认是创建一个集群ID,并写入NameNode和DataNode的VERSION文件中(VERSION文件所在目录为dfs/name/current 和 dfs/data/current),重新格式化时,默认会生成一个新的集群ID,如果不删除原来的目录,会导致namenode中的VERSION文件中是新的集群ID,而DataNode中是旧的集群ID,不一致时会报错。
另一种方法是格式化时指定集群ID参数,指定为旧的集群ID。
6)启动集群
(1)启动HDFS (备注:任何一个节点上启动都可以,因为每个节点上的HADOOP配置文件内容相同,会根据配置在对应的节点上启动相应的进程。不过最好在namenode节点上启动。停止HDFS时,需要在namenode节点上执行stop-dfs.sh)
[hadoop@bigdata-senior01 hadoop-2.9.0]$ start-dfs.sh
(2)启动yarn (备注:可以在任何一个节点上启动)
[hadoop@bigdata-senior02 hadoop-2.9.0]$ start-yarn.sh
(3)启动日志服务
因为我们规划的是在bigdata01服务器上运行MapReduce日志服务,所以要在bigdata01上启动。
[hadoop@bigdata-senior01 tmp]$ mr-jobhistory-daemon.sh start historyserver
starting historyserver, logging to /opt/modules/app/hadoop-2.9.0/logs/mapred-hadoop-historyserver-bigdata-senior01.chybinmy.com.out
最总各个节点上的进程:(和搭建之前规划的一样)
(3)查看HDFS web
http://bigdata-senior01.chybinmy.com:50070/
(4)查看secondarynamenode web
http://bigdata-senior03.chybinmy.com:50090/
(5)查看YARN web
http://bigdata-senior02.chybinmy.com:8088/
(6)查看mapreduce Jobhistory web
http://bigdata-senior01.chybinmy.com:19888/
HA的意思是High Availability高可用,指当当前工作中的机器宕机后,会自动处理这个异常,并将工作无缝地转移到其他备用机器上去,以来保证服务的高可用。
HA方式安装部署才是最常见的生产环境上的安装部署方式。Hadoop HA是Hadoop 2.x中新添加的特性,包括NameNode HA 和 ResourceManager HA。因为DataNode和NodeManager本身就是被设计为高可用的,所以不用对他们进行特殊的高可用处理。
1)时间服务器搭建
Hadoop对集群中各个机器的时间同步要求比较高,要求各个机器的系统时间不能相差太多,不然会造成很多问题。可以配置集群中各个机器和互联网的时间服务器进行时间同步,但是在实际生产环境中,集群中大部分服务器是不能连接外网的,这时候可以在内网搭建一个自己的时间服务器(NTP服务器),集群的各个机器与这个时间服务器进行时间同步。
2)配置NTP服务器
我们选择第三台机器(bigdata-senior03.chybinmy.com)为NTF服务器,其他机器和这台机器进行同步。
(1)检查ntp服务是否已经安装
[hadoop@bigdata-senior03 ~]$ rpm -qa | grep ntp
ntpdate-4.2.6p5-28.el7.centos.x86_64
ntp-4.2.6p5-28.el7.centos.x86_64
显示已经安装过了ntp程序,其中ntpdate-4.2.6p5-28.el7.centos.x86_64
是用来和某台服务器进行同步的,ntp-4.2.6p5-28.el7.centos.x86_64
是用来提供时间同步服务的。
(2)在bigdata-senior03.chybinmy.com节点上修改配置文件ntp.conf
[hadoop@bigdata-senior03 ~]$ vim /etc/ntp.conf
第一处新增,意思是从IP地址192.168.132.1-192.168.132.254,默认网关255.255.255.0的服务器都可以使用我们的NTP服务器来同步时间
第二处新增,指明互联网和局域网中作为NTP服务器的IP。(备注:最后被注释掉,没用到)
第三处是修改,将原有注释去掉,是当服务器与公用的时间服务器失去联系时以本地时间为客户端提供时间服务。
设置开机自启,将chronyd设置为disable
[root@bigdata-senior03 hadoop]# systemctl disable chronyd #禁用chronyd,因为和NTP冲突
[root@bigdata-senior03 hadoop]# systemctl is-enabled chronyd
disabled通过systemctl enable ntpd.service命令设置ntp开机自启
[root@bigdata-senior03 hadoop]# systemctl enable ntpd.service
每次开机ntp就会自动启动
配置文件修改完成,保存退出,启动服务:
[root@bigdata-senior03 hadoop]# service ntpd start
启动后,一般需要5-10分钟左右的时候才能与外部时间服务器开始同步时间。可以通过命令查询NTPD服务情况。
查看ntp的状态:
查看服务连接和监听:
(3)在bigdata-senior01.chybinmy.com和bigdata-senior02.chybinmy.com节点上安装ntp。(备注:这两个节点上不用 修改配置 文件和启动ntp服务 )
通过crontab工具添加定时任务:
[root@bigdata-senior01 hadoop]# crontab -e
*/2 * * * * /usr/sbin/ntpdate bigdata-senior03.chybinmy.com[root@bigdata-senior02 hadoop]# crontab -e
*/2 * * * * /usr/sbin/ntpdate bigdata-senior03.chybinmy.com
则每隔两分钟这两个节点上的时间就会和bigdata-senior03.chybinmy.com上的时间同步。
测试:
[hadoop@bigdata-senior02 ~]$ sudo date -s "2012-10-24 20:30:40" #手动修改bigdata-senior02.chybinmy.com上的系统时间
2012年 10月 24日 星期三 20:30:40 CST
[hadoop@bigdata-senior02 ~]$ date "+%Y-%m-%d %H:%M:%S"
2012-10-24 20:31:30
[hadoop@bigdata-senior02 ~]$ date "+%Y-%m-%d %H:%M:%S"
2018-11-07 00:44:23 #两分钟之后执行定时任务和bigdata-senior03.chybinmy.com的系统时间自动同步
您在 /var/spool/mail/hadoop 中有邮件
3)zookeeper分布式机器部署
(1)zookeeper说明
Zookeeper在Hadoop集群中的作用:
Zookeeper是分布式管理协作框架,Zookeeper集群用来保证Hadoop集群的高可用,(高可用的含义是:集群中就算有一部分服务器宕机,也能保证正常地对外提供服务。)
Zookeeper保证高可用的原理:
Zookeeper集群能够保证NamaNode服务高可用的原理是:Hadoop集群中有两个NameNode服务,两个NaameNode都定时地给Zookeeper发送心跳,告诉Zookeeper我还活着,可以提供服务,单某一个时间只有一个是Action状态,另外一个是Standby状态,一旦Zookeeper检测不到Action NameNode发送来的心跳后,就切换到Standby状态的NameNode上,将它设置为Action状态,所以集群中总有一个可用的NameNode,达到了NameNode的高可用目的。
Zookeeper的选举机制:
Zookeeper集群也能保证自身的高可用,保证自身高可用的原理是,Zookeeper集群中的各个机器分为Leader和Follower两个角色,写入数据时,要先写入Leader,Leader同意写入后,再通知Follower写入。客户端读取数时,因为数据都是一样的,可以从任意一台机器上读取数据。
这里Leader角色就存在单点故障的隐患,高可用就是解决单点故障隐患的。Zookeeper从机制上解决了Leader的单点故障问题,Leader是哪一台机器是不固定的,Leader是选举出来的。选举流程是,集群中任何一台机器发现集群中没有Leader时,就推荐自己为Leader,其他机器来同意,当超过一半数的机器同意它为Leader时,选举结束,所以Zookeeper集群中的机器数据必须是奇数。这样就算当Leader机器宕机后,会很快选举出新的Leader,保证了Zookeeper集群本身的高可用。
写入高可用:
集群中的写入操作都是先通知Leader,Leader再通知Follower写入,实际上当超过一半的机器写入成功后,就认为写入成功了,所以就算有些机器宕机,写入也是成功的。
读取高可用:
zookeeperk客户端读取数据时,可以读取集群中的任何一个机器。所以部分机器的宕机并不影响读取。
zookeeper服务器必须是奇数台,因为zookeeper有选举制度,角色有:领导者、跟随者、观察者,选举的目的是保证集群中数据的一致性。
(2)zookeeper的安装
我们这里在BigData01、BigData02、BigData03三台机器上安装zookeeper集群。
a. 解压安装包
在BigData01上安装解压zookeeper安装包。
[hadoop@bigdata-senior01 ~]$ tar -zxvf zookeeper-3.5.4-beta.tar.gz -C /opt/modules/
b. 修改配置
拷贝conf下的zoo_sample.cfg副本,改名为zoo.cfg。zoo.cfg是zookeeper的配置文件:
[hadoop@bigdata-senior01 zookeeper-3.5.4-beta]$ cp conf/zoo_sample.cfg conf/zoo.cfg
引深:zoo.cfg文件说明
# The number of milliseconds of each tick。每一个滴答的毫秒数
tickTime=2000
# The number of ticks that the initial synchronization phase can take.初始同步阶段可以使用的时钟数量。
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement。在发送请求和获得确认之间可以通过的滴答数
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just example sakes.存储快照的目录。不要使用/tmp来存储。
dataDir=/opt/modules/zookeeper-3.5.4-beta/data/zData
# the port at which the clients will connect。zookeeper客户端将连接的端口
clientPort=2181
# the maximum number of client connections.
# increase this if you need to handle more clients。最大的客户端连接数。如果你需要处理更多的客户,就增加这一点。
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours。清除任务间隔小时数
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1#指定zookeeper集群中各个机器的信息:
server.1=bigdata-senior01.chybinmy.com:2888:3888
server.2=bigdata-senior02.chybinmy.com:2888:3888
server.3=bigdata-senior03.chybinmy.com:2888:3888
c. 创建myid文件。
在dataDir所指定的目录下创一个名为myid的文件,文件内容为server点后面的数字。
[hadoop@bigdata-senior01 ~]$ cd $ZOOKEEPER_HOME
[hadoop@bigdata-senior01 zookeeper-3.5.4-beta]$ touch data/zData/myid^C
[hadoop@bigdata-senior01 zookeeper-3.5.4-beta]$ echo 1>> data/zData//myid ^C
[hadoop@bigdata-senior01 zookeeper-3.5.4-beta]$ cat data/zData/myid
1
d.分发给其它机器
[hadoop@bigdata-senior01 zookeeper-3.5.4]$ scp -r /opt/modules/zookeeper-3.5.4 bigdata-senior02.chybinmy.com:/opt/modules
[hadoop@bigdata-senior01 zookeeper-3.5.4]$ scp -r /opt/modules/zookeeper-3.5.4 bigdata-senior03.chybinmy.com:/opt/modules
e.修改其它机器上的myid文件
[hadoop@bigdata-senior02 zookeeper-3.5.4]$ echo 2 > /opt/modules/zookeeper-3.5.4/data/zData/myid
[hadoop@bigdata-senior02 zookeeper-3.5.4]$ cat /opt/modules/zookeeper-3.5.4/data/zData/myid
f.启动zookeeper
需要在各个机器上分别启动zookeeper。
[hadoop@bigdata-senior01 ~]$ zkServer.sh start
[hadoop@bigdata-senior02 ~]$ zkServer.sh start
[hadoop@bigdata-senior03 ~]$ zkServer.sh start
[hadoop@bigdata-senior01 ~]$ zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /opt/modules/zookeeper-3.5.4-beta/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
[hadoop@bigdata-senior01 ~]$ jps
1480 QuorumPeerMain
1531 Jps
(3)zookeeper命令
进入zookeeper Shell
在zookeeper根目录下执行 bin/zkCli.sh进入zk shell模式。
zookeeper很像一个小型的文件系统,/是根目录,下面的所有节点都叫zNode。
进入zk shell 后输入任意字符,可以列出所有的zookeeper命令:
4)Hadoop 2.x HDFS HA 部署
(1)HDFS HA原理
单NameNode的缺陷存在单点故障的问题,如果NameNode不可用,则会导致整个HDFS文件系统不可用。所以需要设计高可用的HDFS(Hadoop HA)来解决NameNode单点故障的问题。解决的方法是在HDFS集群中设置多个NameNode节点。但是一旦引入多个NameNode,就有一些问题需要解决。
HDFS HA需要保证的四个问题:
保证NameNode内存中元数据数据一致,并保证编辑日志文件的安全性。
多个NameNode如何协作
客户端如何能正确地访问到可用的那个NameNode。
怎么保证任意时刻只能有一个NameNode处于对外服务状态。
解决方法
对于保证NameNode元数据的一致性和编辑日志的安全性,采用Zookeeper来存储编辑日志文件。
两个NameNode一个是Active状态的,一个是Standby状态的,一个时间点只能有一个Active状态的
NameNode提供服务,两个NameNode上存储的元数据是实时同步的,当Active的NameNode出现问题时,通过Zookeeper实时切换到Standby的NameNode上,并将Standby改为Active状态。
客户端通过连接一个Zookeeper的代理来确定当时哪个NameNode处于服务状态。
5)HDFS HA架构图
HDFS HA架构中有两台NameNode节点,一台是处于活动状态(Active)为客户端提供服务,另外一台处于热备份状态(Standby)。
元数据文件有两个文件:fsimage和edits,备份元数据就是备份这两个文件。JournalNode用来实时从Active NameNode上拷贝edits文件,JournalNode有三台也是为了实现高可用。
Standby NameNode不对外提供元数据的访问,它从Active NameNode上拷贝fsimage文件,从JournalNode上拷贝edits文件,然后负责合并fsimage和edits文件,相当于SecondaryNameNode的作用。最终目的是保证Standby NameNode上的元数据信息和Active NameNode上的元数据信息一致,以实现热备份。
Zookeeper来保证在Active NameNode失效时及时将Standby NameNode修改为Active状态。
ZKFC(失效检测控制)是Hadoop里的一个Zookeeper客户端,在每一个NameNode节点上都启动一个ZKFC进程,来监控NameNode的状态,并把NameNode的状态信息汇报给Zookeeper集群,其实就是在Zookeeper上创建了一个Znode节点,节点里保存了NameNode状态信息。当NameNode失效后,ZKFC检测到报告给Zookeeper,Zookeeper把对应的Znode删除掉,Standby ZKFC发现没有Active状态的NameNode时,就会用shell命令将自己监控的NameNode改为Active状态,并修改Znode上的数据。
Znode是个临时的节点,临时节点特征是客户端的连接断了后就会把znode删除,所以当ZKFC失效时,也会导致切换NameNode。
DataNode会将心跳信息和Block汇报信息同时发给两台NameNode,DataNode只接受Active NameNode发来的文件读写操作指令。
6)搭建HDFS HA 环境
(1)服务器角色规划
bigdata-senior01.chybinmy.com | bigdata-senior02.chybinmy.com | bigdata-senior01.chybinmy.com |
NameNode | NameNode | |
Zookeeper | Zookeeper | Zookeeper |
DataNode | DataNode | DataNode |
ResourceManage | ResourceManage | |
NodeManager | NodeManager | NodeManager |
(2)创建HDFS HA 版本Hadoop程序目录
在bigdata01、bigdata02、bigdata03三台机器上分别创建目录/opt/modules/hadoopha/用来存放Hadoop HA环境。
1 | [hadoop@bigdata-senior01 modules]$ mkdir /opt/modules/hadoopha |
---|
(3)解压Hadoop
1 | [hadoop@bigdata-senior01 modules]$ tar -zxf /home/hadoop/hadoop-2.9.0.tar.gz -C /opt/modules/hadoopha/ |
---|
(4) 配置Hadoop JDK路径
修改hadoop-env.sh、mapred-env.sh、yarn-env.sh文件中的JDK路径。备注:我是在/home/hadoop/.bashrc文件或/etc/profile 中配置的JAVA_HOME。
export JAVA_HOME="/home/hadoop/opt/jdk1.8.0_172"
(5)配置hdfs-site.xml
- configuration>
dfs.nameservices ns1 - 此新名称服务的逻辑名称。为此名称服务选择一个逻辑名称,例如“mycluster”,并将此逻辑名称用于此配置选项的值。您选择的名称是任意的。它将同时用于配置和作为集群中绝对HDFS路径的授权组件。注意:如果您还使用HDFS联合,则此配置设置还应包括其他名称服务(HA或其他)的列表,作为逗号分隔的列表。
dfs.ha.namenodes.ns1 nn1,nn2 - dfs.ha.namenodes.[nameservice ID] - 此名称服务中每个名称节点的唯一标识符。使用逗号分隔的NameNode IDs列表进行配置。DataNodes将使用它来确定集群中的所有NameNodes。注意:目前,每个名称服务最多只能配置两个名称节点。
dfs.namenode.rpc-address.ns1.nn1 bigdata-senior01.chybinmy.com:8020 dfs.namenode.rpc-address.ns1.nn2 bigdata-senior02.chybinmy.com:8020 dfs.namenode.http-address.ns1.nn1 bigdata-senior01.chybinmy.com:50070 dfs.namenode.http-address.ns1.nn2 bigdata-senior02.chybinmy.com:50070 dfs.namenode.shared.edits.dir qjournal://bigdata-senior01.chybinmy.com:8485;bigdata-senior02.chybinmy.com:8485;bigdata-senior03.chybinmy.com:8485/ns1 dfs.journalnode.edits.dir /opt/modules/hadoopha/hadoop-2.9.0/tmp/data/dfs/jn - 这是JournalNode计算机上的绝对路径,JNs使用的编辑和其他本地状态将存储在其中。此配置只能使用单个路径。通过运行多个单独的JournalNodes或在本地连接的RAID阵列上配置此目录,可以提供此数据的冗余。例如:
dfs.journalnode.edits.dir /path/to/journal/node/local/data dfs.client.failover.proxy.provider.ns1 org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider - dfs.client.failover.proxy.provider.[nameservice ID] -HDFS客户端用于连接活动NameNode的Java类。
- 配置Java类的名称,DFS客户机将使用该类来确定哪个NameNode是当前活动的,因此哪个NameNode当前正在为客户机请求提供服务。当前与Hadoop一起提供的两个实现是 ConfiguredFailoverProxyProvider和 RequestHedgingProxyProvider(对于第一个调用,它同时调用所有名称节点以确定活动的名称节点,对于随后的请求,调用活动名称节点直到故障转移)如果不使用自定义代理提供程序,请使用其中之一。
dfs.ha.fencing.methods - sshfence
- shell(/bin/true)
- dfs.ha.fencing.methods- 将用于在故障转移期间保护活动NameNode的脚本或Java类列表。
- 为了保证系统的正确性,在任何给定的时间只有一个NameNode处于活动状态。重要的是,在使用Quorum Journal Manager时,只允许一个名称节点写入JournalNodes,因此不存在从分裂的大脑场景( split-brain scenario)破坏文件系统元数据的可能性。然而,当发生故障转移时,前一个活动的NameNode仍然有可能为客户端提供读请求,这些请求可能已经过期,直到此NameNode在尝试向日志节点写入时关闭。因此,即使在使用Quorum Journal Manager时,仍然需要配置一些隔离方法。但是,为了在保护机制失败时提高系统的可用性,建议配置一个保护方法,该方法确保作为列表中的最后一个保护方法返回成功,。注意,如果您选择不使用实际的保护方法,您仍然必须为此设置配置一些东西,例如“shell(/bin/true)”。
- 故障转移期间使用的保护方法被配置为一个以回车分隔的列表,在指示保护成功之前,将依次尝试该列表。Hadoop提供了两种方法:shell和sshfence。有关实现自定义保护方法的信息,请参见 org.apache.hadoop.ha.NodeFencer类。
- sshfence - SSH到活动的NameNode并杀死进程。sshfence选项SSHes到目标节点,并使用fuser终止监听服务TCP端口的进程。为了使这个隔离选项有效,它必须能够在不提供密码的情况下SSH到目标节点。因此,还必须配置dfs.ha.fencing.ssh.private-key-files选项,它是逗号分隔的SSH私钥文件列表。
- 或者,可以配置一个非标准的用户名或端口来执行ssh。还可以为ssh配置超时(以毫秒为单位),在此之后,此保护方法将被视为失败。可以这样配置:
dfs.ha.fencing.methods sshfence([[username][:port]]) dfs.ha.fencing.ssh.connect-timeout 30000 - shell -运行任意shell命令以隔离活动的名称节点。shell 保护方法运行任意shell命令。它可以这样配置:
dfs.ha.fencing.methods shell(/path/to/my/script.sh arg1 arg2 ...) - '(' 和 ')' 之间的字符串直接传递给bash shell,并且可能不包含任何右括号。
- shell命令将在一个环境中运行,该环境设置为包含所有当前Hadoop配置变量,用 "_" 字符替换配置键中的任何 "." 字符。所使用的配置已经将任何特定于名称节点的配置升级为其通用形式-例如, dfs_namenode_rpc-address 将包含目标节点的RPC地址,即使配置可能将该变量指定为dfs.namenode.rpc-address.ns1.nn1。
- 此外,还可以使用以下与要隔离的目标节点相关的变量:
$target_host hostname of the node to be fenced $target_port IPC port of the node to be fenced $target_address the above two, combined as host:port $target_nameserviceid the nameservice ID of the NN to be fenced $target_namenodeid the namenode ID of the NN to be fenced - 这些环境变量也可以在shell命令本身中用作替换。例如:
dfs.ha.fencing.methods shell(/path/to/my/script.sh --nameservice=$target_nameserviceid $target_host:$target_port) 如果shell命令返回退出代码0,则确定保护成功。如果返回任何其他退出代码,则保护未成功,将尝试列表中的下一个保护方法。
注意:此隔离方法(即运行shell命令)不实现任何超时。如果超时是必要的,那么应该在shell脚本本身中实现超时(例如,通过分岔子shell在几秒钟内杀死其父shell)。
dfs.ha.fencing.ssh.private-key-files /home/hadoop/.ssh/id_rsa
dfs.ha.automatic-failover.enabled
true
(6)配置core-site.xml
fs.defaultFS hdfs://ns1 - fs.defaultFS - Hadoop FS客户机在未给定路径前缀时使用的默认路径前缀。
- 现在可以选择配置Hadoop客户机的默认路径,以使用新的启用了Ha的逻辑URI。如果您在前面使用“mycluster”作为nameservice ID,这将是所有HDFS路径的权限部分的值。这可以这样配置,在您的core-site.xml文件中:
fs.defaultFS hdfs://mycluster hadoop.tmp.dir /opt/modules/hadoopha/hadoop-2.9.0/data/tmp dfs.namenode.name.dir file://${hadoop.tmp.dir}/dfs/name dfs.datanode.data.dir file://${hadoop.tmp.dir}/dfs/data
ha.zookeeper.quorum
bigdata-senior01.chybinmy.com:2181,bigdata-senior02.chybinmy.com:2181,bigdata-senior03.chybinmy.com:2181
(7)配置slaves文件
bigdata-senior01.chybinmy.com
bigdata-senior02.chybinmy.com
bigdata-senior03.chybinmy.com
(8)分发到其他节点
分发之前先将share/doc目录删除,这个目录中是帮助文件,并且很大,可以删除。
[hadoop@bigdata-senior01 hadoop-2.9.0]$ scp -r /opt/modules/hadoopha bigdata-senior02.chybinmy.com:/opt/modules
[hadoop@bigdata-senior01 hadoop-2.9.0]$ scp -r /opt/modules/hadoopha bigdata-senior03.chybinmy.com:/opt/modules
(9)启动HDFS HA集群
三台机器分别启动Journalnode。
或者通过shell统一启动:(在集群中任一节点上命令行执行此脚本文件,三台都会启动Journalnode)
#!/usr/bin/bash
JOURNAL_NODES="bigdata-senior01.chybinmy.com bigdata-senior02.chybinmy.com bigdata-senior03.chybinmy.com"
hadoop-daemons.sh --config "$HADOOP_CONF_DIR" --hostnames "$JOURNAL_NODES" /
--script "$HADOOP_HOME/bin/hdfs" start journalnode
[hadoop@bigdata-senior01 hadoop-2.9.0]$ hadoop-daemon.sh start journalnode
[hadoop@bigdata-senior02 hadoop-2.9.0]$hadoop-daemon.sh start journalnode
[hadoop@bigdata-senior03 hadoop-2.9.0]$ hadoop-daemon.sh start journalnode
(10)启动zookeeper
在三台节点上启动Zookeeper:(我已经配置好了zookeeper的环境变量,所以这里就可以直接输入脚本)
[hadoop@bigdata-senior01 ~]$ zkServer.sh start
[hadoop@bigdata-senior02 ~]$ zkServer.sh start
[hadoop@bigdata-senior03 ~]$ zkServer.sh start
(11)启动namenode故障转移。(会分别在各个namenode节点上开启DFSZKFailoverController进程)
[hadoop@bigdata-senior01 hadoop-2.9.0]# hadoop-daemons.sh start zkfc #可以在集群中任一节点上执行
(12)格式化namenode
在第一台上进行NameNode格式化:
[hadoop@bigdata-senior01 hadoop-2.9.0]$ hdfs namenode -format
然后启动此节点上的namenode:
[hadoop@bigdata-senior01 hadoop-2.9.0]$ hadoop-daemon.sh start namenode
在第二台NameNode上:
[hadoop@bigdata-senior02 hadoop-2.9.0]$ hdfs namenode -bootstrapStandby
(13)启动NameNode
在第二台上启动NameNode:
[hadoop@bigdata-senior02 hadoop-2.9.0]$ hadoop-daemon.sh start namenode
查看HDFS Web页面,此时两个NameNode都是standby状态。
切换第一台为active状态:
[hadoop@bigdata-senior01 hadoop-2.9.0]$ hdfs haadmin -transitionToActive nn1
可以添加上forcemanual参数,强制将一个NameNode转换为Active状态:
[hadoop@bigdata-senior01 hadoop-2.9.0]$ hdfs haadmin –transitionToActive --forcemanual nn1