文章目录
  1. 1. 错误集锦
    1. 1.1. HDFS:DataNode不在线,使得出现Namenode in safe mode错误
    2. 1.2. 集群时间不同步问题
    3. 1.3. Hadoop YARN 报 Unhealthy Nodes
    4. 1.4. Hadoop YARN 执行Task时报 Connection Refused.
  2. 2. References

本文记录Hadoop,HDFS,YARN,HBase,Hive等Hadoop社区的系统使用中的一些问题及解决方案,
包括Hadoop集群构建及使用中的一些问题以及解决方案,
包括各种莫名其妙的安装问题,
配置问题,
运行问题,
运行中问题,
等等等等,
积累以备后查,
也方便后来者参考之。
如对大家有所帮助,
对笔者也是一份欣慰。

错误集锦

HDFS:DataNode不在线,使得出现Namenode in safe mode错误

打开Hadoop webUI可以看到类似情况:

1
2
3
4
5
6
7
8
9
Security is off.

Safe mode is ON. The reported blocks 0 needs additional 178895 blocks to reach the threshold 0.9990 of total blocks 179074. The number of live datanodes 0 has reached the minimum number 0. Safe mode will be turned off automatically once the thresholds have been reached.

184051 files and directories, 179074 blocks = 363125 total filesystem object(s).

Heap Memory used 297.78 MB of 1.28 GB Heap Memory. Max Heap Memory is 1.78 GB.

Non Heap Memory used 31.27 MB of 31.81 MB Commited Non Heap Memory. Max Non Heap Memory is 130 MB.

【原因分析】
查看datanode日志出现:

1
2
2017-10-23 09:15:33,336 INFO org.apache.hadoop.ipc.Client: Retrying connect to server: master01/115.212.0.91:9000. Already tried 9 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1000 MILLISECONDS)
2017-10-23 09:15:33,337 WARN org.apache.hadoop.hdfs.server.datanode.DataNode: Problem connecting to server: master01/115.212.0.91:9000

类似错误

于是使用:netstat -an | grep 9000查看端口

1
2
3
[root@master01 etc]# netstat -an | grep 9000
tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:55294 127.0.0.1:9000 TIME_WAIT

这表明,只有127.0.0.1上的9000端口启动了,故只有本机才能访问127.0.0.1:9000了,故datanode无法联通namenode。

查看/etc/hosts文件,如下:

1
2
3
4
127.0.0.1   master01      localhost.localdomain   localhost
::1 master01 localhost6.localdomain6 localhost6

115.212.0.91 master01

由hosts文件可以看到,master01在赋值为114.212.190.91之前被赋值到了127.0.0.1,以及IPv6的::1上。

【解决方案】把前两行的master01删去,得到:

1
2
3
4
127.0.0.1        localhost.localdomain   localhost
::1 localhost6.localdomain6 localhost6

115.212.0.91 master01

这样启动的就会是115.212.0.91:9000,datanode也可以连到namenode了。

最后查看端口监听情况:

1
2
3
4
5
6
7
8
[hadoop@master01 sbin]$ netstat -an | grep 9000
tcp 0 0 115.212.0.91:9000 0.0.0.0:* LISTEN
tcp 0 0 115.212.0.91:9000 115.212.0.91:56574 ESTABLISHED
tcp 0 0 115.212.0.91:9000 192.168.1.18:35381 ESTABLISHED
tcp 0 0 115.212.0.91:9000 192.168.1.15:60196 ESTABLISHED
tcp 0 0 115.212.0.91:56573 115.212.0.91:9000 TIME_WAIT
tcp 0 0 115.212.0.91:9000 192.168.1.6:42243 ESTABLISHED
........

成功。

集群时间不同步问题

集群运行example程序出现时间不一致的问题。

1
2
3
4
17/10/23 10:50:24 INFO mapreduce.Job: Task Id : attempt_1508726229114_0001_m_000000_1, Status                  : FAILED
Container launch failed for container_1508726229114_0001_01_000007 : org.apache.hadoop.yarn.ex ceptions.YarnException: Unauthorized request to start container.
This token is expired. current time is 1508729210138 found 1508728023578
Note: System times on machines may be out of sync. Check system time and time zones.

【解决方案1】手动同步时间,在每台机器上date -s ...设置同样的时间

【解决方案2】使用NTP时间服务器来同步时间(也需要所有机器上运行一次,但是后面可以一直按时同步)

默认master和slaves都安装好了ntpd服务(centOS好像默认有),可以通过如下命令查看:

1
2
[root@node1 ~]# rpm -q ntp
ntp-4.2.4p8-2.el6.x86_64

每个节点都需要配置NTP服务为自启动

