最近工作中遇到的问题,简单记录下。

工作中用到了 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 UsedDFS 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 验证,就能省不少事儿了。

 

引以为鉴。

Leave a Reply

Your email address will not be published. Required fields are marked *