hadoop集群搭建需要一些准备操作,未避免集群在运行时出现意想不到的问题,推荐将下述准备工作完成以后在进行集群的搭建。
准备工作
(1)服务器IP映射(非必须)
Linux IP映射添加
(2)关闭SELinux(高级运维可以不关)
Centos SELinux关闭
(3)节点之间免密钥登录(可以是root用户,也是以是hadoop用户,看具体需要利用什么用户来启动hadoop)我这里是hadoop用户之间做的免密钥。
Centos8之间ssh免密钥登陆
(4)时间同步
Centos8 chrony时间同步服务
(5)关闭防火墙
Centos8防火墙操作
(6)JDK11安装(hadoop3.3.0需要jdk11)
JDK11 配置——Linux
(7)Zookeeper集群搭建
Zookeeper3.6.x集群搭建
hadoop文件下载
我习惯行把数据存放在/data下,这里利用root用户创建了/data/hadoop目录,并赋予hadoop用户及用户组权限
#创建hadoop存放目录
[root@node1 ~]# mkdir /data/hadoop
#如果没有创建hadoop用户,并以hadoop用户启动集群,需要进行准备工作3的操作。
[root@node1 ~]# groupadd hadoop
[root@node1 ~]# useradd -g hadoop hadoop
#赋予hadoop用户及用户组权限。
[root@node1 ~]# chown -R hadoop.hadoop /data/hadoop
切换到hadoop用户,在所有节点上进行操作。官网下载 hadoop3.3.0版本的文件,下载完成后通过scp命令传输到每个节点中。
#下载文件
[hadoop@nodex ~]$ wget https://downloads.apache.org/hadoop/common/hadoop-3.3.0/hadoop-3.3.0.tar.gz
#解压到/data/hadoop目录
[hadoop@nodex ~]$ tar -xf hadoop-3.3.0.tar.gz -C /data/hadoop
配置hadoop需要的环境变量,方便后面全局使用hadoop的命令
vim ~/.bash_profile
export HADOOP_HOME=/data/hadoop/hadoop-3.3.0
export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH
#重新加载下环境变量
source ~/.bash_profile
集群配置
上述工作准备完成以后就可以进行集群的配置了,集群配置前需要对集群进行规划,需要确认每个节点是什么角色,简单说下每个节点的主要功能:
NameNode:集群中的管理主节点,是分布式文件系统中的管理者,主要负责管理文件系统的命名空间、集群配置信息和存储块的复制等。 DataNode:集群中的数据节点,是文件存储的基本单元,它将Block存储在本地文件系统中。同时周期性地将所有存在的Block信息发送给NameNode。 JournalNode:主要就是负责NameNode之间信息同步,为保证Namenode数据保持一致会通过一组JournalNode进行同步。节点个数需要大于3个,以奇数出现3、5、7个。 NodeManager:运行在单个节点的代理,负责容器,监视其资源使用情况(cpu,内存,磁盘,网络),并将其报告给ResourceManager / Scheduler。 ResourceManager:负责集群统一的资源管理、调度、分配,是在系统中所有应用程序之间仲裁资源的最终权限。 ZKFailOverController(ZKFC):负责NameNode的健康检测(ZKFC会周期性的向它监控的NameNode状态)、会话管理、master选举。 ZooKeeper:帮助hadoop实现HA,选举,存放节点信息,创建锁节点。
具体规划如下(由于我的服务器比较好,如果服务器不太好的情况可以适当减少JournalNode、NodeManager、DataNode的节点数量):
node1 | node2 | node3 | node4 | node5 |
NameNode | NameNode | |||
DataNode | DataNode | DataNode | DataNode | DataNode |
JournalNode | JournalNode | JournalNode | JournalNode | JournalNode |
NodeManager | NodeManager | NodeManager | NodeManager | NodeManager |
ResourceManager | ResourceManager | |||
ZKFC | ZKFC | |||
ZooKeeper | ZooKeeper | ZooKeeper | ZooKeeper | ZooKeeper |
进入到hadoop目录中进行配置
#nodex代表所有得节点都重复操作
[hadoop@nodex hadoop]$ cd /data/hadoop/hadoop-3.3.0
配置下Hadoop集群的环境变量 hadoop-env.sh
#将下列内容添加到文件中
vim etc/hadoop/hadoop-env.sh
export JAVA_HOME=/usr/java/jdk-11.0.9
#2.x的HADOOP_PREFIX改为HADOOP_HOME
export HADOOP_HOME=/data/hadoop/hadoop-3.3.0
export HDFS_NAMENODE_USER=hadoop
export HDFS_DATANODE_USER=hadoop
export HDFS_ZKFC_USER=hadoop
export HDFS_JOURNALNODE_USER=hadoop
export YARN_RESOURCEMANAGER_USER=hadoop
export YARN_NODEMANAGER_USER=hadoop
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop
集群全局配置core-site.xml 具体参数可以参考core-site.xml
#编辑文件
vim etc/hadoop/core-site.xml
<configuration>
<!--集群名称,要和后面HDFS的一致。-->
<property>
<name>fs.defaultFS</name>
<value>hdfs://zsjcluster</value>
</property>
<!--其他临时目录-->
<property>
<name>hadoop.tmp.dir</name>
<value>/data/hadoop/hadoop-3.3.0/data/tmp</value>
</property>
<!--HDFS Web UI默认用户名-->
<property>
<name>hadoop.http.staticuser.user</name>
<value>hadoop</value>
</property>
<!--ZooKeeper服务器地址列表,由ZKFailoverController在自动故障转移中使用。-->
<property>
<name>ha.zookeeper.quorum</name>
<value>node1:2181,node2:2181,node3:2181,node4:2181,node5:2181</value>
</property>
</configuration>
配置HDFS hdfs-site.xml 具体参数可以参考 hdfs-site.xml
vim etc/hadoop/hdfs-site.xml
<configuration>
<!--设置 hdfs得副本数 默认为3-->
<property>
<name>dfs.replication</name>
<value>2</value>
</property>
<!--服务列表名称,后面配置HA NameNode得时候需要下面得名称-->
<property>
<name>dfs.nameservices</name>
<value>zsjcluster</value>
</property>
<!-- 启用webhdfs -->
<property>
<name>dfs.webhdfs.enabled</name>
<value>true</value>
</property>
<!--设置NameNode得ID,你设置了几个NameNode,就需要在value中写几个zsjcluter就是上面定义得-->
<property>
<name>dfs.ha.namenodes.zsjcluster</name>
<value>nn1,nn2</value>
</property>
<!--设置第一个NameNode rpc协议的节点地址以及端口-->
<property>
<name>dfs.namenode.rpc-address.zsjcluster.nn1</name>
<value>node1:8020</value>
</property>
<!--设置第二个NameNode rpc协议的节点地址以及端口-->
<property>
<name>dfs.namenode.rpc-address.zsjcluster.nn2</name>
<value>node2:8020</value>
</property>
<!--HDFS名称节点在本地文件系统上应存储位置-->
<property>
<name>dfs.namenode.name.dir</name>
<value>/data/hadoop/hadoop-3.3.0/data/dfs/name</value>
</property>
<!--HDFS数据节点在本地文件系统上应存储位置-->
<property>
<name>dfs.datanode.data.dir</name>
<value>/data/hadoop/hadoop-3.3.0/data/dfs/data</value>
</property>
<!--设置第一个NameNode http协议的节点地址以及端口 原来默认为50070 3.0以后改成9870-->
<property>
<name>dfs.namenode.http-address.zsjcluster.nn1</name>
<value>node1:9870</value>
</property>
<!--设置第二个NameNode http协议的节点地址以及端口 原来默认为50070 3.0以后改成9870-->
<property>
<name>dfs.namenode.http-address.zsjcluster.nn2</name>
<value>node2:9870</value>
</property>
<!--HA群集中多个名称节点之间的共享存储上的目录,定义journal节点地址端口-->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://node1:8485;node2:8485;node3:8485;node4:8485;node5:8485/zsj</value>
</property>
<!--定义了返回active NameNode地址 开启HA集群-->
<property>
<name>dfs.client.failover.proxy.provider.zsjcluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
<!--故障转移期间用于隔离Active NameNode的脚本或Java类的列表-->
<property>
<name>dfs.ha.fencing.methods</name>
<value>sshfence</value>
</property>
<!--SSH私钥文件列表-->
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/home/hadoop/.ssh/id_dsa</value>
</property>
<!--journalnode文件存储目录-->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/data/hadoop/hadoop-3.3.0/data/journal/data</value>
</property>
<!--是否启用自动故障转移。-->
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
<!-- 配置隔离机制方法,多个机制用换行分割,即每个机制暂用一行 -->
<property>
<name>dfs.ha.fencing.methods</name>
<value>
sshfence
shell(/bin/true)
</value>
</property>
</configuration>
workers 由原来得slaves改为workers,用来定义DataNode
vim etc/hadoop/workers
node1
node2
node3
node4
node5
配置YARN以及NodeManager yarn-site.xml 具体参数可以参考yarn-site.xml
vim etc/hadoop/yarn-site.xml
<configuration>
<!--reduce获取数据的方式-->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!--开启HA-->
<property>
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>
<!---yarn集群的名称-->
<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>yarn-cluster</value>
</property>
<!--设置resourcemanager的ID,中间用逗号隔开-->
<property>
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2</value>
</property>
<!--设置resourcemanager节点位置 rm1由上面定义-->
<property>
<name>yarn.resourcemanager.hostname.rm1</name>
<value>node4</value>
</property>
<!--设置resourcemanager节点位置 rm2由上面定义-->
<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>node5</value>
</property>
<!--设置zookeeper集群信息-->
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>node1:2181,node2:2181,node3:2181,node4:2181,node5:2181</value>
</property>
<!--设置nodemanager内存信息,默认为8192MB(8G),
也可以让集群自动设置内存,yarn.nodemanager.elastic-memory-control.enabled默认为false,我设置内存为16G-->
<property>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>16384</value>
</property>
<!--task所用内存的百分比,默认值为2.1倍,计算机内存小于8GB应该调低这个值-->
<property>
<name>yarn.nodemanager.vmem-pmem-ratio</name>
<value>4</value>
<description>Ratio between virtual memory to physical memory when setting memory limits for containers</description>
</property>
</configuration>
配置MapReduce作业资源配置 mapred-site.xml
vim etc/hadoop/mapred-site.xml
<configuration>
<!--执行MapReduce作业的方式 local(默认),classic or yarn-->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<!--MapReduce应用程序的CLASSPATH-->
<property>
<name>mapreduce.application.classpath</name>
<value>$HADOOP_MAPRED_HOME/*, $HADOOP_MAPRED_HOME/lib/*</value>
</property>
</configuration>
创建数据存放目录,根据上面配置文件进行创建
#其他临时存放目录
mkdir -p /data/hadoop/hadoop-3.3.0/data/tmp
#HDFS名称节点存放目录
mkdir -p /data/hadoop/hadoop-3.3.0/data/dfs/name
#HDFS数据节点存放目录
mkdir -p /data/hadoop/hadoop-3.3.0/data/dfs/data
#journalnode文件存储目录
mkdir -p /data/hadoop/hadoop-3.3.0/data/journal/data
格式化NameNode
以前启动集群是用start-all.sh脚本直接进行启动的,在3.0以后进行了修改,是分为start-dfs.sh(HDFS)和start-yarn.sh(YARN)2个脚本,利用start-all.sh启动也可以只是为报一些警告。
启动 JournalNode ,可以一个节点一个节点启动,也可以直接启动 start-dfs.sh
#直接通过脚本启动 在主节点就可以node1(二选一)
[hadoop@node1 ~]$ start-dfs.sh
#使用单节点启动所有节点都需要启动 (二选一)
[hadoop@nodex ~]$ hdfs --daemon start journalnode
格式化以及同步NameNode
#在其中一个主节点执行
[hadoop@node1 ~]$ hdfs namenode -format
#启动NameNode
[hadoop@node1 ~]$ hdfs namenode
#在另一节节点执行同步
[hadoop@node1 ~]$ hdfs namenode -bootstrapStandby
#在主节点格式化ZKFS
[hadoop@node1 ~]$ hdfs zkfc -formatZK
#关闭DHFS
[hadoop@node1 ~]$ stop-dfs.sh
HDFS启动
#任意节点启动HDFS
[hadoop@node1 ~]$ start-dfs.sh
# 使用jps查看各个节点的状态
[hadoop@nodex ~]$ jps
访问下web节点 node1:9870,node2:9870,node1处于standby状态node2处于activate状态
数据节点也都和设计的一样 node1-node5都做数据节点
hdfs-HA完全启动完成,关闭使用stop-dfs.sh进行关闭
YARN启动
#任意节点,启动yarn脚本
[hadoop@node1 ~]$ start-yarn.sh
可以发现ResourceManager 和 NodeManager 已经完全启动了。访问webUI节点发现和hadoop2.x不同的是以前不会自动跳转到ResourceManager的主节点,现在可以直接自动跳转主节点UI界面了 node4:8088 node5:8088
目前hadoop -HA已经完全搭建完成了,也可以使用start-all.sh 和 stop-all.sh进行打开关闭,或者使用3.X的命令,start-dfs.sh start-yarn.sh对hadoop集群分开关闭。