CentOS 7 中配置 Hadoop 3.1.2 完全分布式

首先送上整个配置流程的思维导图

1. 配置 hosts、hostname

我这边有 1 个 master 主机,2 个 slave 主机,

3 台主机的 hosts 配置文件如下

[root@master .ssh]$ cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.199.201         master
192.168.199.202         slave1
192.168.199.203         slave2

master 的 hostname 是

$ cat /etc/hostname
master

slave1 的 hostname 是

$ cat /etc/slave1
master

slave2 的 hostname 是

$ cat /etc/slave2
master

2. 配置 SSH

2.1 安装 ssh(三个主机都要安装)
$ sudo yum install openssh-server
2.2 配置集群间 ssh 无密钥登陆

1) 首先在 master 上生成 ssh 公钥

$ ssh-keygen -t rsa

然后连续按 3 个回车即可。再到生成 ssh 密钥的目录下查看是否成功

[root@master hadoop]$ cd ~/.ssh
[root@master .ssh]$ ls
authorized_keys  id_rsa  id_rsa.pub  known_hosts

注意:若没有生成 authorized_keys 文件,需要自己手动创建,

2)然后将 id_rsa.pub 中的内容复制到 authorized_keys 文件中。

$ cat id_rsa.pub >> authorized_keys

3)最后将 authorized_keys 分发给另外两个节点

$ scp authorized_keys slave1:~/.ssh/
$ scp authorized_keys slave2:~/.ssh/

4)测试 ssh 无密登陆是否成功

[root@master .ssh]$ ssh master
Last login: Sat Mar 23 17:11:13 2019 from master
[root@master ~]$ exit
logout
Connection to master closed.
[root@master .ssh]$ ssh slave1
Last login: Sat Mar 23 17:04:46 2019 from master
[root@slave1 ~]$ exit
logout
Connection to slave1 closed.
[root@master .ssh]$ ssh slave2
Last login: Sat Mar 23 15:31:54 2019 from master
[root@slave2 ~]$ exit
logout
Connection to slave2 closed.

3. 配置 jdk(三台主机都要配置)

3.1 首先确认删除 centos 系统自带的 jdk
$ rpm -qa | grep java
python-javapackages-3.4.1-11.el7.noarch
tzdata-java-2018e-3.el7.noarch
javapackages-tools-3.4.1-11.el7.noarch
java-1.8.0-openjdk-1.8.0.102-4.b14.el7.x86_64
java-1.8.0-openjdk-headless-1.8.0.102-4.b14.el7.x86_64
  • rpm 是一种用于打包及安装工具
  • -q 代表 query,a 代表 all
  • grep: 用于文本搜索

名称里有 openjdk 的要删除

$ rpm -e --nodeps java-1.8.0-openjdk-1.8.0.102-4.b14.el7.x86_64
$ rpm -e --nodeps java-1.8.0-openjdk-headless-1.8.0.102-4.b14.el7.x86_64
3.2 安装 jdk

这里安装的是 jdk1.8

1)创建 jdk 环境的路径

$ mkdir /usr/local/java

2)将下载好的压缩包解压到指定路径

[root@master Downloads]# tar -zxvf jdk-8u201-linux-x64.tar.gz -C /usr/local/java/

3)配置 java 的环境变量

# vi /etc/profile
export JAVA_HOME=/usr/local/java/jdk1.8.0_201
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin

4)使配置生效

$ source /etc/profile

5)测试是否配置成功

$ java -version
java version "1.8.0_201"
Java(TM) SE Runtime Environment (build 1.8.0_201-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.201-b09, mixed mode)

4. 关闭防火墙(三个节点都关闭)

$ su firewall-cmd --state  查看防火墙状态
$ su systemctl stop firewalld.service  关闭防火墙
$ su systemctl disable firewalld.service  禁止开机时防火墙自启

5. 下载、解压 Hadoop(三台主机都要安装)

这里 下载 Hadoop 3.1.2 版本

5.1 创建 hadoop 目录
$ mkdir /usr/local/hadoop
5.2 解压 hadoop 压缩包到指定目录
$ tar -zxvf hadoop-3.1.2.tar.gz -C /usr/local/hadoop/

