Hadoop 3.3.1 分布式集群部署

Hadoop 架构

Hadoop 的优点:

  • 存储和处理数据具有高可靠性。

  • 通过分布式集群分配数据,具有高扩展性。

  • 可以在节点间动态的移动数据,并保证各个节点的动态平衡,处理速度非常快,具有高效性。

  • 能够自动保存数据的多个副本,并且能够自动将失败的任务重新分配,具有高容错性。

Hadoop 的缺点:

  • 不适用低延迟数据访问。

  • 不能高效存储海量小文件。

  • 不支持多用户写入并任意修改文件。

HDFS

HDFS (Hadoop Distribute File System) 是一个高可靠、高吞吐量的分布式文件系统,采用 Master/Slave 架构:

NameNode(NN):集群的 Master 节点,负责存储文件的元数据,例如文件名、目录结构、文件属性(创建时间、副本数、权限)等,以及每个块列表所在的 DateNode 等。

SecondaryNameNode(2NN):辅助 NameNode 更好的工作,用来监控 HDFS 状态的辅助后台程序,每隔一段时间获取 HDFS 元数据快照。

DataNode(DN):集群的 Slave 节点,负责在本地文件系统存储文件块数据,以及块数据的校验。

MapReduce

MapReduce 是一个分布式的离线并行计算框架:

Yarn

Yarn 是负责作业调度和集群资源管理的框架。

*注:图中紫色部分为一个任务流程,蓝色部分为另外一个任务流程。

ResourceManager(RM):在整个集群中承担 Master 的角色。它负责整个系统的资源管理和分配,包括客户端请求、启动/监控 ApplicationMaster、监控 NodeManager、资源的分配调度。内部主要有两个核心组件:

  • Scheduler: 一个可插拔的插件。当 Clien 提交一个任务时,它会根据任务所需资源和集群当前资源状况进行分配。要注意的是 Scheduler 只进行资源分配,并不对任务的执行情况进行监控。

  • ApplicationsManager: 主要负责接收提交的作业、协商启动第一个 Contaniner 来执行特定 Application 对应的 ApplicationMaster、监控 ApplicationMaster 的运行状态,并在其失败后重新启动它等。

ApplicationMaster(AM):每当 Client 提交一个 Application,就会初始化一个 ApplicationMaster,ApplicationMaster 负责向 Scheduler 申请适当的资源创建 Contaniner,随后将要运行的程序发送到该 Container 上启动,进行分布式计算。在此过程中,ApplicationMaster 还要时刻跟踪作业的状态并监视进度。是不是有些费解,为什么要把应用程序分发到容器上运行呢?在传统系统架构中,数据可以在各个应用中轻松流转,但是到了大数据的范畴,海量数据移动带来的成本是难以接受的,正所谓山不向我走来,我便向山走去,既然数据难以移动,我就让应用程序流动起来,只有真正理解这一点,你才能更好的理解大数据的架构。

NodeManager(NM):在整个集群中承担 Slave 的角色。它负责监控每台机器上物理资源(cpu、memory、disk、network)的使用情况以及向 ResourceManager/Scheduler 上报这些内容。

以紫色任务为例,客户端任务提交流程如下:

  1. Client 向 ResourceManager 提交一个 Application。

  2. ResourceManager 向有空闲资源的 NodeManager 发出指令为 Application 分配第一个容器,并在这个容器内启动该应用对应的 ApplicationMaster。

  3. ApplicationMaster 启动后将作业(也就是 Application)拆分成若干个 Task,这些 Task 可以运行在一个或多个容器中,然后向 ResourceManager 申请要运行程序的容器,并定时向 ResourceManager 发送心跳。

  4. 申请到容器后,ApplicationMaster 会去和容器对应的 NodeManager 通信,而后将作业分发到对应的 NodeManager 中的容器去运行,这里会将拆分后的 MapReduce 进行分发,对应容器中运行的可能是 Map 任务,也可能是 Reduce 任务。

  5. 容器中运行的任务会向 ApplicationMaster 发送心跳,汇报自身情况。当程序运行完成后, ApplicationMaster 再向 ResourceManager 注销并释放容器资源。

集群搭建

集群规划

安装准备

