Skip to content

hadoop

目录


内容不包含:Linux 基础知识的讲解

安装

添加 hadoop 用户

如果你安装 Ubuntu 的时候不是用的 “hadoop” 用户,那么需要增加一个名为 hadoop 的用户。

bash
# 创建 hadoop 用户
sudo useradd -m hadoop -s /bin/bash
# 设置 hadoop 用户密码
sudo passwd hadoop
# 为 hadoop 用户增加管理员权限
sudo adduser hadoop sudo

为什么要使用名为 hadoop 的用户来管理 hadoop 在 Linux 系统中,使用特定的用户来运行和管理特定的服务是一种常见的最佳实践。这样做有以下几个原因:

  • 安全性:每个用户都有自己的权限和访问控制,这样可以防止未经授权的用户访问或修改 Hadoop 的数据和配置。
  • 隔离性:使用特定的用户可以将 Hadoop 的运行环境与其他服务分开,避免相互干扰。
  • 易于管理:如果 Hadoop 服务有问题,可以直接查看 hadoop 用户的进程和日志,方便进行故障排查。

在这段代码中,首先使用 useradd 命令创建了一个名为 hadoop 的新用户,然后设置了该用户的密码,最后使用 adduser 命令将 hadoop 用户添加到 sudo 组,赋予了其管理员权限。这样,hadoop 用户就可以执行需要 root 权限的命令,如安装软件、修改系统配置等。

安装基础软件

bash
sudo apt update
sudo apt upgrade
sudo apt install vim openssh-server -y

apt 和 apt-get 的区别

apt 和 apt-get 都是 Ubuntu 系统中用于管理软件包的命令行工具,它们的功能基本相同,但有一些细微的区别:

  • apt 是 apt-get 的一个高级封装,提供了更多的功能和友好的输出格式。
  • apt-get 是 apt 的底层工具,可以通过 apt-get 命令执行 apt 不支持的操作。
  • apt-get 命令的输出更加详细,适合在调试时使用。
  • apt 命令的输出更加简洁,适合在日常使用时使用。

配置 SSH 无密码登陆

使用 ssh 连接本机

bash
ssh localhost

为什么使用 hadoop 要使用 ssh 连接本机使用?

Hadoop 集群中的各个节点需要通过 SSH 进行通信。在单机模式下,Hadoop 也需要通过 SSH 连接到本机,以启动和管理 Hadoop 的各个组件。

这是因为 Hadoop 的设计是为了在分布式环境中运行的,即使在单机模式下,它也会模拟分布式环境的行为。通过 SSH 连接到本机,Hadoop 可以启动和停止各个组件,就像在真正的分布式环境中一样。

此外,使用 SSH 还可以提供一种安全的通信方式,因为 SSH 提供了数据加密和用户身份验证等功能。

配置 ssh 无密码登陆

bash
exit                           # 退出刚才的 ssh localhost
cd ~/.ssh/                     # 若没有该目录,请先执行一次ssh localhost
ssh-keygen -t rsa              # 会有提示,都按回车就可以
cat ./id_rsa.pub >> ./authorized_keys  # 加入授权

安装 Java

Hadoop3.1.3 需要 JDK 版本在 1.8 及以上。需要按照下面步骤来自己手动安装 JDK1.8。

bash
cd /usr/lib
sudo mkdir jvm #创建/usr/lib/jvm目录用来存放JDK文件
cd ~ #进入hadoop用户的主目录
cd Downloads  #注意区分大小写字母,刚才已经通过FTP软件把JDK安装包jdk-8u162-linux-x64.tar.gz上传到该目录下
sudo tar -zxvf ./jdk-8u162-linux-x64.tar.gz -C /usr/lib/jvm  #把JDK文件解压到/usr/lib/jvm目录下

## JDK文件解压缩以后,可以执行如下命令到/usr/lib/jvm目录查看一下
cd /usr/lib/jvm
ls

## 设置环境变量
cd ~
vim .bashrc

在 .bashrc 文件中添加如下内容:

