Hadoop基础概念
Hadoop优势
- 高可靠性
- 高扩展性
- 高效性
- 高容错性
hadoop的组成(面试重点)
hadoop 1.x 2.x 3.x 的区别
hadoop1.x的组成
- MapReduce : 计算 + 资源调度
- HDFS : 数据存储
- Common :辅助工具
hadoop2.x 组成
- MapReduce: 计算
- Yarn: 资源调度
- HDFS:数据存储
- Common:辅助工具
hadoop3.x 在组成上与2.x没有任何变化
HDFS架构概述
- Hadoop Distributed File System 分布式文件系统
- NameNode(nn): 存储文件的元数据,如文件名,问文件目录结构,文件属性(生成时间、副本数、文件权限)以及每个文件的块列表和快所在的DataNode等。
- DataNode(dn):在本地文件系统中存储文件数据块,以及数据的校验和。
- Secondary NameNode(2nn):每隔一段时间对NameNode元数据备份。
YARN架构概述
- Yet Another Resource Negotiator 资源协调者
- ResourceManager(RM): 整个集群资源(内存,CPU等)的老大
- NodeManage(NM): 单个节点服务资源的老大
- ApplicationMaster(AM): 单个任务运行的老大
- Container : 容器,相当于一台独立的服务器,里面封装了任务运行所需的资源,如内存、IO、磁盘、网络等.
MapReduce架构概述
- Map阶段并行处理输入数据
- Reduce阶段对Map结果进行汇总
hadoop集群搭建
hadoop运行模式
- 本地模式(Local(Standalone) Mode): 只有一台服务器,数据存储在Linux本地,一般只做测试使用。
- 伪分布式模式(Pseudo-Distributed Mode): 只有一台服务器,数据存储在HDFS, 小公司使用。
- 完全分布式(Fully-Distributed Mode): 多台服务器工作,数据存储在HDFS,企业里面大量使用。
本地模式
- 官方WordCount
cd hadoop-3.1.3
mkdir wcinput
cd wcinput
vim word.txt # 新建文本文档并向里面写入内容,同于统计单次数量
atguigu atguigu
hadoop hadoop
mapreduce
yarn
# 回到hadoop-3.1.3,并执行以下命令, 执行jar包中的wordcount功能,统计wcinput/内的单次出现次数
# 并将统计信息保存进wcoutput文件夹内(wcoutput文件夹不能事先存在)
hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar wordcount wcinput/ ./wcoutput
# 查看结果, 看到以下结果
cat /wcoutput/part-r-00000
atguigu 1
hadoop 2
mapreduce 1
yarn 1
完全分布式运行模式(开发重点)
- 分析
- 安装三台客户机(关闭防火墙、静态IP、主机名)
- 安装JDK
- 配置环境变量
- 安装hadoop
- 配置集群
- 单节点启动
- 配置ssh
- 群起并测试集群
编写集群分发脚本
- scp(secure copy) 安全拷贝
scp可以实现服务器与服务器之间的数据拷贝。(from server1 to server2)
- 基本语法
# 安装
yum -y install openssh-clients
#命令 递归 要拷贝的文件路径/名称 目的地用户@主机:目的地路径/名称
scp -r $pdir/$fname $usr@$host:$pdir/$fname
# 也可从其他主机向自己拷贝文件
scp -r $usr@$host:$pdir/$fname $pdir/$fname
# 也可从一台主机拷贝文件到另一台主机
scp -r root@h100:/opt/module/* root@h103:/opt/module/*
# 备注,通过ssh协议传输数据,因此必须开启ssh服务
- rsync远程同步工具
- rsync主要用于备份和镜像。具有速度快、避免复制相同内容的支持符号链接的优缺点。
- rsync和scp的区别:用rsync做文件的复制要比scp的速度快,rsync只对差异文件做更新。scp是把所有文件都复制过去。
- 基本语法
#命令 选项参数 要拷贝的文件路径 目的地用户@主机:目的地路径/名称
rsync -av $pdir/$fname $user@$host:$pdir/$fname
# 选项参数说明 -a 归档拷贝 -v 显示复制过程
- xsync集群分发脚本
- 需求:循环复制文件到所有节点的相同目录下
- xsync配置
#!/bin/bash
#1. 判断参数个数是否小于1
if [ $# -lt 1 ]
then
echo Not Enough Argument!
exit;
fi
#2. 遍历集群所有机器
for host in h100 h101 h102
do
echo ================== $host ==================
# 3. 遍历所有目录(文件),挨个发送
for file in $@
do
#4. 判断文件是否存在,文件存在则发送
if [ -e $file ]
then
#5. 获取父目录
pdir=$(cd -P $(dirname $file); pwd)
#6. 获取当前文件的名称
fname=$(basename $file)
#7. 在目标主机上创建目标文件夹
ssh $host "mkdir -p $pdir"
#8. 同步文件
rsync -av $pdir/$fname $host:$pdir
else
echo $file dose not exists!
fi
done
done
# :wq退出后,修改文件权限,使其可执行
chmod 777 xsync
- 同步分发
# 同步bin目录
# 1.配置环境变量
vim /etc/profile.d/my_env.sh
# 2. 写入以下内容
export XSYNC=/home/usr/bin
export PATH=$PATH:$XSYNC
# 3. 激活
source /etc/profile
# 4. 同步/home/usr/bin目录(返回bin的上一级)
cd ..
xsync bin/
# 存在的问题:没有配置ssh免密登陆
# 因此执行xsync命令时对每台待分发的服务器都需要输入密码才能进行数据同步
- 一些参数
# 为aaa创建一个软连接bbb
ln -s aaa bbb
# 软连接若存在,则进入软连接
cd
cd -L
# 进入真实目录
cd -P
# 需要时创建上层目录,若目录已存在,则不当错误处理
mkdir -p
- ssh免密登陆
cd /root/.ssh
# 生成公钥秘钥对,三次回车
ssh-keygen -t rsa
# 执行上述命令会生成两个文件
id_rsa # 私钥
id_rsa.pub # 公钥
# 将公钥拷贝到其他设备,需要输入h101的密码
ssh-copy-id h101
# 此外, .ssh文件夹下还有两个重要文件
known_host
# 存放已知主机的公钥,首次连接一个主机时,会受到该服务器的公钥
# 并被询问是否信任,确定信任,则会将该公钥存放在known_host文件中
authorized_keys
# 存放授权过的无密登录服务器的公钥
- 集群配置
-
集群部署规划
-
NameNode和SecondNameNode不要安装在同一台机器
-
ResourceManager也很消耗内存,不要和NameNode、SecondaryNameNode配置在同一台机器
-
| h100 | h101 | h102 | |
|---|---|---|---|
| HDFS | NameNode, DateNode | DateNode | SecondaryNameNode, DateNode |
| YARN | NodeManager | ResourceManager, NodeManager | NodeManager |
- 配置文件说明
hadoop配置文件分两类:默认配置文件和自定义配置文件,只有用户想修改某一默认配置文件时,才需要修改自定义配置文件,更改相应属性值。
- 默认配置文件
| 要获取的默认配置文件 | 问价存放在Hadoop的jar包中的位置 |
|---|---|
| core-default.xml | hadoop-common-3.1.3.jar/core-default.xml |
| hdfs-default.xml | hadoop-hdfs-3.1.3.jar/hdfs-default.xml |
| yarn-default.xml | hadoop-yarn-common-3.1.3.jar/yarn-default.xml |
| mapred-default.xml | hadoop-mapreduce-client-core-3.1.3.jar/mapred-default.xml |
- 自定义配置文件
core-site.xml、hdfs-site.xml、yarn-site.xml、mapred-site.xml 四个配置文件存放在$HADOOP_HOME/etc/hadoop这个路径上,用户胡可以根据需求重新进行修改配置
-
配置集群(按照集群规划进行配置)
- 核心配置文件
cd $HADOOP_HOME/etc/hadoop vim core-site.xml # 在<configuration></configuration>中添加以下内容 <!-- 指定NameNode的地址--> <property> <name>fs.defaultFS</name> <value>hdfs://h100:8020</value> </property> <!-- 指定hadoop数据的存储目录(一定要写绝对路径,使用环境变量会报错) --> <property> <name>hadoop.tmp.dir</name> <value>/opt/module/hadoop-3.1.3/data</value> </property> <!-- 配置HDFS网页登录使用的静态用户为root --> <property> <name>hadoop.http.staticuser.user</name> <value>root</value> </property> # NameNode常用端口 8020 9000 9820- HDFS配置文件
vim hdfs-site.xml # 在<configuration></configuration>中添加以下内容 <!-- nn web端访问地址 --> <property> <name>dfs.namenode.http-address</name> <value>h100:9870</value> </property> <!-- 2nn web访问地址 --> <property> <name>dfs.namenode.secondary.http-address</name> <value>h102:9868</value> </property>- YARN配置文件
vim yarn-site.xml # 在<configuration></configuration>中添加以下内容 <!-- 指定MR走shuffle协议 --> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <!-- 指定ResourceManager的地址 --> <property> <name>yarn.resourcemanager.hostname</name> <value>h101</value> </property> <!-- 环境变量的继承 --> <property> <name>yarn.nodemanager.env-whitelist</name> <value>JAVA_HOME,HADOOP_COMMON_HOME,HADOOP_HDFS_HOME,HADOOP_CONF_DIR,CLASSPATH_PREPEND_DISTCACHE,HADOOP_YARN_HOME,HADOOP_MAPRED_HOME</value> </property>- MapReduce配置
vim mapred-site.xml # 在<configuration></configuration>中添加以下内容 <!-- 指定MapReduce程序运行在Yarn上 --> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property>- 在集群上分发配置好的Hadoop配置文件
xsync $HADOOP_HOME/etc/hadoop/
- 群起集群
- 配置workers
vim $HADOOP_HOME/etc/hadoop/workers
# 添加以下内容(文件中不允许有空格, 删除默认的localhost)
h100
h101
h102
# 同步所有节点配置文件
xsync $HADOOP_HOME/etc
-
启动集群
- 若集群是第一次启动,需要在h100节点格式化NameNode.(注意,格式化NameNode,会产生新的集群id,导致NameNode和DateNode的集群id不一致,集群找不到以往数据。如果集群在运行过程中报错,需要重新格式化NameNode的话,一定要先停止NameNode和DataNode进程,并且要删除所有机器的data和logs目录,然后再进行格式化).
hdfs namenode -format- 启动HDFS
sbin/start-dfs.sh- 可能存在如下错误
# 错误1: [root@h100 hadoop]# start-dfs.sh Starting namenodes on [h100] ERROR: Attempting to operate on hdfs namenode as root ERROR: but there is no HDFS_NAMENODE_USER defined. Aborting operation. Starting datanodes ERROR: Attempting to operate on hdfs datanode as root ERROR: but there is no HDFS_DATANODE_USER defined. Aborting operation. Starting secondary namenodes [h102] ERROR: Attempting to operate on hdfs secondarynamenode as root ERROR: but there is no HDFS_SECONDARYNAMENODE_USER defined. Aborting operation. # 解决办法 vim /etc/profile # 添加以下内容 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 source /etc/profile # 其它几个也需要配置 # 错误2: [root@h100 hadoop]# start-dfs.sh Starting namenodes on [h100] Last login: Fri Jul 14 16:07:29 CST 2023 from h102.docker-hadoop_hadoop on pts/3 h100: ERROR: JAVA_HOME is not set and could not be found. Starting datanodes Last login: Fri Jul 14 16:24:57 CST 2023 on pts/2 h101: ERROR: JAVA_HOME is not set and could not be found. h102: ERROR: JAVA_HOME is not set and could not be found. h100: ERROR: JAVA_HOME is not set and could not be found. Starting secondary namenodes [h102] Last login: Fri Jul 14 16:24:58 CST 2023 on pts/2 h102: ERROR: JAVA_HOME is not set and could not be found. # 修改hadoop-env.sh文件,确保包含以下内容($JAVA_HOME替换为自己的绝对路径) export JAVA_HOME=$JAVA_HOME- 在配置了ResourceManager的节点h101启动Yarn
sbin/start-yarn.sh-
在web端查看HDFS的NameNode
- 在浏览器中输入:http://h100:9870
- 查看HDFS上存储的数据信息
-
web端查看Yarn的ResourceManager
- 浏览器中输入: http://h101:8088
- 查看yarn上运行的Job信息
-
集群基本测试
- 上传文件到集群
# 上传小文件 # 1. 在hdfs上创建目录 hadoop fs -mkdir /input # 2. 上传文件 hadoop fs -put $HADOOP_HOME/wcinput/word.txt /input # 上传大文件到根目录 hadoop fs -put /JAVA_HOME/jdk-8u361-linux-x64.tar.gz /- 上传后查看文件存放在什么位置
cd $HADOOP_HOME/data/dfs/data/current/BP-1456512281-*/current/finalized/subdir0/subdir0- 拼接
# jdk文件上传后被分块,需要拼接后才能解压 cat blk_1073741828 >> tmp.tar.gz cat blk_1073741829 >> tmp.tar.gz tar -zxvf tmp.tar.gz-
备注:hadoop的高可用性,上传的文件会选择任意三个DataNode进行存储,这样当一台服务器宕机后,仍然可以读取到数据
-
下载
hadoop fs -get /jdk-8u361-linux-x64.tar.gz- 执行wordcount程序
hadoop jar -
集群崩溃处理
#1. DataNode宕机
kil -9:<h100 DataNode的进程id>
#2. 删除h100,h101以及h102data数据
#(注:data中存储的数据会被删除,但由于集群仍在运行以及core-site.xml中的配置,
# data文件夹会被自动创建,历史上传文件虽被删除,但集群配置信息仍然在)
rm -rf $HADOOP_HOME/data
#3. NN web页面无法访问下载数据,连接失败
# 通常集群崩溃时,格式化集群,并重启可解决,但有一以下注意事项
# 1. 格式化之前必须删除 data文件夹以及logs问价夹,因为其中存储的有当前集群的配置信息,若不删除,新启动的集群ID与过往ID不同,且data中的name问价夹被删除,会导致NameNode或DataNode启动失败。
# 2. 先停止集群(杀死进程),stop-dfs.sh, stop-yarn.sh
# 3. 删除(每个集群上的data与logs)
# 4. 格式化 hdfs namenode -format
# 5. 启动集群 start-dfs.sh, start-yarn.sh
- 配置历史服务器
vim mapred-site.xml
# 添加以下内容
<!-- 历史服务器地址 -->
<property>
<name>mapreduce.jobhistory.address</name>
<value>h100:10020</value>
</property>
<!-- 历史服务器web端口 -->
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>h100:19888</value>
</property>
# 1. 分发 xsync mapred-site.xml
# 2. 重启yarn(h101)
stop-yarn.sh
start-yarn.sh
# 3. 启动历史服务器进程(h100 NameNode19888)
mapred --daemon start historyserver # --daemon 后台启动,守护进程 (mapred 在$HADOOP_HOME/bin目录下)
# 4. 查看历史服务器是否启动
jps
# 测试
hadoop jar hare/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar wordcount /wcinput /wcoutput
# 在h101:8088页面可以查看任务状态并查看历史信息
- 配置日志的聚集
- 日志聚集的概念:应用运行完成后,将程序运行日志信息上传到HDFS系统上。
- 日志聚集功能的好处: 可以方便的查看到程序运行详情,方便开发测试
- 注意:开启日志聚集功能,需要重新启动NodeManager、ResourceManager和HistoryServer
- 配置yarn.site.xml
vim yarn-site.xml
# 添加以下内容
<!-- 开启日志聚集功能 -->
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<!-- 配置日志聚集服务器地址 -->
<property>
<name>yarn.log.server.url</name>
<value>http://h100:19888/jobhistory/logs</value>
</property>
<!-- 设置日志保留时间7天 -->
<property>
<name>yarn.log.aggregation.retain-seconds</name>
<value>604800</value>
</property>
- 分发配置
xsync $HADOOP_HOME/etc/hadoop/yarn-site.xml
- 关闭NodeManager、ResourceManager和HistoryServer
stop-yarn.sh
mapred --daemon stop historyserver
- 启动NodeManager、ResourceManage和HistoryServer
start-yarn.sh
mapred --daemon start historyserver
- 集群启动/停止方式总结
-
各个模块分开启动/停止(配置ssh是前提)常用
- 整体启动/停止HDFS
start-dfs.sh / stop-dfs.sh- 整体启动/停止yarn
start-yarn.sh / stop-yarn.sh -
各个服务组件逐一启动停止
- 分别启动/停止HDFS组件(组件名小写)
hdfs --daemon start/stop namenode/datanode/secondarynamenode- 分别启动或停止Yarn(组件名小写)
yarn --daemon start/stop resourcemanager/nodemanager
- 编写hadoop集群常用脚本
- Hadoop集群启停脚本(包含HDFS, Yarn, Historyserver):myhadoop.sh
cd /usr/local/bin
vim myhadoop.sh
# 输入以下内容
#!/bin/bash
if [ $# -lt 1 ]
then
echo "No Args Input..."
exit;
fi
case $1 in
"start")
echo "=============== 启动hadoop集群 ==============="
echo "------------- 启动hdfs ---------------"
ssh h100 "/usr/local/hadoop/hadoop-3.1.3/sbin/start-dfs.sh"
echo "--------------- 启动yarn ---------------"
ssh h101 "/usr/local/hadoop/hadoop-3.1.3/sbin/start-yarn.sh"
echo "--------------- 启动historyserver ---------------"
ssh h100 "/usr/local/hadoop/hadoop-3.1.3/bin/mapred --daemon start historyserver"
;;
"stop")
echo "=============== 关闭hadoop集群 ==============="
echo "--------------- 关闭historyserver ---------------"
ssh h100 "/usr/local/hadoop/hadoop-3.1.3/bin/mapred --daemon stop historyserver"
echo "--------------- 关闭yarn ---------------"
ssh h101 "/usr/local/hadoop/hadoop-3.1.3/sbin/stop-yarn.sh"
echo "--------------- 关闭hdfs ---------------"
ssh h100 "/usr/local/hadoop/hadoop-3.1.3/sbin/stop-dfs.sh"
;;
*)
echo "Input Args Errors..."
;;
esac
# 保存退出,然后修改权限
chmod 777 myhadoop.sh
- 查看所有服务器JAVA进程的脚本: jpsall
cd /usr/local/bin
vim jpsall
# 写入以下内容
#!/bin/bash
for host in h100 h101 h102
do
echo "=============== $host ==============="
ssh $host jps
done
# 保存退出,然后修改权限
chmod +x jpsall
- 可能出现的错误
# 若使用root用户启动或停止yarn以及hdfs,即便在/etc/profile中配置了HDFS_NAMENODE_USER等值为root
# 也会出现如下错误
--------------- 停止yarn ---------------
Stopping nodemanagers
ERROR: Attempting to operate on yarn nodemanager as root
ERROR: but there is no YARN_NODEMANAGER_USER defined. Aborting operation.
Stopping resourcemanager
ERROR: Attempting to operate on yarn resourcemanager as root
ERROR: but there is no YARN_RESOURCEMANAGER_USER defined. Aborting operation.
--------------- 停止hdfs ---------------
Stopping namenodes on [h100]
ERROR: Attempting to operate on hdfs namenode as root
ERROR: but there is no HDFS_NAMENODE_USER defined. Aborting operation.
Stopping datanodes
ERROR: Attempting to operate on hdfs datanode as root
ERROR: but there is no HDFS_DATANODE_USER defined. Aborting operation.
Stopping secondary namenodes [h102]
ERROR: Attempting to operate on hdfs secondarynamenode as root
ERROR: but there is no HDFS_SECONDARYNAMENODE_USER defined. Aborting operation.
# 解决办法
# 1. 修改 hadoop-env.sh
vim $HADOOP_HOME/etc/hadoop/hadoop-env.sh
# 添加以下内容
export HDFS_NAMENODE_USER=root
export HDFS_DATANODE_USER=root
export HDFS_SECONDARYNAMENODE_USER=root
# 2. 修改yarn-env.sh
vim $HADOOP_HOME/etc/hadoop/yarn-env.sh
# 添加以下内容
export YARN_NODEMANAGER_USER=hadoop
export YARN_RESOURCEMANAGER_USER=hadoop
# 3. xsync分发
-
常用端口号说明(面试题)
- Hadoop3.x
- HDFS NameNode 内部常用端口号:8020/9000/9820
- HDFS NameNode 对用户的查询端口:9870
- Yarn 查看任务运行情况:8088
- 历史服务器: 19888
- Hadoop2.x
- HDFS NameNode 内部常用端口号:8020/9000
- HDFS NameNode 对用户的查询端口:50070
- Yarn 查看任务运行情况:8088
- 历史服务器: 19888
- Hadoop3.x
-
常用配置文件(面试题)
- Hadoop3.x
- core-site.xml
- hdfs-site.xml
- yarn-site.xml
- mapred-site.xml
- workers
- Hadoop2.x
- core-site.xml
- hdfs-site.xml
- yarn-site.xml
- mapred-site.xml
- slaves
- Hadoop3.x
-
集群时间同步
- 生产环境: 如果服务器能连接外网,不需要时间同步
- 生产环境:如果服务器不能连接外网,需要时间同步,所有节点向同一个节点同步时间
-
时间服务器配置(必须是root用户)
- 查看所有节点ntpd服务状态和开机自启动状态
sudo systemctl status ntpd sudo systemctl start ntpd sudo systemctl is-enabled ntpd- 修改h100的ntp.conf配置文件
sudo vim /etc/ntp.conf # 修改1(授权192.168.·0.0-192.168.10.255网段所有机器可从这台机器上查询和同步时间) # 取消注释以下语句 restrict 192.168.10.0 mask 155.155.155.0 nomodify notrap # 修改2(集群在局域网中,不使用其他互联网上的时间) # 注释以下内容 server 0.centos.pool.ntp.orgh iburst server 1.centos.pool.ntp.orgh iburst server 2.centos.pool.ntp.orgh iburst server 3.centos.pool.ntp.orgh iburst # 添加3(当节点丢失网络连接,依然可以采用本地时间作为服务器为集群中的其他节点提供时间同步) server 127.127.1.0 fudge 127.127.1.0 stratum 10- 修改h100的/etc/sysconfig/ntpd文件
sudo vim /etc/sysconfig/ntpd # 添加以下内容(让硬件时间与系统时间同步) SYNC_HWCLOCK=yes- 重启ntpd服务
sudo systemctl start ntpd- 设置ntpd开机自启
sudo systemctl enable ntpd -
其他机器配置
- 关闭所有节点ntpd服务和开机自启动
sudo systemctl stop ntpd sudo systemctl disable ntpd- 在其他机器配置1分钟与时间服务器同步一次
sudo crontab -e # 添加以下内容 */1 * * * * /usr/sbin/ntpdate h100- 修改任一服务器时间
sudo date -s "2021-9-11 11:11:11"- 一分钟后查看机器是否与时间服务器同步
sudo date
常见错误以及解决方案
- 防火墙未关闭、或者没有启动YARN
INFO client.RMProxy: Connecting to ResourceManager at hadoop108/192.168.10.108:8083
- 主机名配置错误
- IP地址配置错误
- ssh配置错误
- root与自定义用户启动集群不统一
- 不识别主机名称(修改主机名与IP映射, 主机名不要取hadoop 以及 hadoop000等特殊名称)
java.net.UnknownHostException: hadoop102: hadoop102
- 同一个节点上,NameNode 与 DataNode只能同时工作一个
- NameNode在format后生成clusterId(集群id)
- DataNode在启动后也会生成和NameNode一样的clusterId(集群id)
- 再次格式化NameNode后,生成新的clusterid,与未删除DataNode的clusterid不一致
- 解决办法: 在格式化前,先删除DataNode里的信息(默认在/tmp下,本文配置在$HADOOP_HOME/data下,也要删除logs文件)
- jps发现进程已经没有,但是重新启动集群,提示进程已经开启。
- 原因:是在Linux的根目录下/tmp目录中存在启动的临时文件,将集群相关进程删除掉,再重新启动
- jps不生效
- 原因:全局变量hadoop java没有生效,source /etc/profile