yarn的伪分布式部署&jps的原理&oom-killer&/tmp目录的clean机制

目标

  1. 搭建 yarn伪分布式
  2. 跑mr count案例
  3. 整理 jps命令
  4. Linux两个机制 oom clean

Yarn伪分布式部署&单点&主从架构

由于hadoop集成了MapReduce和Yarn,所以这里我们只要修改相关的配置文件即可使用

我们需要配置mapred-site.xmlyarn-site.xml这两个文件,由于mapred-site.xml不存在所以需要复制一个出来

[hadoop@aliyun hadoop]$ cp mapred-site.xml.template mapred-site.xml

然后用vim打开mapred-site.xml并修改

vim mapred-site.xml

<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<!-- 历史服务器端地址 -->
<property>
<name>mapreduce.jobhistory.address</name>
<value>hadoop:10020</value>
</property>
<!-- 历史服务器web端地址 -->
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>hadoop:19888</value>
</property>
</configuration>

然后用vim打开yarn-site.xml并修改文件

vim yarn-site.xml

<configuration>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address</name>
<value>aliyun:38088</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>

注意: 这是使用38088替代默认的8088是为了避免云主机被挖矿

最后启动Yarn

[hadoop@aliyun hadoop]$ start-yarn.sh
starting yarn daemons
starting resourcemanager, logging to /home/hadoop/app/hadoop-2.6.0-cdh5.16.2/logs/yarn-hadoop-resourcemanager-aliyun.out
aliyun: starting nodemanager, logging to /home/hadoop/app/hadoop-2.6.0-cdh5.16.2/logs/yarn-hadoop-nodemanager-aliyun.out

[hadoop@aliyun hadoop]$ jps
32501 NodeManager
349 Jps
32415 ResourceManager

最后再用ps -ef命令验证ResourceManager程序是否真的启动完成

[hadoop@aliyun hadoop]$ netstat -nlp|grep 32415
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
tcp 0 0 172.16.39.48:38088 0.0.0.0:* LISTEN 32415/java
tcp 0 0 0.0.0.0:8030 0.0.0.0:* LISTEN 32415/java
tcp 0 0 0.0.0.0:8031 0.0.0.0:* LISTEN 32415/java
tcp 0 0 0.0.0.0:8032 0.0.0.0:* LISTEN 32415/java
tcp 0 0 0.0.0.0:8033 0.0.0.0:* LISTEN 32415/java

启动完成,可以去玩wordcount案例了

使用MapReduce运行WordCount案例

在data目录下创建mapreduce的输入文件

[hadoop@aliyun data]$ vim name.log

ruozedata
ruoze
jepson
huhu
ye
tunan
afei
1
2
3
3
2
1
a b c a a aaaa bcd
ruoze jepson

把name.log文件put到hdfs上

[hadoop@aliyun data]$ hdfs dfs -mkdir -p /wordcount/input
[hadoop@aliyun data]$ hdfs dfs -put name.log /wordcount/input
[hadoop@aliyun data]$ hdfs dfs -ls /wordcount/input/
Found 1 items
-rw-r--r-- 1 hadoop supergroup 86 2019-12-01 17:46 /wordcount/input/name.log

使用hadoop jar 运行案例

hadoop jar share/hadoop/mapreduce2/hadoop-mapreduce-examples-2.6.0-cdh5.16.2.jar wordcount /wordcount/input /wordcount/output

查看结果