bash
export JAVA_HOME=/usr/lib/jvm/jdk1.8.0_162
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH

保存退出后,执行如下命令使环境变量生效:

bash
source ~/.bashrc

## 验证是否安装成功
java -version

安装 hadoop

Hadoop 安装文件,可以到 Hadoop 官网下载hadoop-3.1.3.tar.gz

bash
sudo tar -zxf ~/下载/hadoop-3.1.3.tar.gz -C /usr/local    # 解压到/usr/local中
cd /usr/local/
sudo mv ./hadoop-3.1.3/ ./hadoop            # 将文件夹名改为hadoop
sudo chown -R hadoop ./hadoop       # 修改文件权限

Hadoop 解压后即可使用。输入如下命令来检查 Hadoop 是否可用,成功则会显示 Hadoop 版本信息:

bash
cd /usr/local/hadoop
./bin/hadoop version
# Hadoop 3.1.3
# Source code repository https://gitbox.apache.org/repos/asf/hadoop.git -r ba631c436b806728f8ec2f54ab1e289526c90579
# Compiled by ztang on 2019-09-12T02:47Z
# Compiled with protoc 2.5.0
# From source with checksum ec785077c385118ac91aadde5ec9799
# This command was run using /usr/local/hadoop/share/hadoop/common/hadoop-common-3.1.3.jar

Hadoop 单机配置(非分布式)

Hadoop 默认模式为非分布式模式(本地模式),无需进行其他配置即可运行。非分布式即单 Java 进程,方便进行调试。 现在我们可以执行例子来感受下 Hadoop 的运行。Hadoop 附带了丰富的例子(运行./bin/hadoop jar ./share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar 可以看到所有例子),包括 wordcount、terasort、join、grep 等。

在此我们选择运行 grep 例子,我们将 input 文件夹中的所有文件作为输入,筛选当中符合正则表达式 dfs[a-z.]+ 的单词并统计出现的次数,最后输出结果到 output 文件夹中。

bash
cd /usr/local/hadoop
mkdir ./input
cp ./etc/hadoop/*.xml ./input   # 将配置文件作为输入文件
./bin/hadoop jar ./share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar grep ./input ./output 'dfs[a-z.]+'
cat ./output/*          # 查看运行结果

注意,Hadoop 默认不会覆盖结果文件,因此再次运行上面实例会提示出错,需要先将  ./output  删除。

Hadoop 伪分布式配置

Hadoop 可以在单节点上以伪分布式的方式运行,Hadoop 进程以分离的 Java 进程来运行,节点既作为 NameNode 也作为 DataNode,同时,读取的是 HDFS 中的文件。

Hadoop 的配置文件位于 /usr/local/hadoop/etc/hadoop/ 中,伪分布式需要修改 2 个配置文件  core-site.xml  和  hdfs-site.xml 。Hadoop 的配置文件是 xml 格式,每个配置以声明 property 的 name 和 value 的方式来实现。

修改配置文件  core-site.xml (通过 gedit 编辑会比较方便: gedit ./etc/hadoop/core-site.xml),将当中的

xml
<configuration>
</configuration>

修改为:

xml
<configuration>
    <property>
       <name>hadoop.tmp.dir</name>
        <value>file:/usr/local/hadoop/tmp</value>
        <description>Abase for other temporary directories.</description>
    </property>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://localhost:9000</value>
    </property>
</configuration>

同样的,修改配置文件  hdfs-site.xml:

xml
<configuration>
    <property>
        <name>dfs.replication</name>
        <value>1</value>
    </property>
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>file:/usr/local/hadoop/tmp/dfs/name</value>
    </property>
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>file:/usr/local/hadoop/tmp/dfs/data</value>
    </property>
</configuration>

Hadoop 的运行方式是由配置文件决定的(运行 Hadoop 时会读取配置文件),因此如果需要从伪分布式模式切换回非分布式模式,需要删除 core-site.xml 中的配置项。

此外,伪分布式虽然只需要配置 fs.defaultFS 和 dfs.replication 就可以运行(官方教程如此),不过若没有配置 hadoop.tmp.dir 参数,则默认使用的临时目录为 /tmp/hadoo-hadoop,而这个目录在重启时有可能被系统清理掉,导致必须重新执行 format 才行。所以我们进行了设置,同时也指定 dfs.namenode.name.dir 和 dfs.datanode.data.dir,否则在接下来的步骤中可能会出错。

配置完成后,执行 NameNode 的格式化:

bash
cd /usr/local/hadoop
./bin/hdfs namenode -format

成功的话,会看到 “successfully formatted” 的提示

2020-01-08 15:31:31,560 INFO namenode.NameNode: STARTUP_MSG:
/************************************************************

STARTUP_MSG: Starting NameNode
STARTUP_MSG:   host = hadoop/127.0.1.1
STARTUP_MSG:   args = [-format]
STARTUP_MSG:  version = 3.1.3
*************************************************************/

