最近工作中遇到的问题,简单记录下。
工作中用到了 Hadoop/Hive,但是搭建的集群硬件配置很差,磁盘空间严重不足。我只好先找了台虚拟机,暂时凑合着用一下,好歹硬盘算是够用了。
但是没过两天,发现用 Hive 执行 HiveQL 语句时,经常出现下面的错误:
Caused by: org.apache.hadoop.hive.ql.metadata.HiveException: org.apache.hadoop.ipc.RemoteException(java.io.IOException): File /tmp/hive-hduser/hive_2013-11-26_13-14-51_742_5228871571450845489/_task_tmp.-ext-10002/_tmp.000003_0 could only be replicated to 0 nodes instead of minReplication (=1). There are 3 datanode(s) running and no node(s) are excluded in this operation. Container killed by the ApplicationMaster. Container killed on request. Exit code is 143 FAILED: Execution Error, return code 20002 from org.apache.hadoop.hive.ql.exec.MapRedTask. Hive encountered some unknown error while running your custom script.
这个错误并不陌生。如果硬盘空间不足,导致 HDFS 可用空间太少,就容易出现这个错。但问题是,我已经新增加了一台 slave,硬盘不足的问题应该已经解决了,怎么还会出现这个错误呢?
接着,便开始定位问题。SSH 登录到新增加的 slave 上,ps
发现进程状态正常:datanode 和 nodemanager 两个进程都在;master 和这台 slave 之间相互可 ping
通,似乎网络通信没有问题;hdfs dfsadmin -report
,看到所有 slave 的状态都是正常的;hdfs fsck / -files -blocks
,输出显示 HDFS 文件系统状态也是 HEALTHY……
但是,用 Hive 多跑几个任务后(其中有导入数据、删除旧表等操作),发现了可疑之处——那台新增加的 slave,它的 HDFS 使用率一直是不变的:hdfs dfsadmin -report
的输出,DFS Used
和 DFS Remaining
两项值都不变!
基本可以确定,问题出在 Hadoop 这一层,而不是它上层的 Hive。为确定 Hadoop 是否正常,我就跑了安装 Hadoo 时 Hadoop 官方的那个测试用例(计算 Pi
值),果然有错:
$ cd $HADOOP_INSTALL $ hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.2.0.jar pi 10 100 ... 13/12/24 16:08:03 INFO hdfs.DFSClient: Exception in createBlockOutputStream java.io.IOException: Bad connect ack with firstBadLink as xxx.xxx.xxx.xxx:50010 at org.apache.hadoop.hdfs.DFSOutputStream$DataStreamer.createBlockOutputStream(DFSOutputStream.java:1166) at org.apache.hadoop.hdfs.DFSOutputStream$DataStreamer.nextBlockOutputStream(DFSOutputStream.java:1088) at org.apache.hadoop.hdfs.DFSOutputStream$DataStreamer.run(DFSOutputStream.java:514) 13/12/24 16:08:03 INFO hdfs.DFSClient: Abandoning BP-1690188358-xxx.xxx.xxx.xxx-1384336389673:blk_1073751591_10794 13/12/24 16:08:03 INFO hdfs.DFSClient: Excluding datanode xxx.xxx.xxx.xxx:50010 (注:真实的 IP 地址,我这里统一用 xxx.xxx.xxx.xxx 替换掉了)
Google 下,看到这个链接。原来是 iptables
和 SELinux 的缘故。这时才想起来自己重启过那台 slave,而 iptables
和 SELinux 一直是开机启动的。算是一个低级错误了吧。
关掉防火墙 # service iptables stop 停用 SELinux # setenforce 0
OK! Hadoop 和 Hive 都正常鸟。至于原因嘛,太简单了,我不好意思说出口。:-)
两点启示:
- 想要准确地定位问题所在,最好能估计(并验证)问题大概出现在哪个层面上,然后在做进一步的定位。
就好像网络不通时,经常会依次去
ping
这些地址:localhost、内网 IP、网关、外网 IP、域名。(当然,Linux 下用mtr
分析网络状况,结果一目了然) - 别再用
ping
判断网络通信是否正常,应该用telnet
/netcat
测试端口/服务是否可用。如果我一开始就用
telnet xxx.xxx.xxx.xxx 50010
验证,就能省不少事儿了。
引以为鉴。