[hadoop@aliyun hadoop]$ hdfs dfs -cat /wordcount/output/*
1 2
2 2
3 2
a 3
aaaa 1
afei 1
b 1
bcd 1
c 1
huhu 1
jepson 2
ruoze 2
ruozedata 1
tunan 1
ye 1

jps命令不为人知的地方

我们想既然jps可以直接运行,肯定在APTH路径下,我们何不which一下看看

[hadoop@aliyun hadoop]$ which jps
/usr/java/jdk/bin/jps

原来jps是一个java命令,我们使用一下jps看看它有什么作用

[hadoop@aliyun hadoop]$ jps
883 DataNode
2117 Jps
32501 NodeManager
1082 SecondaryNameNode
781 NameNode
32415 ResourceManager

jps命令打印出来了hadoop组件里面的程序pid和程序名,引申出这些程序都属于java程序,结合jps属于java命令,得出jps打印出来所有运行的java程序

我们可以从启动程序的脚本中得到pid和程序名存放的文件,这里就不去debug,他们默认存放在/tmp目录下一个叫做hsperfdata_用户名的文件下

[hadoop@aliyun tmp]$ ll hsperfdata_hadoop/
total 160
-rw------- 1 hadoop hadoop 32768 Dec 1 18:08 1082
-rw------- 1 hadoop hadoop 32768 Dec 1 18:08 32415
-rw------- 1 hadoop hadoop 32768 Dec 1 18:08 32501
-rw------- 1 hadoop hadoop 32768 Dec 1 18:08 781
-rw------- 1 hadoop hadoop 32768 Dec 1 18:08 883

每个pid对应是一些二进制文件,没啥好看的,我们发现这个文件下还有一些以pid结尾的文件,文件保存的其实也是各自对应的pid号码,但是这里的.pid文件是进程自己创建的。用来管理和结束进程的。

[hadoop@aliyun tmp]$ ll grep *.pid
-rw-rw-r-- 1 hadoop hadoop 4 Dec 1 17:39 hadoop-hadoop-datanode.pid
-rw-rw-r-- 1 hadoop hadoop 4 Dec 1 17:39 hadoop-hadoop-namenode.pid
-rw-rw-r-- 1 hadoop hadoop 5 Dec 1 17:39 hadoop-hadoop-secondarynamenode.pid
-rw-rw-r-- 1 hadoop hadoop 6 Dec 1 17:37 yarn-hadoop-nodemanager.pid
-rw-rw-r-- 1 hadoop hadoop 6 Dec 1 17:37 yarn-hadoop-resourcemanager.pid
[hadoop@aliyun tmp]$ cat hadoop-hadoop-datanode.pid 
883

所以jps命令的作用就明白了,在使用jsp命令时,会去/tmp目录下/hsperfdata_username目录下找到程序的pid和程序名并打印出来,/tmp/hsperfdata_username目录会存放该用户所有已经启动的java进程信息。

这里需要get到一个很关键的知识点,它可能让你在shell脚本中犯错,那就是进程所属的用户去执行 jps命令,只显示自己的相关的进程信息,也就是说,其他用户使用jps命令查看不到本用户启动的程序,root用户可以看所有的,但是显示不可用,我们这里就用root用户尝试一下

我在这里翻车了,使用root显示出来了所有的进程,原因不明,但是其他普通用户无法显示

aliyun:mysqladmin:/usr/local/mysql:>jps
2346 Jps

这同样能得出我们想要的结果,那就是其他用户使用jps不能查看到本用户启动的java程序。其原理我们看看这个文件夹的权限就知道了

[hadoop@aliyun tmp]$ ll hsperfdata_hadoop/
total 128
-rw------- 1 hadoop hadoop 32768 Dec 1 18:26 1082
-rw------- 1 hadoop hadoop 32768 Dec 1 18:26 32415
-rw------- 1 hadoop hadoop 32768 Dec 1 18:26 32501
-rw------- 1 hadoop hadoop 32768 Dec 1 18:26 781

最后总结一下我们在判断一个程序是否在运行时,切不可使用jps命令,因为jps命令只能查看本用户的java进程,那我们在shell脚本中应该如何判断一个程序是否存在?使用万能的ps -ef。

[hadoop@aliyun tmp]$ ps -ef|grep 781 | grep -v grep | wc -l
1

Linux的oom-kill和clean机制

在最后我们说一下在使用hadoop时会遇到的两个坑,而且还都是Linux自带的特性,以及解决的方法。

oom-killer机制: 大数据程序是非常吃内存的,而在Linux内核检测到系统内存不足后,会触发oom-killer,挑选占用最大内存的进程杀掉。

如果我们的进程突然断了,首先查看日志找EROOR,有ERROR具体分析,没有ERROR但是INFO信息断了,很可能就是触发了oom-killer机制,使用free -h命令查看内存使用情况,再使用cat /var/log/messages | grep oom命令查看有没有类似于Killed process 的命令,如果有,就是触发了oom-killer机制

clean机制: Linux的/tmp目录是一个临时目录,它有一个机制,默认清理超过30天的内容,而前面使用jps命令的时候就发现,hadoop的进程pid都存放在/tmp目录中,启动进程的时候去/tmp目录下创建对应的pid文件,结束进程的时候去/tmp目录下找到程序对应的pid用来结束进程并删除pid文件,那么引申出来一个问题,如果我们的hadoop组件进程启动时间超过了30天了呢,pid文件被清理,结束命令找不到pid号,会再重新创建一个pid,结果就是pid号紊乱,进程无法正常结束。

解决的办法就是在家目录下面创建一个tmp目录,然后把hdfs和yarn的pid号管理文件夹设置成家目录下的tmp目录即可。

[hadoop@aliyun hadoop]$ vi hadoop-env.sh
export HADOOP_PID_DIR=/home/hadoop/tmp

[hadoop@aliyun hadoop]$ cat yarn-env.sh
export YARN_PID_DIR=/home/hadoop/tmp
Author: Tunan
Link: http://yerias.github.io/2018/10/05/hadoop/2/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.