在三台机器上均准备以下内容:

  • Java
    install.sh shell
    yum -y install java-1.8.0-openjdk java-1.8.0-openjdk-devel
    echo "export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.312.b07-1.el7_9.x86_64" >> ~/.bashrc
    source ~/.bashrc
    
  • Hadoop
    code shell
    wget https://dlcdn.apache.org/hadoop/common/hadoop-3.3.1/hadoop-3.3.1.tar.gz --no-check-certificate -O /download/hadoop-3.3.1.tar.gz
    tar -xvf hadoop-3.3.1.tar.gz -C /opt/
    

验证:

code shell-session
[root@dell /]# /opt/hadoop-3.3.1/bin/hadoop version
Hadoop 3.3.1
Source code repository https://github.com/apache/hadoop.git -r a3b9c37a397ad4188041dd80621bdeefc46885f2
Compiled by ubuntu on 2021-06-15T05:13Z
Compiled with protoc 3.7.1
From source with checksum 88a4ddb2299aca054416d6b7f81ca55
This command was run using /opt/hadoop-3.3.1/share/hadoop/common/hadoop-common-3.3.1.jar
[root@dell /]# echo $JAVA_HOME
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.312.b07-1.el7_9.x86_64
[root@dell /]# java -version
openjdk version "1.8.0_312"
OpenJDK Runtime Environment (build 1.8.0_312-b07)
OpenJDK 64-Bit Server VM (build 25.312-b07, mixed mode)
[root@dell /]# javac -version
javac 1.8.0_312

HDFS 配置

Hadoop 的配置均在 /opt/hadoop-3.3.1/etc/hadoop 目录下,下文 shell 环境当前目录均为此目录。

  1. 配置所使用的 JDK 路径

因为在上一节安装 java 的时候已经配置了环境变量 JAVA_HOME,所以此步骤可以省略,但如果你需要指定另外的 jdk 给 hadoop 使用,则需要编辑 hadoop-env.sh 指定路径。

code shell
vi hadoop-env.sh

  1. 指定 NameNode 节点以及存储目录

文档:core-default.xml

code shell
mkdir -p /data/hadoop
<configuration>
  <!-- 指定 HDFS 集群 NameNode 地址 -->
  <property>
    <name>fs.defaultFS</name>
    <value>hdfs://192.168.8.9:9000</value>
  </property>
  <!-- 指定 Hadoop 运行时产生文件的存储目录 -->
  <property>
    <name>hadoop.tmp.dir</name>
    <value>/data/hadoop</value>
  </property>
</configuration>
  1. 指定 SecondaryNameNode 节点

文档:hdfs-default.xml

<configuration>
  <!-- 指定 HDFS 集群辅助节点 SecondaryNameNode 地址 -->
  <property>
    <name>dfs.namenode.secondary.http-address</name>
    <value>192.168.8.60:50090</value>
  </property>
  <!-- 副本数量 -->
  <property>
    <name>dfs.replication</name>
    <value>3</value>
  </property>
</configuration>
  1. 指定 DataNode 节点
workers text
192.168.8.8
192.168.8.9
192.168.8.60

MapReduce 配置

文档:mapred-default.xml

code shell
# 在 hadoop-env.sh 最后追加 Hadoop 路径
echo export HADOOP_HOME=/opt/hadoop-3.3.1 >> hadoop-env.sh
<configuration>
  <!-- 指定 MapReduce 运行在 Yarn 上 -->
  <property>
    <name>mapreduce.framework.name</name>
    <value>yarn</value>
  </property>
  <!-- 历史记录服务地址 -->
  <property>
    <name>mapreduce.jobhistory.address</name>
    <value>192.168.8.9:10020</value>
  </property>
  <!-- 历史记录服务 web 地址 -->
  <property>
    <name>mapreduce.jobhistory.webapp.address</name>
    <value>192.168.8.9:19888</value>
  </property>
  <property>
    <name>yarn.app.mapreduce.am.env</name>
    <value>HADOOP_MAPRED_HOME=$HADOOP_HOME</value>
  </property>
  <property>
    <name>mapreduce.map.env</name>
    <value>HADOOP_MAPRED_HOME=$HADOOP_HOME</value>
  </property>
  <property>
    <name>mapreduce.reduce.env</name>
    <value>HADOOP_MAPRED_HOME=$HADOOP_HOME</value>
  </property>
</configuration>

Yarn 配置

文档:yarn-default.xml

