三、Hadoop 运行模式
Hadoop 运行模式
文章目录
Hadoop 官方网站:http://hadoop.apache.org/
Hadoop 运行模式包括:本地模式、伪分布式模式以及完全分布式模式。
- 本地模式:单机运行,只是用来演示一下官方案例。生产环境不用。
- 伪分布式模式:也是单机运行,但是具备 Hadoop 集群的所有功能,一台服务器模拟一个分布式的环境。个别缺钱的公司用来测试,生产环境不用。
- 完全分布式模式:多台服务器组成分布式环境。生产环境使用。
1. 本地运行模式(官方 WordCount)
1)创建在 hadoop-3.1.3 文件下面创建一个 wcinput 文件夹
1 | [wxler@wxler1 hadoop-3.1.3]$ mkdir wcinput |
2)在 wcinput 文件下创建一个 word.txt 文件
1 | cd wcinput |
3)编辑 word.txt 文件
1 | vim word.txt |
在文件中输入如下内容
1 | hadoop yarn |
4)回到 Hadoop 目录/opt/module/hadoop-3.1.3
5)执行程序
1 | [wxler@wxler1 hadoop-3.1.3]$ hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar wordcount wcinput wcoutput |
- wcinput是输入目录
- wcoutput是输出目录
6)查看结果
1 | [wxler@wxler1 hadoop-3.1.3]$ cat wcoutput/part-r-00000 |
2. 完全分布式运行模式(开发重点)
分析:
1)准备 3 台客户机(关闭防火墙、静态 IP、主机名称)
2)安装 JDK
3)配置环境变量
4)安装 Hadoop
5)配置环境变量
6)配置集群
7)单点启动
8)配置 ssh
9)群起并测试集群
2.1 编写集群分发脚本 xsync
1)scp(secure copy)安全拷贝
(1)scp 定义
scp 可以实现服务器与服务器之间的数据拷贝。(from server1 to server2)
(2)基本语法
1 | scp -r $pdir/$fname $user@$host:$pdir/$fname |
(3)案例实操
前提:在 wxler1、wxler2、wxler3都已经创建好的/opt/module、/opt/software 两个目录,并且已经把这两个目录修改为 wxler:wxler
1 | sudo chown wxler:wxler -R /opt/module |
(a )在 wxler1上,将 wxler1 中/opt/module/jdk1.8.0_212 目录拷贝到wxler2上。
1 | [wxler@wxler1 ~]$ scp -r /opt/module/jdk1.8.0_212 wxler@wxler2:/opt/module |
(b )在 wxler2 上,将 wxler1中/opt/module/jdk1.8.0_212 目录拷贝到wxler2上。
1 | [wxler@wxler2 module]$ scp -r wxler@wxler1:/opt/module/hadoop-3.1.3 /opt/module/ |
(c)在 wxler2 上操作,将 wxler1中/opt/module 目录下所有目录拷贝到wxler3上。
1 | scp -r wxler@wxler1:/opt/module/* wxler@wxler3:/opt/module |
2)rsync 远程同步工具
rsync 主要用于备份和镜像。具有速度快、避免复制相同内容和支持符号链接的优点
rsync 和 scp 区别:用 rsync 做文件的复制要比 scp 的速度快,rsync 只对差异文件做更新。scp 是把所有文件都复制过去。
(1)基本语法
1 | rsync -av $pdir/$fname $user@$host:$pdir/$fname |
选项参数说明
(2)案例实操
(a)删除 wxler2 中/opt/module/hadoop-3.1.3/wcinput
1 | [wxler@wxler2 hadoop-3.1.3]$ rm -rf wcinput/ |
(b)同步 wxler1 中的/opt/module/hadoop-3.1.3 到 wxler2
1 | rsync -av hadoop-3.1.3/ wxler@wxler2:/opt/module/hadoop-3.1.3/ |
注意:两个服务器都要安装yum install rsync -y
3)xsync 集群分发脚本
(1)需求:循环复制文件到所有节点的相同目录下
(2)需求分析:
(a)rsync 命令原始拷贝
1 | rsync -av /opt/module wxler@wxler2:/opt/ |
(b)期望脚本:
1 | xsync 要同步的文件名称 |
(c)期望脚本在任何路径都能使用(脚本放在声明了全局环境变量的路径)
1 | [wxler@wxler2 hadoop-3.1.3]$ echo $PATH |
(3)脚本实现
(a)在/home/wxler/bin 目录下创建 xsync 文件
1 | [wxler@wxler1 hadoop-3.1.3]$ cd /home/wxler |
在该文件中编写如下代码
1 |
|
(b)修改脚本 xsync 具有执行权限
1 | chmod +x xsync |
(c)测试脚本
1 | xsync /home/wxler/bin |
(d)将脚本复制到/bin 中,以便全局调用
1 | sudo cp xsync /bin/ |
(e)同步环境变量配置(root 所有者)
1 | sudo xsync /etc/profile.d/my_env.sh |
让环境变量生效,在另外两台虚拟机上执行source /etc/profile
2.2 SSH 无密登录配置
1)配置 ssh
(1)基本语法
1 | ssh 另一台电脑的 IP 地址 |
(2)ssh 连接时出现 Host key verification failed 的解决方法
1 | ssh wxler2 |
如果出现如下内容
1 | Are you sure you want to continue connecting (yes/no)? |
输入 yes,并回车
(3)退回到 wxler1,输入exit
2)无秘钥配置
(1)免密登录原理
(2)生成公钥和私钥
ssh-keygen 产生公钥与私钥对.
1 | [wxler@wxler1 ~]$ ls -a |
然后敲(三个回车),就会生成两个文件 id_rsa(私钥)、id_rsa.pub(公钥)
(3)将公钥拷贝到要免密登录的目标机器上
ssh-copy-id 将本机的公钥复制到远程机器的authorized_keys文件中,ssh-copy-id也能让你有到远程机器的home, ~./ssh , 和 ~/.ssh/authorized_keys的权利
1 | [wxler@wxler1 .ssh]$ ssh-copy-id wxler1 |
然后在wxler2、wxler3上分别执行第(2)、(3)步
到这里,我们用wxler用户进行了免密配置,但是用别的用户登录时(比如root用户),还是要输入密码,为了方便起见,我们在wxler1主机上再采用root账号配置一下无密登录到wxler1、wxler2、wxler3上,别的机器上用到再说。
1 | [wxler@wxler1 .ssh]$ su root |
再在wxler1主机上分别执行第(2)、(3)步即可
3).ssh 文件夹下(~/.ssh)的文件功能解释
2.3 集群配置
以下命令均在wxler1虚拟机上执行
1)集群部署规划
注意:
- NameNode 和 SecondaryNameNode 不要安装在同一台服务器
- ResourceManager 也很消耗内存,不要和 NameNode、SecondaryNameNode 配置在同一台机器上。
2)配置文件说明
Hadoop 配置文件分两类:默认配置文件和自定义配置文件,只有用户想修改某一默认配置值时,才需要修改自定义配置文件,更改相应属性值。
(1)默认配置文件:
从官网上下载之后,会有这四个文件
(2)自定义配置文件:
core-site.xml 、 hdfs-site.xml 、 yarn-site.xml 、 mapred-site.xml 四个配置文件存放在$HADOOP_HOME/etc/hadoop
这个路径上,用户可以根据项目需求重新进行修改配置。
3)配置集群
(1)核心配置文件
配置 core-site.xml
1 | cd $HADOOP_HOME/etc/hadoop |
文件内容如下:
1 | <?xml version="1.0" encoding="UTF-8"?> |
注意,8020是hadoop内部通讯的端口
(2)HDFS 配置文件
配置 hdfs-site.xml
1 | vim hdfs-site.xml |
文件内容如下:
1 | <?xml version="1.0" encoding="UTF-8"?> |
(3)YARN 配置文件
1 | vim yarn-site.xml |
文件内容如下:
1 | <?xml version="1.0" encoding="UTF-8"?> |
注意:HADOOP_MAPRED_HOME
是比默认多的配置,这是hadoop-3.1.3的小Bug,高版本就没有这个问题了
(4)MapReduce 配置文件
配置 mapred-site.xml
1 | vim mapred-site.xml |
文件内容如下:
1 | <?xml version="1.0" encoding="UTF-8"?> |
4)在集群上分发配置好的 Hadoop 配置文件
1 | xsync /opt/module/hadoop-3.1.3/etc/hadoop/ |
5)去 wxler2 和 wxler3上查看文件分发情况
1 | [wxler@wxler2 .ssh]$ cat /opt/module/hadoop-3.1.3/etc/hadoop/core-site.xml |
2.4 群起集群
以下命令均在wxler1虚拟机上执行
1)配置 workers
1 | vim /opt/module/hadoop-3.1.3/etc/hadoop/workers |
在该文件中增加如下内容:
1 | wxler1 |
注意:该文件中添加的内容结尾不允许有空格,文件中不允许有空行。
同步所有节点配置文件
1 | xsync /opt/module/hadoop-3.1.3/etc |
2)启动集群
以下命令均在wxler1虚拟机上执行
(1)如果集群是第一次启动,需要在 wxler1 节点格式化 NameNode(注意:格式化 NameNode,会产生新的集群 id,导致 NameNode 和 DataNode 的集群 id 不一致,集群找不到已往数据。 如果集群在运行过程中报错,需要重新格式化 NameNode 的话, 一定要先停止 namenode 和 datanode 进程,并且要删除所有机器的 data 和 logs 目录,然后再进行格式化。)
data 目录存放在:/opt/module/hadoop-3.1.3/data
logs 目录存放在:/opt/module/hadoop-3.1.3/logs
格式化:
1 | hdfs namenode -format |
格式化以后会在/opt/module/hadoop-3.1.3/
目录下产生data目录存放数据
(2)启动 HDFS
1 | [wxler@wxler1 hadoop-3.1.3]$ sbin/start-dfs.sh |
启动之后会在/opt/module/hadoop-3.1.3/
产生logs目录
(3)在配置了 ResourceManager 的节点(wxler2)启动 YARN
1 | [wxler@wxler2 hadoop-3.1.3]$ sbin/start-yarn.sh |
(4)Web 端查看 HDFS 的 NameNode
(a)浏览器中输入:http://wxler1:9870
(b)查看 HDFS 上存储的数据信息
(5)Web 端查看 Y ARN 的 ResourceManager
(a)浏览器中输入:http://wxler2:8088
(b)查看 YARN 上运行的 Job 信息
3)集群基本测试
(1)上传文件到集群
上传小文件
1 | [wxler@wxler1 hadoop-3.1.3]$ hadoop fs -mkdir /input |
上传大文件
1 | [wxler@wxler1 hadoop-3.1.3]$ hadoop fs -put /opt/software/jdk-8u212-linux-x64.tar.gz / |
(2)上传文件后查看文件存放在什么位置
查看 HDFS 文件存储路径
1 | [wxler@wxler1 subdir0]$ pwd |
查看 HDFS 在磁盘存储文件内容
1 | [wxler@wxler1 subdir0]$ cat blk_1073741825 |
(3)拼接
1 | [wxler@wxler1 subdir0]$ ll |
可以看到,解压出来就是一个jdk
(4)下载
1 | [wxler@wxler1 subdir0]$ cd ~ |
(5)执行 wordcount 程序
1 | [wxler@wxler1 hadoop-3.1.3]$ pwd |
如果执行过程中,报如下错误,任务执行失败
1 | [2021-03-31 17:26:59.903]Container killed on request. Exit code is 143 |
解决方法:
①修改配置文件 /opt/module/hadoop-3.1.3/etc/hadoop/yarn-site.xml
添加如下内容
1 | <!--是否启动一个线程检查每个任务正使用的物理内存量,如果任务超出分配值,则直接将其杀掉,默认是true --> |
②分发配置(支持相对路径)
1 | xsync /opt/module/hadoop-3.1.3/etc/hadoop/ |
③重启hadoop集群
2.5 配置历史服务器
为了查看程序的历史运行情况,需要配置一下历史服务器。具体配置步骤如下:
1)配置 mapred-site.xml
1 | [wxler@wxler1 hadoop]$ pwd |
在该文件里面增加如下配置。
1 | <!-- 历史服务器端地址 --> |
- 10020是历史服务器内部通讯的端口
- 19888是外部暴露的端口
2)分发配置(支持相对路径)
1 | xsync $HADOOP_HOME/etc/hadoop/mapred-site.xml |
3)在 wxler1 启动历史服务器
1 | [wxler@wxler1 hadoop]$ mapred --daemon start historyserver |
--daemon
表示在后台启动
4)查看 JobHistory
http://wxler1:19888/jobhistory
2.6 配置日志的聚集
日志聚集概念:应用运行完成以后,将程序运行日志信息上传到 HDFS 系统上。
日志聚集功能好处:可以方便的查看到程序运行详情,方便开发调试。
注意 :开启日志聚集功能, 需要 重新启动 NodeManager 、 ResourceManager 和HistoryServer。
开启日志聚集功能具体步骤如下:
1)配置 yarn-site.xml
1 | [wxler@wxler1 hadoop]$ pwd |
在该文件里面增加如下配置。
1 | <!-- 开启日志聚集功能 --> |
2)分发配置
1 | xsync $HADOOP_HOME/etc/hadoop/yarnsite.xml |
3)关闭 NodeManager 、ResourceManager 和 HistoryServer
1 | [wxler@wxler2 hadoop]$ cd /opt/module/hadoop-3.1.3/ |
注意,因为ResourceManager 是在wxler2上配置的,所以一定要在wxler2上关闭。而historyserver是在wxler1上配置的,所以historyserver要在weler1上关闭。
4)启动 NodeManager 、ResourceManage 和 HistoryServer
1 | [wxler@wxler2 hadoop-3.1.3]$ start-yarn.sh |
同理,启动的位置同上一步
5)删除 HDFS 上已经存在的输出文件
1 | [wxler@wxler1 hadoop-3.1.3]$ hadoop fs -rm -r /output |
6)执行 WordCount 程序
1 | [wxler@wxler1 hadoop-3.1.3]$ hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar wordcount /input /output |
7)查看日志
(1)历史服务器地址
http://wxler1:19888/jobhistory
(2)历史任务列表
(3)查看任务运行日志
(4)运行日志详情
2.7 集群启动/停止方式总结
1)各个模块分开启动/停止(配置 ssh 是前提)常用
(1)整体启动/停止 HDFS
1 | start-dfs.sh/stop-dfs.sh |
(2)整体启动/停止 YARN
1 | start-yarn.sh/stop-yarn.sh |
2)各个服务组件逐一启动/停止
(1)分别启动/停止 HDFS 组件
1 | hdfs --daemon start/stop namenode/datanode/secondarynamenode |
(2)启动/停止 YARN
1 | yarn --daemon start/stop resourcemanager/nodemanager |
2.8 编写 Hadoop 集群常用脚本
1)Hadoop 集群启停脚本(包含 HDFS,Y arn,Historyserver):myhadoop.sh
1 | [wxler@wxler1 hadoop-3.1.3]$ cd /home/wxler/bin |
输入以下内容:
1 |
|
保存后退出,然后赋予脚本执行权限
1 | chmod +x myhadoop.sh |
2)查看三台服务器 Java 进程脚本:jpsall
1 | [wxler@wxler1 hadoop-3.1.3]$ cd /home/wxler/bin |
输入以下内容:
保存后退出,然后赋予脚本执行权限
1 | chmod +x jpsall |
3)分发/home/atguigu/bin 目录,保证自定义脚本在三台机器上都可以使用
1 | [wxler@wxler1 bin]$ pwd |
2.9 常用端口号说明
2.10 集群时间同步
如果服务器在公网环境(能连接外网),可以不采用集群时间同步,因为服务器会定期和公网时间进行校准;
如果服务器在内网环境,必须要配置集群时间同步,否则时间久了,会产生时间偏差,导致集群执行任务时间不同
步。
1)需求
找一个机器,作为时间服务器,所有的机器与这台集群时间进行定时的同步, 生产环境根据任务对时间的准确程度要求周期同步。 测试环境为了尽快看到效果,采用 1 分钟同步一次。
2)时间服务器配置
以下代码均在wxler1上执行
(1)查看所有节点 ntpd 服务状态和开机自启动状态
查看ntpd状态
1 | [wxler@wxler1 ~]$ sudo systemctl start ntpd |
安装ntpd
1 | [wxler@wxler1 ~]$ sudo yum -y install ntp |
下面依次执行
1 | [wxler@wxler1 ~]$ sudo systemctl start ntpd #启动ntpd服务 |
(2)修改 hadoop102 的 ntp.conf 配置文件
1 | sudo vim /etc/ntp.conf |
修改内容如下,总共修改3出
(a)修改 1(授权 192.168.10.0-192.168.10.255 网段上的所有机器可以从这台机器上查询和同步时间),即都可以查询wxler1虚拟机上的时间并同步
1 | #restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap |
改为
1 | restrict 192.168.218.0 mask 255.255.255.0 nomodify notrap |
(b)修改 2(集群在局域网中,不使用其他互联网上的时间)
1 | server 0.centos.pool.ntp.org iburst |
修改为
1 | # server 0.centos.pool.ntp.org iburst |
(c) 添加 3 (当该节点丢失网络连接,wxler1依然可以采用本地时间作为时间服务器为集群中的其他节点提供时间同步)
在/etc/ntp.conf
最后增加
1 | server 127.127.1.0 |
(3)修改 wxler1 的/etc/sysconfig/ntpd 文件
1 | [wxler@wxler1 ~]$ sudo vim /etc/sysconfig/ntpd |
增加内容如下(让硬件时间与系统时间一起同步)
1 | SYNC_HWCLOCK=yes |
(4)重新启动 ntpd 服务
1 | sudo systemctl restart ntpd |
3)其他机器配置
(1)关闭所有节点上 ntp 服务和自启动
1 | sudo systemctl stop ntpd |
(2)在其他机器配置 1 分钟与时间服务器同步一次
1 | sudo crontab -e |
编写定时任务如下:
1 | */1 * * * * /usr/sbin/ntpdate wxler1 |
注意:除了wxler1之外,wxler2、wxler3都要执行
3. 常见错误及解决方案
1)防火墙没关闭、或者没有启动 YARN
1 | INFO client.RMProxy: Connecting to ResourceManager at hadoop108/192.168.10.108:8032 |
2)主机名称配置错误
3)IP 地址配置错误
4)ssh 没有配置好
5)root 用户和 atguigu 两个用户启动集群不统一
6)配置文件修改不细心
7)不识别主机名称
1 | java.net.UnknownHostException: hadoop102: hadoop102 |
解决办法:
(1)在/etc/hosts 文件中添加 192.168.10.102 wxler1
(2)主机名称不要起 hadoop、hadoop000 等特殊名称
8)DataNode 和 NameNode 进程同时只能工作一个。
三个步骤:
- 关闭hdfs、yarn、历史服务器等
- 删除所有节点的data和logs目录
- 重新格式化
9)执行命令不生效,粘贴 Word 中命令时,遇到-和长–没区分开。导致命令失效
解决办法:尽量不要粘贴 Word 中代码。
10)jps 发现进程已经没有,但是重新启动集群,提示进程已经开启。
原因是在 Linux 的根目录下/tmp 目录中存在启动的进程临时文件,将集群相关进程删除掉,再重新启动集群。
11)jps 不生效
原因:全局变量 hadoop java 没有生效。解决办法:需要 source /etc/profile 文件。
12)8088 端口连接不上
1 | vim /etc/hosts |
注释掉如下代码
1 | #127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 |
13)hdfs删除文件保存
原因是没有在core-site.xml配置HDFS 网页登录使用的静态用户,解决方法参见2.3节的 3)