6. 修改配置文件(三台主机都要配置)

配置文件的路径在 /usr/local/hadoop/hadoop-3.1.2/etc/hadoop

1)hadoop-env.sh
$ vi /usr/local/hadoop/hadoop-3.1.2/etc/hadoop/hadoop-env.sh
加入这一行
export JAVA_HOME=/usr/local/java/jdk1.8.0_201
2)core-site.xml
<configuration>
    <!-- 指定 namenode 的通信地址 默认 8020 端口 -->
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://master/</value>
    </property>

    <!-- 指定 hadoop 运行时产生文件的存储路径 -->
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/usr/local/hadoop/hadoop-3.1.2/tmp</value>
    </property>
</configuration>
3)hdfs-site.xml
<configuration>
    
    <!-- namenode 上存储 hdfs 名字空间元数据-->
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>/usr/local/hadoop/hadoop-3.1.2/namenode</value>
    </property>

    <!-- datanode 上数据块的物理存储位置-->  
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>/usr/local/hadoop/hadoop-3.1.2/datanode</value>
    </property>

    <!-- 设置 hdfs 副本数量 -->
    <property>
        <name>dfs.replication</name>
        <value>1</value>
    </property>

</configuration>
4)mapred-site.xml
<configuration>

    <!-- 指定yarn运行-->
    <property>
        <name>mapreduce.framework.name</name
        <value>yarn</value>
    </property>

    <property>
        <name>yarn.app.mapreduce.am.env</name>
        <value>HADOOP_MAPRED_HOME=/usr/local/hadoop/hadoop-3.1.2</value>
    </property>

    <property>
        <name>mapreduce.map.env</name>
        <value>HADOOP_MAPRED_HOME=/usr/local/hadoop/hadoop-3.1.2</value>
    </property>

    <property>
        <name>mapreduce.reduce.env</name>
        <value>HADOOP_MAPRED_HOME=/usr/local/hadoop/hadoop-3.1.2</value>
    </property>

</configuration>
5)year-site.xml
<configuration>
<!-- Site specific YARN configuration properties -->
    <!-- 指定ResourceManager的地址 -->
    <property>
        <name>yarn.resourcemanager.hostname</name>
        <value>master</value>
    </property>

    <!-- reducer取数据的方式是mapreduce_shuffle -->  
    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>

</configuration>
6)workers
$ vi workers

添加如下内容
slave1
slave2
7)start-dfs.sh 和 stop-dfs.sh

这两个文件在 /usr/local/hadoop/hadoop-3.1.2/sbin/ 中,分别在 start-dfs.sh 和 stop-dfs.sh 中添加如下内容

HDFS_DATANODE_USER=root
HDFS_DATANODE_SECURE_USER=hdfs
HDFS_NAMENODE_USER=root
HDFS_SECONDARYNAMENODE_USER=root
8)start-yarn.sh 和 stop-yarn.sh

这两个文件在 /usr/local/hadoop/hadoop-3.1.2/sbin/ 中,分别在 start-yarn.sh 和 stop-yarn.sh 中添加如下内容

YARN_RESOURCEMANAGER_USER=root
HADOOP_SECURE_DN_USER=yarn
YARN_NODEMANAGER_USER=root
9)配置 hadoop 环境变量

/etc/profile 中添加如下内容

$ vi /etc/profile

export HADOOP_HOME=/usr/local/hadoop/hadoop-3.1.2
export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin

添加成功后

$ source /etc/profile

上面的操作要在每一个节点上都同步,但是一个一个的去编辑太麻烦了,可以用 scp 命令,在 master 节点编辑好之后,直接发送给 slave 节点

$ scp /usr/local/hadoop/hadoop-3.1.2/etc/hadoop/ slave1 /usr/local/hadoop/hadoop-3.1.2/etc/hadoop/

$ scp /usr/local/hadoop/hadoop-3.1.2/etc/hadoop/ slave2 /usr/local/hadoop/hadoop-3.1.2/etc/hadoop/

7. 启动 hadoop(在主节点上操作)

7.1 启动 hadoop 之前在 master 上 format 名称节点
$ cd /usr/local/hadoop/hadoop-3.1.2/bin
$ hdfs namenode -format