1
2
3
[root@master ~]# chkconfig ntpd on
[root@master ~]# chkconfig --list ntpd
ntpd 0:off 1:off 2:on 3:on 4:on 5:on 6:off

然后在master上修改配置文件:

1
[root@master ~]# vim /etc/ntp.conf

如下编辑,(如下是conf文件部分信息)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
restrict 127.0.0.1
restrict -6 ::1

# Hosts on local network are less restricted.
restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap

# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
# server 114.212.190.91 prefer
# server 0.rhel.pool.ntp.org
# server 1.rhel.pool.ntp.org
# server 2.rhel.pool.ntp.org
server 210.72.145.44 perfer
server 202.112.10.36
server 59.124.196.83
server 192.168.1.1 # 局域网NTP服务器的IP
#broadcast 192.168.1.255 autokey # broadcast server
#broadcastclient # broadcast client
#broadcast 224.0.1.1 autokey # multicast server
#multicastclient 224.0.1.1 # multicast client
#manycastserver 239.255.254.254 # manycast server
#manycastclient 239.255.254.254 autokey # manycast client

# Undisciplined Local Clock. This is a fake driver intended for backup
# and when no outside source of synchronized time is available.
server 127.127.1.0 # local clock
fudge 127.127.1.0 stratum 10

主要的修改有:

  • 添加了restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap表示192.168.1.1-192.168.1.255的IP地址都可以访问本NTP服务器。
  • 添加了server 210.72.145.44 perfer开始的4行,尤其最后一个局域网NTP服务器的IP很重要,后面从节点的时间都要与此IP(master)来同步,相当于一个权威时间服务器。

遇到的一些问题:

  • slave上运行ntpdate <masterIP>出现bind() fails: Permission denied【解决方案】没有权限,用root做
  • slave上运行ntpdate <masterIP>出现23 Oct 13:11:05 ntpdate[1454]: the NTP socket is in use, exiting 【解决方案】lsof -i:123 然后 kill -9 pid 再重新尝试即可

crontab自动同步,crontab是自动运行的服务,可以让机器自动按一定周期进行时间同步。
【方法】在每台机器上

1
2
crontab -u root -e   # 新建root的crontab文件并编辑,写入如下语句
* */24 * * * /usr/sbin/ntpdate 192.168.1.1 # 24小时同步一次

这样每24小时,所有的worker都会自动与时间服务器192.168.1.1上的时间同步一次,应该不会再出现时间不同步的问题了,除非机器重启可能会早造成设置改变等,还没有遇到,等遇到了再写。

Hadoop YARN 报 Unhealthy Nodes

Healthy报告如下:

1
2
1/1 local-dirs are bad: /data/hadoop_tmp/nm-local-dir;
1/1 log-dirs are bad: /data/hadoop_logs/userlogs

【原因分析】网上说最常见原因是由于节点上的磁盘使用率超出了max-disk-utilization-per-disk-percentage(默认为90.0%)。
确实是这个原因,但是这个可能只是表面原因。可以通过增加磁盘利用率阈值来缓解问题:
yarn-site.xml中填写:

1
2
3
4
<property>
<name>yarn.nodemanager.disk-health-checker.max-disk-utilization-per-disk-percentage</name>
<value>98.5</value>
</property>

但是增加阈值的方法治标不治本,迟早有一天会超过你设置的98.5%。
所以最好是清理磁盘空间。
清理磁盘空间发现/data目录用量极大,说明HDFS很满,用如下命令查看HDFS各目录大小:

1
2
3
4
5
[hadoop@machine ~]$ hadoop fs -du -h /
12.1 G /data
1.6 T /tmp
2.8 T /user
0 /user41

发现/tmp目录页用量巨大,再细看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[hadoop@machine ~]$ hadoop fs -du -h /tmp
55.2 M /tmp/2017st08
321.7 M /tmp/2017st22
9.2 K /tmp/2017st26
53.6 M /tmp/MF1733016
2 /tmp/b.txt
36 /tmp/files
17.7 G /tmp/hadoop-yarn
255.9 M /tmp/input
1.6 T /tmp/logs # logs极大
4 /tmp/out
1.5 M /tmp/out2
1.5 M /tmp/out3
108.0 M /tmp/output
36 /tmp/test-in
2.1 M /tmp/test.txt
31.0 M /tmp/twitter_graph_v2.txt

由上可以发现,日志文件居然占据1.6T的空间,不可容许。
查看yarn-site.xml,发现有两点:
1) 开启了log-aggregation:

1
2
3
4
5
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
<source>java.io.BufferedInputStream@1bf57bb</source>
</property>

开启了日志聚合服务之后,用户程序运行生成的日志会自动传到HDFS的/tmp目录下,如果不设置自动清空时间的话,日志将一直累积。
2)没有设置retain-seconds,即保存时间