<configuration>
  <!-- 指定 Yarn 集群的 ResourceManager 地址 -->
  <property>
    <name>yarn.resourcemanager.hostname</name>
    <value>192.168.8.9</value>
  </property>
  <!-- Reduce 获取数据的方式 -->
  <property>
    <name>yarn.nodemanager.aux-services</name>
    <value>mapreduce_shuffle</value>
  </property>
  <!-- 日志地址 -->
  <property>
    <name>yarn.log.server.url</name>
    <value>http://192.168.8.9:19888/jobhistory/logs</value>
  </property>
  <!-- 开启日志聚集 -->
  <property>
    <name>yarn.log-aggregation-enable</name>
    <value>true</value>
  </property>
  <!-- 设置日志保留 7 天 -->
  <property>
    <name>yarn.log-aggregation.retain-seconds</name>
    <value>604800</value>
  </property>
</configuration>

格式化 NameNode

只有在集群第一次启动时才需要格式化操作!!!之后千万不要再重复执行!!!

192.168.8.9 shell
bin/hadoop namenode -format

格式化成功后目录结构如下:

192.168.8.9 shell-session
[root@dell hadoop-3.3.1]# tree /data/hadoop
/data/hadoop
└── dfs
    └── name
        └── current
            ├── fsimage_0000000000000000000
            ├── fsimage_0000000000000000000.md5
            ├── seen_txid
            └── VERSION

3 directories, 4 files

单独启动

192.168.8.9 shell-session
[root@dell hadoop-3.3.1]# bin/hdfs --daemon start namenode
[root@dell hadoop-3.3.1]# bin/hdfs --daemon start datanode
[root@dell hadoop-3.3.1]# bin/yarn --daemon start resourcemanager
[root@dell hadoop-3.3.1]# bin/yarn --daemon start nodemanager
[root@dell hadoop-3.3.1]# jps
26673 Jps
23366 ResourceManager
4634 DataNode
4349 NameNode
26542 NodeManager
192.168.8.8 shell-session
[root@nuc hadoop-3.3.1]# bin/hdfs --daemon start datanode
[root@nuc hadoop-3.3.1]# bin/yarn --daemon start nodemanager
[root@nuc hadoop-3.3.1]# jps
1673 NodeManager
362 DataNode
1852 Jps
192.168.8.60 shell-session
[root@g4 hadoop-3.3.1]# bin/hdfs --daemon start secondarynamenode
[root@g4 hadoop-3.3.1]# bin/hdfs --daemon start datanode
[root@g4 hadoop-3.3.1]# bin/yarn --daemon start nodemanager
[root@g4 hadoop-3.3.1]# jps
7649 NodeManager
9842 Jps
6119 DataNode
9785 SecondaryNameNode

群起

群起是 Hadoop 脚本通过 ssh 将命令批量发送至各个节点进行启动的,所以在群起之前需要保证各个节点可以通过 ssh 正常访问。

在启动前还需对群起脚本进行简单配置:

# ssh 连接端口号,默认会使用 22
export HADOOP_SSH_OPTS="-p 1234 -o BatchMode=yes -o StrictHostKeyChecking=no -o ConnectTimeout=10s"

# 各个节点 ssh 登录的用户
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

配置完成后,使用脚本启动即可:

code shell
# 启动集群
sbin/start-all.sh

# 停止集群
sbin/stop-all.sh

启动历史记录服务

192.168.8.9 shell-session
[root@dell hadoop-3.3.1]# bin/mapred --daemon start historyserver
[root@dell hadoop-3.3.1]# jps
12562 Jps
419 DataNode
2116 NodeManager
1349 ResourceManager
12470 JobHistoryServer
32298 NameNode

验证

集群启动后,可以通过 webui 查看集群当前状态,webui 部署在 NameNode 所在节点的 9870 端口:

如需使用其它端口,可修改 etc/hadoop/yarn-site.xml 文件,新增 dfs.namenode.http-address0.0.0.0:xxxx 即可。

注意图中红色框选位置,Live Nodes 应为 3,Dead Nodes 应为 0。

webui 还提供了 HDFS 文件系统的可视化界面,在此界面可以对文件系统进行简单的操作,例如创建文件夹、上传下载文件等:

当然 HDFS 也可以通过命令行进行操作,操作命令与本地文件系统常用命令基本一致:

hdfs-help shell-session
[root@dell hadoop-3.3.1]# bin/hdfs dfs -help
Usage: hadoop fs [generic options]
        [-appendToFile <localsrc> ... <dst>]
        [-cat [-ignoreCrc] <src> ...]
        [-checksum [-v] <src> ...]
        [-chgrp [-R] GROUP PATH...]
        [-chmod [-R] <MODE[,MODE]... | OCTALMODE> PATH...]
        [-chown [-R] [OWNER][:[GROUP]] PATH...]
        [-concat <target path> <src path> <src path> ...]
        [-copyFromLocal [-f] [-p] [-l] [-d] [-t <thread count>] <localsrc> ... <dst>]
        [-copyToLocal [-f] [-p] [-ignoreCrc] [-crc] <src> ... <localdst>]
        [-count [-q] [-h] [-v] [-t [<storage type>]] [-u] [-x] [-e] [-s] <path> ...]
        [-cp [-f] [-p | -p[topax]] [-d] <src> ... <dst>]
        [-createSnapshot <snapshotDir> [<snapshotName>]]
        [-deleteSnapshot <snapshotDir> <snapshotName>]
        [-df [-h] [<path> ...]]
        [-du [-s] [-h] [-v] [-x] <path> ...]
        [-expunge [-immediate] [-fs <path>]]
        [-find <path> ... <expression> ...]
        [-get [-f] [-p] [-ignoreCrc] [-crc] <src> ... <localdst>]
        [-getfacl [-R] <path>]
        [-getfattr [-R] {-n name | -d} [-e en] <path>]
        [-getmerge [-nl] [-skip-empty-file] <src> <localdst>]
        [-head <file>]
        [-help [cmd ...]]
        [-ls [-C] [-d] [-h] [-q] [-R] [-t] [-S] [-r] [-u] [-e] [<path> ...]]
        [-mkdir [-p] <path> ...]
        [-moveFromLocal [-f] [-p] [-l] [-d] <localsrc> ... <dst>]
        [-moveToLocal <src> <localdst>]
        [-mv <src> ... <dst>]
        [-put [-f] [-p] [-l] [-d] [-t <thread count>] <localsrc> ... <dst>]
        [-renameSnapshot <snapshotDir> <oldName> <newName>]
        [-rm [-f] [-r|-R] [-skipTrash] [-safely] <src> ...]
        [-rmdir [--ignore-fail-on-non-empty] <dir> ...]
        [-setfacl [-R] [{-b|-k} {-m|-x <acl_spec>} <path>]|[--set <acl_spec> <path>]]
        [-setfattr {-n name [-v value] | -x name} <path>]
        [-setrep [-R] [-w] <rep> <path> ...]
        [-stat [format] <path> ...]
        [-tail [-f] [-s <sleep interval>] <file>]
        [-test -[defswrz] <path>]
        [-text [-ignoreCrc] <src> ...]
        [-touch [-a] [-m] [-t TIMESTAMP (yyyyMMdd:HHmmss) ] [-c] <path> ...]
        [-touchz <path> ...]
        [-truncate [-w] <length> <path> ...]
        [-usage [cmd ...]]

后续内容省略.....

递归创建文件夹:

code shell
bin/hdfs dfs -mkdir -p /fangjin/txt

上传文件:

code shell
echo hello world! > /hello.txt
bin/hdfs dfs -put /hello.txt /fangjin/txt

下载文件:

download file shell-session
[root@dell hadoop-3.3.1]# bin/hdfs dfs -get /fangjin/txt/hello.txt ./hh.txt
[root@dell hadoop-3.3.1]# cat hh.txt
hello world!

分布式计算初体验:

Hadoop 官方提供了一个 WordCount 的示例用来统计一段文本中每个单词出现的次数,首先我们需要准备一个文件并上传到 HDFS 中:

code shell
# 将 hdfs 的帮助文档写入文件
bin/hdfs dfs -help > /hdfs-help.txt

# 上传到一个已存在的目录
bin/hdfs dfs -put /hdfs-help.txt /fangjin/txt

# 执行示例
bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.1.jar wordcount /fangjin/txt /wordcount-output

# 打印结果
bin/hdfs dfs -cat /wordcount-output/part-r-00000

通过 webui 查看任务执行日志:

Yarn 集群的 ResourceManager 对外暴露了 8088 端口,浏览器访问 http://192.168.8.9:8088 可以查看历史任务日志:

324