2019-03-23 19:47:19,332 INFO namenode.NameNode: STARTUP_MSG:
/************************************************************
STARTUP_MSG: Starting NameNode
STARTUP_MSG:   host = master/192.168.199.201
STARTUP_MSG:   args = [-format]
STARTUP_MSG:   version = 3.1.2
...此处省略很多日志信息
2019-03-23 19:47:21,670 INFO common.Storage: Storage directory /usr/local/hadoop/hadoop-3.1.2/namenode has been successfully formatted.
2019-03-23 19:47:21,692 INFO namenode.FSImageFormatProtobuf: Saving image file /usr/local/hadoop/hadoop-3.1.2/namenode/current/fsimage.ckpt_0000000000000000000 using no compression
2019-03-23 19:47:21,899 INFO namenode.FSImageFormatProtobuf: Image file /usr/local/hadoop/hadoop-3.1.2/namenode/current/fsimage.ckpt_0000000000000000000 of size 391 bytes saved in 0 seconds .
2019-03-23 19:47:21,933 INFO namenode.NNStorageRetentionManager: Going to retain 1 images with txid >= 0
2019-03-23 19:47:21,962 INFO namenode.NameNode: SHUTDOWN_MSG:
/************************************************************
SHUTDOWN_MSG: Shutting down NameNode at master/192.168.199.201

出现以下信息则说明 namenode 格式化成功

INFO common.Storage: Storage directory /usr/local/hadoop/hadoop-3.1.2/namenode has been successfully formatted.
7.2 在 master 节点上启动 hadoop 服务
$ start-all.sh

Starting namenodes on [master]
Last login: Sat Mar 23 19:42:41 CST 2019 on pts/1
Starting datanodes
Last login: Sat Mar 23 19:54:46 CST 2019 on pts/1
Starting secondary namenodes [master]
Last login: Sat Mar 23 19:54:49 CST 2019 on pts/1
Starting resourcemanager
Last login: Sat Mar 23 19:54:56 CST 2019 on pts/1
Starting nodemanagers
Last login: Sat Mar 23 19:55:11 CST 2019 on pts/1
7.3 查看 hadoop 服务是否启动成功

查看 master 节点

$ jps
39578 ResourceManager
39324 SecondaryNameNode
39933 Jps
39039 NameNode

查看 slave1 节点

$ jps
16000 Jps
15907 NodeManager
15780 DataNode

查看 slave2 节点

$ jps
15040 DataNode
15298 Jps
15167 NodeManager

当 3 台节点分别出现这些 java 进程,则 hadoop 启动成功

8. 运行 wordcount 示例

Wordcount 是 MapReduce 的示例程序,可以统计某个文件中,各个单词出现的次数。

8.1 在 hdfs 文件系统中创建存放被测试文件的目录 input
$ hadoop fs -mkdir /input
8.2 查看 input 目录是否创建成功
$ hadoop fs -ls -R /

drwxr-xr-x   - root supergroup          0 2019-03-23 20:06 /input
8.3 创建测试文件 test.txt 并上传到 hdfs 中

首先介绍一些 hdfs 常用的命令语句

列出 hdfs 下的文件
$ hadoop dfs -ls
列出 hdfs / 路径下的所有文件,文件夹  
$ hadoop dfs -ls -R /
创建目录 /input
$ hadoop dfs -mkdir /input
列出 hsfs 名为 input 的文件夹中的文件
$ hadoop dfs -ls input
将 test.txt 上传到 hdfs 中
$ hadoop fs -put /home/binguner/Desktop/test.txt /input
将 hsdf 中的 test.txt 文件保存到本地桌面文件夹
$ hadoop dfs -get /input/test.txt /home/binguenr/Desktop
删除 hdfs 上的 test.txt 文件
$ hadoop dfs -rmr /input/test.txt
查看 hdfs 下 input 文件夹中的内容
$ hadoop fs -cat input/*
进入安全模式
$ hadoop dfsadmin –safemode enter
退出安全模式
$ hadoop dfsadmin -safemode leave
报告 hdfs 的基本统计情况
$ hadoop dfsadmin -report

在 Desktop 下创建 test.txt

$ vi /home/binguner/Desktop/test.txt

hello world
hello hadoop

test.txt 上传到 hdfs 中

# hadoop fs -put /home/binguner/Desktop/test.txt /input
8.4 运行 wordcount 程序
$ hadoop jar /usr/local/hadoop/hadoop-3.1.2/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.2.jar wordcount /input /output

日志信息出现

INFO mapreduce.Job: Job job_1553342123652_0001 completed successfully

则运行成功

然后查看 hdfs 中新生成的文件

$ hadoop fs -ls -R /

drwxr-xr-x   - root supergroup          0 2019-03-23 20:11 /input
-rw-r--r--   1 root supergroup         25 2019-03-23 20:11 /input/test.txt
drwxr-xr-x   - root supergroup          0 2019-03-23 20:13 /output
-rw-r--r--   1 root supergroup          0 2019-03-23 20:13 /output/_SUCCESS
-rw-r--r--   1 root supergroup         25 2019-03-23 20:13 /output/part-r-00000
drwx------   - root supergroup          0 2019-03-23 20:12 /tmp
drwx------   - root supergroup          0 2019-03-23 20:12 /tmp/hadoop-yarn
drwx------   - root supergroup          0 2019-03-23 20:12 /tmp/hadoop-yarn/staging
drwxr-xr-x   - root supergroup          0 2019-03-23 20:12 /tmp/hadoop-yarn/staging/history
drwxrwxrwt   - root supergroup          0 2019-03-23 20:12 /tmp/hadoop-yarn/staging/history/done_intermediate
drwxrwx---   - root supergroup          0 2019-03-23 20:13 /tmp/hadoop-yarn/staging/history/done_intermediate/root
-rwxrwx---   1 root supergroup      22276 2019-03-23 20:13 /tmp/hadoop-yarn/staging/history/done_intermediate/root/job_1553342123652_0001-1553343159309-root-word+count-1553343194205-1-1-SUCCEEDED-default-1553343173503.jhist
-rwxrwx---   1 root supergroup        439 2019-03-23 20:13 /tmp/hadoop-yarn/staging/history/done_intermediate/root/job_1553342123652_0001.summary
-rwxrwx---   1 root supergroup     213381 2019-03-23 20:13 /tmp/hadoop-yarn/staging/history/done_intermediate/root/job_1553342123652_0001_conf.xml
drwx------   - root supergroup          0 2019-03-23 20:12 /tmp/hadoop-yarn/staging/root
drwx------   - root supergroup          0 2019-03-23 20:13 /tmp/hadoop-yarn/staging/root/.staging

/output/part-r-00000 里就是本次运行的结果

$ hadoop fs -cat /output/part-r-00000


hadoop  1
hello   2
world   1

Q&A

(1)运行 wordcount 时,出现错误 Error: Could not find or load main class.org.apache.hadoop.mapred.YarnChild.

检查 mapred-site.xml 文件配置

参考链接 1 参考链接 2

(2)启动 hadoop 时:Starting resourcemanager
ERROR: Attempting to launch yarn resourcemanager as root
ERROR: but there is no YARN_RESOURCEMANAGER_USER defined. Aborting launch.
Starting nodemanagers
ERROR: Attempting to launch yarn nodemanager as root
ERROR: but there is no YARN_NODEMANAGER_USER defined. Aborting launch.

编辑 start-yarn.sh 和 stop-yarn.sh,添加文章中提到的参数。

(3)启动 hadoop 时:Starting namenodes on [localhost]
ERROR: Attempting to launch hdfs namenode as root
ERROR: but there is no HDFS_NAMENODE_USER defined. Aborting launch.

编辑 start-dfs.sh 和 stop-dfs.sh,添加文章中提到的参数。

(4)启动 start-dfs.sh 后,节点中的 datanode 闪退

重复格式化导致出错,确认各个 xml 文件配置无误后,
删除 dfs.namenode.name.dir,dfs.datanode.data.dir,hadoop.tmp.dir 对应的文件夹后重新 format。

如果出现了其他奇奇怪怪的错误,去 logs 文件夹下查看出错的原因。

欢迎关注本文作者:

扫码关注并回复「干货」,获取我整理的千G Android、iOS、JavaWeb、大数据、人工智能等学习资源。