......
2020-01-08 15:31:35,677 INFO common.Storage: Storage directory /usr/local/hadoop/tmp/dfs/name **has been successfully formatted**.
2020-01-08 15:31:35,700 INFO namenode.FSImageFormatProtobuf: Saving image file /usr/local/hadoop/tmp/dfs/name/current/fsimage.ckpt_0000000000000000000 using no compression
2020-01-08 15:31:35,770 INFO namenode.FSImageFormatProtobuf: Image file /usr/local/hadoop/tmp/dfs/name/current/fsimage.ckpt_0000000000000000000 of size 393 bytes saved in 0 seconds .
2020-01-08 15:31:35,810 INFO namenode.NNStorageRetentionManager: Going to retain 1 images with txid >= 0
2020-01-08 15:31:35,816 INFO namenode.FSImage: FSImageSaver clean checkpoint: txid = 0 when meet shutdown.
2020-01-08 15:31:35,816 INFO namenode.NameNode: SHUTDOWN_MSG:
/************************************************************
SHUTDOWN_MSG: Shutting down NameNode at hadoop/127.0.1.1
*************************************************************/

接着开启 NameNode 和 DataNode 守护进程。

bash
cd /usr/local/hadoop
./sbin/start-dfs.sh

启动完成后,可以通过命令  jps  来判断是否成功启动,若成功启动则会列出如下进程: “NameNode”、”DataNode” 和 “SecondaryNameNode”(如果 SecondaryNameNode 没有启动,请运行 sbin/stop-dfs.sh 关闭进程,然后再次尝试启动尝试)。如果没有 NameNode 或 DataNode ,那就是配置不成功,请仔细检查之前步骤,或通过查看启动日志排查原因。

Hadoop 无法正常启动的解决方法

一般可以查看启动日志来排查原因,注意几点:

  • 启动时会提示形如 “DBLab-XMU: starting namenode, logging to /usr/local/hadoop/logs/hadoop-hadoop-namenode-DBLab-XMU.out”,其中 DBLab-XMU 对应你的机器名,但其实启动日志信息是记录在 /usr/local/hadoop/logs/hadoop-hadoop-namenode-DBLab-XMU.log 中,所以应该查看这个后缀为  .log  的文件;
  • 每一次的启动日志都是追加在日志文件之后,所以得拉到最后面看,对比下记录的时间就知道了。
  • 一般出错的提示在最后面,通常是写着 Fatal、Error、Warning 或者 Java Exception 的地方。
  • 可以在网上搜索一下出错信息,看能否找到一些相关的解决方法。

此外,若是 DataNode 没有启动,可尝试如下的方法(注意这会删除 HDFS 中原有的所有数据,如果原有的数据很重要请不要这样做):

bash
# 针对 DataNode 没法启动的解决方法
cd /usr/local/hadoop
./sbin/stop-dfs.sh   # 关闭
rm -r ./tmp     # 删除 tmp 文件,注意这会删除 HDFS 中原有的所有数据
./bin/hdfs namenode -format   # 重新格式化 NameNode
./sbin/start-dfs.sh  # 重启

