单机和伪分布式安装就不介绍了,可以看官网Hadoop: Setting up a Single Node Cluster.。本文直接说集群配置。
1 准备工作
1.1 准备服务器
为了配置Hadoop集群,申请了3台阿里云ECS,都安装了CentOS,配置如图,差不多就行:
申请完服务器,如果你用
ssh
连接时经常发呆掉线,可以改一下sshd
:
vi /etc/ssh/sshd_config
找到并修改这两个参数:
ClientAliveInterval 30
ClientAliveCountMax 10000
然后重启下服务,可能需要登出登入下,大家自己试试,不是本文重点。
service sshd restart
接下里为了方便,修改下3个主机的名称,也就是hostname
,注意不是实例名称,实例名称只是用来管理实例的,如图:
image.png
当然也可以登录到服务器上用命令行来修改。最终把三台主机分别改成:
master
worker1
worker2
然后在3个服务器上都改一下hosts
文件,方便连接:
vi /etc/hosts
添加如下3行,填上服务器的内网IP,如图,顺序无所谓,为什么有两个master
也无所谓。
1.2 配置免密登录
至少master
要能免密ssh
登录到这3台服务器,自身也不例外,当然了3台互相免密访问就更方便传输文件了。配置过程就是生成密钥,然后添加到授权密钥里,并添加读写权限,先登录到master
上,这样:
[root@master ~]# ssh-keygen -t rsa # 一路回车即可
[root@master ~]# cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys # 用vi手动添加也可以
[root@master ~]# chmod 0600 ~/.ssh/authorized_keys
[root@master ~]# scp ~/.ssh/authorized_keys root@worker1:~/.ssh # 复制到worker1,第一次需要密码
[root@master ~]# scp ~/.ssh/authorized_keys root@worker2:~/.ssh # 复制到worker2,第一次需要密码
测试一下,看看能否免密登录。
[root@master ~]# ssh localhost
[root@master ~]# ssh worker1
[root@master ~]# ssh worker2
官网也有介绍,如图,可以参考下。
如果你希望
worker1
也能免密登录master
、worker2
,那就需要同样生成密钥,追加到被登录服务器的authorized_keys
里,自行尝试。
1.3 关闭防火墙
这可能是坑,所以提前做好以防万一,不过阿里云ECS好像默认都已经关了。3台服务器上都查看下防火墙状态:
[root@master ~]# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
Active: inactive (dead)
Docs: man:firewalld(1)
如果开着,就禁用firewalld
:
[root@master ~]# systemctl disable --now firewalld
再查看SELinux
状态,
[root@master ~]# getenforce
Disabled
如果开着,就禁用SELinux
:
[root@master ~]# setenforce 0
setenforce: SELinux is disabled
1.4 其它
刚才的操作都是在root
下的,有的教程会建议专门建个Hadoop
用户,对于初学者可能不必要,也简单说下。比如新建用户名叫hadoopuser
,密码自己定。
sudo adduser hadoopuser
passwd hadoopuser # 设定密码
sudo usermod -aG wheel hadoop # 加入wheel组,相当于一个管理员组
切换到新用户,并生成ssh-key
,用于免密访问。
su - hadoopuser # 切换到hadoopuser
ssh-keygen -t rsa
然后把公钥添加到授权密钥里,并添加读写权限,这样:
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys # 用vi手动添加也可以
chmod 0600 ~/.ssh/authorized_keys
然后测试一下,是否能够免密登录本地。
ssh localhost
其它类似,有时候操作会需要sudo
。
2 安装Java
我是没想到装Java
也能有坑,慢慢来。本文将要安装Hadoop 3.1.2
,只支持Java8
,可以参考官网Java版本说明,我当时就是没看这个不信邪,吃了大亏,折腾了很久。
有的
CentOS
可能自带jdk
,先查看一下:
rpm -qa|grep jdk
如果有乱七八糟的,可以卸载,比如:
rpm -e --nodeps java-1.8.0-openjdk-headless-1.8.0.181-7.b13.el7.x86_64
rpm -e --nodeps ......
我觉得不卸载也没关系,反正还要装新的,这个坑留给读者踩一踩。有的教程使用yum
安装,直接这样:
yum -y install java-1.8.0-openjdk java-1.8.0-openjdk-devel
这样安装的是开源简化的OpenJDK
,没什么问题,不过我还是想去装个官网的完整的。先找安装包地址,首先来到Java官网,转了半天没找到选择各种系统各种版本的链接,掉头去了Oracle官网,找到Java 8
。装tar.gz
还是rpm
呢?前者得自己找目录解压,所以我选择了rpm
,系统自动帮我安排得明明白白就行。如图:
点击后居然需要注册,注册后开始下载,暂停下,把下载项的地址复制下来,使用
wget
下载到比如用户主目录:
[root@master ~]# wget https://download.oracle.com/otn/java/jdk/8u221-b11/230deb18db3e4014bb8e3e8324f81b43/jdk-8u221-linux-x64.rpm?AuthParam=1568257266_083ed48033f8bd09a12a1415367d9ea1
用mv
命令把后面没用的文件名删掉,然后安装:
[root@master ~]# rpm -ivh jdk-8u221-linux-x64.rpm
如果配置好了环境变量$PATH
,可以测试下:
[root@master ~]# java -version
java version "1.8.0_221"
Java(TM) SE Runtime Environment (build 1.8.0_221-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.221-b11, mixed mode)
不过环境变量待会儿跟Hadoop
一起配置。
3 安装Hadoop
终于进入正题,先去Hadoop官网下载安装程序,点进去选择合适的版本镜像,本文选择3.1.2
,比如:
[root@master ~]# wget http://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/hadoop-3.1.2/hadoop-3.1.2.tar.gz
解压:
[root@master ~]# tar -zxvf hadoop-3.1.2.tar.gz
然后移到比如usr/local
目录,原压缩包可以删了。当然应该也可以直接下载到该目录再解压,权限不够就加上sudo
。现在设置环境变量:
[root@master ~]# vi /etc/profile
在最后添加如下:
export JAVA_HOME=/usr/java/jdk1.8.0_221-amd64 # 或者/usr/java/latest
export HADOOP_HOME=/usr/local/hadoop-3.1.2
export HADOOP_HDFS_HOME=$HADOOP_HOME
export HADOOP_MAPRED_HOME=$HADOOP_HOME
export YARN_HOME=$HADOOP_HOME
export HADOOP_COMMON_HOME=$HADOOP_HOME
export HADOOP_COMMON_LIB_NATIVE_DIR=$HADOOP_HOME/lib/native
export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
生效一下:
[root@master ~]# source /etc/profile
注意,生效了这几行也别删掉,不然重启就没了。另外,也别重复source
,不然那个PATH
就会重复调用自己越来越长。运行Hadoop
查看版本试试:
[root@master java]# hadoop version
Hadoop 3.1.2
Source code repository https://github.com/apache/hadoop.git -r 1019dde65bcf12e05ef48ac71e84550d589e5d9a
Compiled by sunilg on 2019-01-29T01:39Z
Compiled with protoc 2.5.0
From source with checksum 64b8bdd4ca6e77cce75a93eb09ab2a9
This command was run using /usr/local/hadoop-3.1.2/share/hadoop/common/hadoop-common-3.1.2.jar
# which hadoop
/usr/local/hadoop-3.1.2/bin/hadoop
没什么问题。那么3个服务器都这么安装配置Java和Hadoop!
4 配置Hadoop
继续配置Hadoop
环境,重要的配置基本都在$HADOOP_HOME/etc/hadoop/
目录下。
4.1 配置hadoop-env.sh
首先配置hadoop
环境:
[root@master hadoop]# vi hadoop-env.sh
找一下,大概在第54行,至少把JAVA_HOME
给配置了,这个很重要。
# The java implementation to use. By default, this environment
# variable is REQUIRED on ALL platforms except OS X!
export JAVA_HOME=/usr/java/latest
最后还需要加上:
export HDFS_NAMENODE_USER=root
export HDFS_DATANODE_USER=root
export HDFS_SECONDARYNAMENODE_USER=root
export YARN_RESOURCEMANAGER_USER=root
export YARN_NODEMANAGER_USER=root
4.2 配置core-site.xml
这里定义了一些全局参数,
[root@master hadoop]# vi core-site.xml
配置如下:
<configuration>
<property>
<name>fs.default.name</name>
<value>hdfs://master:9000</value>
<description>文件系统URL,3个一样</description>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/hadoop</value>
<description>临时文件目录,可能不配也行</description>
</property>
</configuration>
4.3 配置hdfs-site.xml
配置HDFS
参数,把SecondaryNameNode
配置在worker1
上。
<configuration>
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>worker1:50090</value>
<description>Secondary名称节点的URL</description>
</property>
<property>
<name>dfs.namenode.secondary.https-address</name>
<value>worker1:50091</value>
<description>这个可能不需要</description>
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>/opt/hadoop/dfs/name</value>
<description>名称节点文件位置</description>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>/opt/hadoop/dfs/data</value>
<description>数据节点文件位置</description>
</property>
<property>
<name>dfs.replication</name>
<value>2</value>
<description>每个文件复制2块</description>
</property>
</configuration>
4.4 配置yarn-site.xml
也就是配置资源管理器,
<configuration>
<!-- Site specific YARN configuration properties -->
<property>
<name>yarn.resourcemanager.hostname</name>
<value>worker1</value>
<description>官网建议把namenode和resourcemanager分在两个机器上配置,其实配成master也没关系</description>
</property>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
<description>配置NodeManager上运行的附属服务为mapreduce_shuffle,才可运行MapReduce程序</description>
</property>
</configuration>
4.5 配置mapred-site.xml
配置MapReduce
参数,
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
<description>选择用yarn来管理</description>
</property>
<property>
<name>yarn.app.mapreduce.am.env</name>
<value>HADOOP_MAPRED_HOME=/usr/local/hadoop-3.1.2</value>
</property>
<property>
<name>mapreduce.map.env</name>
<value>HADOOP_MAPRED_HOME=/usr/local/hadoop-3.1.2</value>
</property>
<property>
<name>mapreduce.reduce.env</name>
<value>HADOOP_MAPRED_HOME=/usr/local/hadoop-3.1.2</value>
</property>
<property>
<name>mapreduce.application.classpath</name>
<value>$HADOOP_MAPRED_HOME/share/hadoop/mapreduce/*,$HADOOP_MAPRED_HOME/share/hadoop/mapreduce/lib/*,$HADOOP_MAPRED_HOME/share/hadoop/common/*,$HADOOP_MAPRED_HOME/share/hadoop/common/lib/*,$HADOOP_MAPRED_HOME/share/hadoop/yarn/*,$HADOOP_MAPRED_HOME/share/hadoop/yarn/lib/*,$HADOOP_MAPRED_HOME/share/hadoop/hdfs/*,$HADOOP_MAPRED_HOME/share/hadoop/hdfs/lib/*</value>
</property>
</configuration>
4.6 其它配置
在当前目录的workers
文件里添加节点,注意,这个文件以前叫slavers
,另外现在好像也不用添加masters
文件了。
[root@master hadoop]# vi workers
worker1
worker2
目前都是在master
进行配置,把这个配置目录,复制到worker1
和worker2
。
scp $HADOOP_HOME/etc/hadoop/* root@worker1:$HADOOP_HOME/etc/hadoop/
scp $HADOOP_HOME/etc/hadoop/* root@worker2:$HADOOP_HOME/etc/hadoop/
5 Hadoop的启动与停止
5.1 启动NameNode和DataNode
第一次跑,先格式化HDFS
。
[root@master ~]# hdfs namenode -format
然后启动NameNode和DataNode,
[root@master ~]# hdfs --daemon start namenode
[root@master ~]# hdfs --daemon start datanode
当然也可以直接用一个脚本启动,
[root@master ~]# start-dfs.sh
看看启动后的结果,发现节点都正常启动了。
[root@master ~]# jps
20720 NameNode
21089 Jps
...
[root@worker1 ~]# jps
17889 SecondaryNameNode
17991 Jps
17771 DataNode
...
[root@worker2 ~]# jps
17288 DataNode
17438 Jps
如果没有正常启动,一定去相应的节点看日志文件,比如有一次启动的时候DataNode
没有起来,就去worker1
看了下:
[root@worker1 ~]# cd $HADOOP_HOME/logs
[root@worker1 logs]# tail -100 hadoop-root-datanode-worker1.log
发现由于多次格式化,导致什么ID不一致,java.io.IOException: Incompatible clusterIDs
,于是进入2个数据节点的HDFS
文件目录,删除了,回到master
重新格式化,搞定。
[root@worker1 ~]# cd /opt/hadoop/dfs/
[root@worker2 dfs]# rm -rf data/
5.2 启动ResourceManager和HistoryServer
接下来启动yarn
,记住,得去worker1
去启动ResourceManager
。所以还挺不方便的,还不如就放在master
上呢。
[root@worker1~]# yarn --daemon start resourcemanager
去master
启动nodemanager
,这个其实随便去哪个节点都能启动,只是因为我们之前只配置了master
到所有节点的免密登录。
[root@master ~]# yarn --daemon start nodemanager
当然也可以在worker1
上直接用一个脚本启动,不过这就需要配齐免密登陆了,
[root@worker1~]# start-yarn.sh
另外,dfs
和yarn
也可以用一个start-all.sh
合并启动。
真绕啊,我后悔了,应该把ResourceManager
也放到master
上。
还有个MapReduce JobHistory Server
启动一下,可以查看历史任务,这个随便在那个节点都能启动。
[root@master ~]# mapred --daemon start historyserver
最终看看3个服务器起来的程序。
[root@master ~]# jps
20720 NameNode
22234 Jps
22475 JobHistoryServer
...
[root@worker1 ~]# jps
17889 SecondaryNameNode
18882 ResourceManager
18482 NodeManager
19544 Jps
17771 DataNode
...
[root@worker2 ~]# jps
18464 Jps
17288 DataNode
17896 NodeManager
把之前启动命令的start
都改成stop
,就变成停止。
5.3 网页管理页面
先用netstat
命令查看开放的端口。注意,如果Hadoop
不是3.1.2
版本,端口号可能不同,读者自行确认。先看master
:
可以访问9870查看NameNode:
image.png
可以访问19888查看历史任务:
image.png
再看
worker1
:image.png
访问8088端口进行资源管理:
image.png
对了,要提前去阿里云控制台配置安全组规则,把端口开放,不然无法访问。如图:
image.png
6 运行WordCount例子
可以在master
上运行,建立文件夹,并复制了一些xml
文件,然后计数并输出到output目录。
[root@master ~]# cd $HADOOP_HOME/
[root@master hadoop-3.1.2]# hdfs dfs -mkdir -p /wordcount/input
[root@master hadoop-3.1.2]# hdfs dfs -put etc/hadoop/*.xml /wordcount/input
[root@master hadoop-3.1.2]# cd share/hadoop/mapreduce/
[root@master mapreduce]# hadoop jar hadoop-mapreduce-examples-3.1.2.jar wordcount /wordcount/input/*.xml output # 猜测:这个output目录如果不指定绝对路径,就会在hdfs的/user/root下。
查看下结果:
[root@master mapreduce]# hdfs dfs -ls /user/root/output
Found 2 items
-rw-r--r-- 2 root supergroup 0 2019-09-12 16:45 /user/root/output/_SUCCESS
-rw-r--r-- 2 root supergroup 10783 2019-09-12 16:45 /user/root/output/part-r-00000
当然也可以拉到本地查看:
[root@master ~]# hdfs dfs -get output localout
[root@master ~]# ll
total 4
drwxr-xr-x 2 root root 4096 Sep 12 16:50 localout
如果运行的时候,卡住了怎么办?可以先把日志等级改一下,看看调试信息,这样:
[root@master ~]# export HADOOP_ROOT_LOGGER=DEBUG,console
如果是由于安全模式导致某个文件无法删除,先退出安全模式即可。
[root@master ~]# hdfs dfsadmin -safemode leave
如果还有其它问题,就查看日志排查。
7 其它
7.1 为Hadoop专门配数据盘
这部分可以跳过,参考了这篇的内容,其实没有必要,先买个盘,如图:
在挂载数据盘之前,先查看当前磁盘,可以看到只有一个盘
vda
。
[root@master ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sr0 11:0 1 1024M 0 rom
vda 253:0 0 40G 0 disk
└─vda1 253:1 0 40G 0 part /
然后在阿里云控制台把数据盘挂载到当前ECS实例上,就多了一个vdb
。
[root@master ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sr0 11:0 1 1024M 0 rom
vda 253:0 0 40G 0 disk
└─vda1 253:1 0 40G 0 part /
vdb 253:16 0 20G 0 disk
通过如下操作,把这个磁盘分区并挂载到/hadoop
目录下。
sudo parted -s -- /dev/vdb mklabel gpt # 创建空磁盘分区表
sudo parted -s -a optimal -- /dev/vdb mkpart primary 0% 100% # 分区
sudo parted -s -- /dev/vdb align-check optimal 1 # 检查分区是否对齐
sudo mkfs.xfs /dev/vdb1 # 格式化
sudo mkdir /hadoop
echo "/dev/vdb1 /hadoop xfs defaults 0 0" | sudo tee -a /etc/fstab # 写入分区表
sudo mount -a # 根据分区表挂载
最后再看结果,新盘已经挂载到/hadoop
点上了。
[root@master ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sr0 11:0 1 1024M 0 rom
vda 253:0 0 40G 0 disk
└─vda1 253:1 0 40G 0 part /
vdb 253:16 0 20G 0 disk
└─vdb1 253:17 0 20G 0 part /hadoop
当然通过df
命令也能看,不赘述。记得配置hdfs.xml
时,把参数设置到这个目录下。
7.2 为Hadoop专门配置用户
刚才所有操作都是root
用户,一些教程会专门建用户管理运行Hadoop
,官网也这么建议:
In general, it is recommended that HDFS and YARN run as separate users. In the majority of installations, HDFS processes execute as ‘hdfs’. YARN is typically using the ‘yarn’ account.
其实也不复杂,常用的如下:
sudo adduser hadoopuser
passwd hadoopuser # 设定密码
sudo usermod -aG wheel hadoop # 加入wheel组,相当于一个管理员组
su - hadoopuser # 切换到hadoopuser
chown -R hadoopuser:hadoopuser /testdir
比如HDFS
的根目录就需要赋权限,可能需要sudo
,权限问题是常见的坑。
7.3 其它坑
有一次发现ResourceManager
、NodeManager
启动不了,去/usr/local/hadoop-3.1.2/logs
目录下看日志(这是个好习惯!),发现类似java.lang.ClassNotFoundException: javax.activation.DataSource
这样的错误。搜了不少地方,都说是JDK
太新,默认禁用访问许多javax. * API
,后来换为Java 8
就好了。
8 参考
前前后后看了很多,加一些踩坑排错,看得比较多的几个列一下。
Hadoop官网
How to Install Apache Hadoop / HBase on CentOS 7
用阿里云搭建Hadoop集群
搭建云服务器Hadoop集群/伪分布
安装hadoop3.0版本踩坑
MapReduce wordcount测试卡死在running job
Stackoverflow
网友评论