1
2
3
4
5
<property>
<name>yarn.log-aggregation.retain-seconds</name>
<value>-1</value>
<source>yarn-default.xml</source>
</property>

默认永久保存。

但是其实发现集群并没有开启history-server服务,所以这些日志都白记录了。

【解决方案】所以要么关闭log-aggregation,要么设置一定的保持时间,超过保持时间自动清除。
【总结】我们看到,有时其实表面原因下,隐藏着更深刻的问题,找到最关键的地方,治其本才是最一劳永逸的。

Hadoop YARN 执行Task时报 Connection Refused.

遇到FAILED问题

master01:19888/jobhistory/...查看map task的log信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2018-02-09 21:18:26,815 WARN [main] org.apache.hadoop.mapred.YarnChild: Exception running child : java.net.ConnectException: Call From slave015/127.0.0.1 to slave015:38953 failed on connection exception: java.net.ConnectException: Connection refused; For more details see:  http://wiki.apache.org/hadoop/ConnectionRefused
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at org.apache.hadoop.net.NetUtils.wrapWithMessage(NetUtils.java:792)
at org.apache.hadoop.net.NetUtils.wrapException(NetUtils.java:732)
at org.apache.hadoop.ipc.Client.call(Client.java:1480)
at org.apache.hadoop.ipc.Client.call(Client.java:1407)
at org.apache.hadoop.ipc.WritableRpcEngine$Invoker.invoke(WritableRpcEngine.java:242)
at com.sun.proxy.$Proxy7.getTask(Unknown Source)
at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:132)
Caused by: java.net.ConnectException: Connection refused

at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)
at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:739)
at org.apache.hadoop.net.SocketIOWithTimeout.connect(SocketIOWithTimeout.java:206)
at org.apache.hadoop.net.NetUtils.connect(NetUtils.java:531)
at org.apache.hadoop.net.NetUtils.connect(NetUtils.java:495)
at org.apache.hadoop.ipc.Client$Connection.setupConnection(Client.java:609)
at org.apache.hadoop.ipc.Client$Connection.setupIOstreams(Client.java:707)
at org.apache.hadoop.ipc.Client$Connection.access$2800(Client.java:370)
at org.apache.hadoop.ipc.Client.getConnection(Client.java:1529)
at org.apache.hadoop.ipc.Client.call(Client.java:1446)
... 4 more

【问题分析】
发现这么一条:

1
Call From slave015/127.0.0.1 to localhost.localdomain:38953  failed on connection exception.

在分布式集群中,一般遇到Connection refused问题,大概率是hosts解析有问题。

查看/etc/hosts文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
127.0.0.1       slave015        localhost.localdomain   localhost
#::1 localhost6.localdomain6 localhost6
#::1 master01 localhost6.localdomain6 localhost6
#::1 master01 localhost6.localdomain6 localhost6
115.212.190.91 master01
192.168.1.2 slave002
192.168.1.3 slave003
192.168.1.4 slave004
192.168.1.5 slave005
192.168.1.6 slave006
192.168.1.7 slave007
192.168.1.8 slave008
192.168.1.9 slave009
192.168.1.10 slave010
192.168.1.11 slave011
192.168.1.12 slave012
192.168.1.13 slave013
192.168.1.14 slave014
192.168.1.15 slave015
192.168.1.16 slave016

注意第一行的,前三项依次代表内网IP,主机名,主机别名。
也就是说,主机是slave015把自己解析成127.0.0.1,同样地,别的机器也部分出现了这种情况,所以大概的一个错误原因分析如下:
在yarn集群中,一些主机会在一个临时端口(假如如上是38953)启动job tracker,然后任意主机的task tracker向此job tracker拉取任务时,job tracker会把自己的地址和端口发送给需求的task tracker,然后task tracker自己去此端口拉取任务。
如果job tracker的hosts设置错误,假如如上解析为本机地址,那么job tracker会将127.0.0.1,即别名为localhost.localdomain的地址发给task tracker(在本例为slave015),所以slave015开始向localhost.localdomain:38953去拉取任务或者信息,但是对于slave015而言,localhost.localdomain是本机地址,而本机地址没有38953端口!所以会造成Connection refused。
当然可能造成这个的原因不止这一个,也可能不是这一个,我们可以在master:8088/cluster中查看log来判断解决。如果无法跳转到master01:19888/jobhistory,那么需要在本机(webUI端)设置一条hosts规则:

1
115.212.190.91  master01

【解决方案】
把所有设置错误的节点修正过来。删掉第二个条目(如slave015)。

1
127.0.0.1        localhost.localdomain   localhost

其实之前的hosts设置是OK的,只不过机器硬件重启之后,hosts设置又还原了。在分布式集群中就是这样,很难保证机器全部非常健康的运转。

References