成功启动后,可以访问 Web 界面  http://localhost:9870  查看 NameNode 和 Datanode 信息,还可以在线查看 HDFS 中的文件。

运行 Hadoop 伪分布式实例

上面的单机模式,grep 例子读取的是本地数据,伪分布式读取的则是 HDFS 上的数据。要使用 HDFS,首先需要在 HDFS 中创建用户目录:

bash
# 创建用户目录
./bin/hdfs dfs -mkdir -p /user/hadoop

教材《大数据技术原理与应用》的命令是以”./bin/hadoop dfs”开头的 Shell 命令方式,实际上有三种 shell 命令方式。

  1. hadoop fs
  2. hadoop dfs
  3. hdfs dfs

hadoop fs 适用于任何不同的文件系统,比如本地文件系统和 HDFS 文件系统

hadoop dfs 只能适用于 HDFS 文件系统

hdfs dfs 跟 hadoop dfs 的命令作用一样,也只能适用于 HDFS 文件系统

接着将 ./etc/hadoop 中的 xml 文件作为输入文件复制到分布式文件系统中,即将 /usr/local/hadoop/etc/hadoop 复制到分布式文件系统中的 /user/hadoop/input 中。我们使用的是 hadoop 用户,并且已创建相应的用户目录 /user/hadoop ,因此在命令中就可以使用相对路径如 input,其对应的绝对路径就是 /user/hadoop/input:

bash
# 复制配置文件到 HDFS
./bin/hdfs dfs -mkdir input
./bin/hdfs dfs -put ./etc/hadoop/*.xml input

复制完成后,可以通过如下命令查看文件列表:

bash
./bin/hdfs dfs -ls input
# Found 9 items
# -rw-r--r--   1 hadoop supergroup       8260 2024-04-10 11:44 input/capacity-scheduler.xml
# -rw-r--r--   1 hadoop supergroup       1075 2024-04-10 11:44 input/core-site.xml
# -rw-r--r--   1 hadoop supergroup      11392 2024-04-10 11:44 input/hadoop-policy.xml
# -rw-r--r--   1 hadoop supergroup       1133 2024-04-10 11:44 input/hdfs-site.xml
# -rw-r--r--   1 hadoop supergroup        620 2024-04-10 11:44 input/httpfs-site.xml
# -rw-r--r--   1 hadoop supergroup       3518 2024-04-10 11:44 input/kms-acls.xml
# -rw-r--r--   1 hadoop supergroup        682 2024-04-10 11:44 input/kms-site.xml
# -rw-r--r--   1 hadoop supergroup        758 2024-04-10 11:44 input/mapred-site.xml
# -rw-r--r--   1 hadoop supergroup        690 2024-04-10 11:44 input/yarn-site.xml

伪分布式运行 MapReduce 作业的方式跟单机模式相同,区别在于伪分布式读取的是 HDFS 中的文件(可以将单机步骤中创建的本地 input 文件夹,输出结果 output 文件夹都删掉来验证这一点)。

bash
# 运行 grep 例子
./bin/hadoop jar ./share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar grep input output 'dfs[a-z.]+'

运行完成后,可以通过如下命令查看运行结果:

bash
./bin/hdfs dfs -cat output/*
# 2024-04-10 12:18:28,448 INFO sasl.SaslDataTransferClient: SASL encryption trust check: localHostTrusted = false, remoteHostTrusted = false
# 1	dfsadmin
# 1	dfs.replication
# 1	dfs.namenode.name.dir
# 1	dfs.datanode.data.dir

取回结果文件到本地:

bash
# 先删除本地 output 文件夹
rm -rf output
# 取回结果文件
./bin/hdfs dfs -get output output
# 查看结果文件
cat output/*

若要再次运行 MapReduce 作业,需要先删除 output 文件夹:

bash
./bin/hdfs dfs -rm -r output

停止 Hadoop 伪分布式模式:

bash
./sbin/stop-dfs.sh

Copyright © 2022 田园幻想乡 浙ICP备2021038778号-1