Hadoop使用常见问题以及解决方法 (转)

Hadoop使用常见问题以及解决方法 .

作者:keda8997110 和 linux相关  
http://biancheng.dnbcw.info/linux/441854.html
1:Shuffle Error: Exceeded MAX_FAILED_UNIQUE_FETCHES; bailing-out
Answer:
程序里面需要打开多个文件,进行分析,系统一般默认数量是1024,(用ulimit -a可以看到)对于正常使用是够了,但是对于程序来讲,就太少了。
修改办法:
修改2个文件。
        /etc/security/limits.conf
vi /etc/security/limits.conf
加上:
* soft nofile 102400
* hard nofile 409600

    $cd /etc/pam.d/
    $sudo vi login
        添加        session    required     /lib/security/pam_limits.so

针对第一个问题我纠正下答案:
这是reduce预处理阶段shuffle时获取已完成的map的输出失败次数超过上限造成的,上限默认为5。引起此问题的方式可能会有很多种,比如网络连接不正常,连接超时,带宽较差以及端口阻塞等。。。通常框架内网络情况较好是不会出现此错误的。

2:Too many fetch-failures
Answer:
出现这个问题主要是结点间的连通不够全面。
1) 检查 、/etc/hosts
   要求本机ip 对应  服务器名
   要求要包含所有的 服务器ip + 服务器名
2) 检查 .ssh/authorized_keys
   要求包含所有服务器(包括其自身)的public key

3:处理速度特别的慢 出现map很快 但是reduce很慢 而且反复出现 reduce=0% 
Answer:
结合第二点,然后
修改 conf/hadoop-env.sh 中的export HADOOP_HEAPSIZE=4000 

4:能够启动datanode,但无法访问,也无法结束的错误
在重新格式化一个新的分布式文件时,需要将你NameNode上所配置的dfs.name.dir这一namenode用来存放NameNode 持久存储名字空间及事务日志的本地文件系统路径删除,同时将各DataNode上的dfs.data.dir的路径 DataNode 存放块数据的本地文件系统路径的目录也删除。如本此配置就是在NameNode上删除/home/hadoop/NameData,在DataNode上删除/home/hadoop/DataNode1和/home/hadoop/DataNode2。这是因为Hadoop在格式化一个新的分布式文件系统时,每个存储的名字空间都对应了建立时间的那个版本(可以查看/home/hadoop /NameData/current目录下的VERSION文件,上面记录了版本信息),在重新格式化新的分布式系统文件时,最好先删除NameData 目录。必须删除各DataNode的dfs.data.dir。这样才可以使namedode和datanode记录的信息版本对应。
注意:删除是个很危险的动作,不能确认的情况下不能删除!!做好删除的文件等通通备份!!

5: java.io.IOException: Could not obtain block: blk_194219614024901469_1100 file=/user/hive/warehouse/src_20090724_log/src_20090724_log
出现这种情况大多是结点断了,没有连接上。

6: java.lang.OutOfMemoryError: Java heap space
出现这种异常,明显是jvm内存不够得原因,要修改所有的datanode的jvm内存大小。
Java -Xms1024m -Xmx4096m

一般jvm的最大内存使用应该为总内存大小的一半,我们使用的8G内存,所以设置为4096m,这一值可能依旧不是最优的值。

7: Namenode in safe mode 
解决方法
bin/hadoop dfsadmin -safemode leave

8:java.net.NoRouteToHostException: No route to host
j解决方法:
sudo /etc/init.d/iptables stop

9:更改namenode后,在hive中运行select 依旧指向之前的namenode地址
这是因为:When youcreate a table, hive actually stores the location of the table (e.g.
hdfs://ip:port/user/root/...) in the SDS and DBS tables in the metastore . So when I bring up a new cluster the master has a new IP, but hive's metastore is still pointing to the locations within the old
cluster. I could modify the metastore to update with the new IP everytime I bring up a cluster. But the easier and simpler solution was to just use an elastic IP for the master
所以要将metastore中的之前出现的namenode地址全部更换为现有的namenode地址

10:Your DataNode is started and you can create directories with bin/hadoop dfs -mkdir, but you get an error message when you try to put files into the HDFS (e.g., when you run a command like bin/hadoop dfs -put).
解决方法:
Go to the HDFS info web page (open your web browser and go to http://namenode:dfs_info_port where namenode is the hostname of your NameNode and dfs_info_port is the port you chose dfs.info.port; if followed the QuickStart on your personal computer then this URL will be http://localhost:50070). Once at that page click on the number where it tells you how many DataNodes you have to look at a list of the DataNodes in your cluster.
If it says you have used 100% of your space, then you need to free up room on local disk(s) of the DataNode(s).
If you are on Windows then this number will not be accurate (there is some kind of bug either in Cygwin's df.exe or in Windows). Just free up some more space and you should be okay. On one Windows machine we tried the disk had 1GB free but Hadoop reported that it was 100% full. Then we freed up another 1GB and then it said that the disk was 99.15% full and started writing data into the HDFS again. We encountered this bug on Windows XP SP2.
11:Your DataNodes won't start, and you see something like this in logs/*datanode*:
Incompatible namespaceIDs in /tmp/hadoop-ross/dfs/data
原因:
Your Hadoop namespaceID became corrupted. Unfortunately the easiest thing to do reformat the HDFS.
解决方法:
You need to do something like this:
bin/stop-all.sh
rm -Rf /tmp/hadoop-your-username/*
bin/hadoop namenode -format
12:You can run Hadoop jobs written in Java (like the grep example), but your HadoopStreaming jobs (such as the Python example that fetches web page titles) won't work.
原因:
You might have given only a relative path to the mapper and reducer programs. The tutorial originally just specified relative paths, but absolute paths are required if you are running in a real cluster.
解决方法:
Use absolute paths like this from the tutorial:
bin/hadoop jar contrib/hadoop-0.15.2-streaming.jar \
  -mapper  $HOME/proj/hadoop/multifetch.py         \
  -reducer $HOME/proj/hadoop/reducer.py            \
  -input   urls/*                                  \
  -output  titles


13: 2009-01-08 10:02:40,709 ERROR metadata.Hive (Hive.java:getPartitions(499)) - javax.jdo.JDODataStoreException: Required table missing : ""PARTITIONS"" in Catalog "" Schema "". JPOX requires this table to perform its persistence operations. Either your MetaData is incorrect, or you need to enable "org.jpox.autoCreateTables"
原因:就是因为在 hive-default.xml 里把 org.jpox.fixedDatastore 设置成 true 了

14:09/08/31 18:25:45 INFO hdfs.DFSClient: Exception in createBlockOutputStream java.io.IOException:Bad connect ack with firstBadLink 192.168.1.11:50010
> 09/08/31 18:25:45 INFO hdfs.DFSClient: Abandoning block blk_-8575812198227241296_1001
> 09/08/31 18:25:51 INFO hdfs.DFSClient: Exception in createBlockOutputStream java.io.IOException:
Bad connect ack with firstBadLink 192.168.1.16:50010
> 09/08/31 18:25:51 INFO hdfs.DFSClient: Abandoning block blk_-2932256218448902464_1001
> 09/08/31 18:25:57 INFO hdfs.DFSClient: Exception in createBlockOutputStream java.io.IOException:
Bad connect ack with firstBadLink 192.168.1.11:50010
> 09/08/31 18:25:57 INFO hdfs.DFSClient: Abandoning block blk_-1014449966480421244_1001
> 09/08/31 18:26:03 INFO hdfs.DFSClient: Exception in createBlockOutputStream java.io.IOException:
Bad connect ack with firstBadLink 192.168.1.16:50010
> 09/08/31 18:26:03 INFO hdfs.DFSClient: Abandoning block blk_7193173823538206978_1001
> 09/08/31 18:26:09 WARN hdfs.DFSClient: DataStreamer Exception: java.io.IOException: Unable
to create new block.
>         at org.apache.hadoop.hdfs.DFSClient$DFSOutputStream.nextBlockOutputStream(DFSClient.java:2731)
>         at org.apache.hadoop.hdfs.DFSClient$DFSOutputStream.access$2000(DFSClient.java:1996)
>         at org.apache.hadoop.hdfs.DFSClient$DFSOutputStream$DataStreamer.run(DFSClient.java:2182)

> 09/08/31 18:26:09 WARN hdfs.DFSClient: Error Recovery for block blk_7193173823538206978_1001
bad datanode[2] nodes == null
> 09/08/31 18:26:09 WARN hdfs.DFSClient: Could not get block locations. Source file "/user/umer/8GB_input"
- Aborting...
> put: Bad connect ack with firstBadLink 192.168.1.16:50010


解决方法:
I have resolved the issue:
What i did: 


1) '/etc/init.d/iptables stop' -->stopped firewall
2) SELINUX=disabled in '/etc/selinux/config' file.-->disabled selinux
I worked for me after these two changes

15:把IP换成主机名,datanode 挂不上
解决方法:
把temp文件删除,重启hadoop集群就行了
是因为多次部署,造成temp文件与namenode不一致的原因

 

 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 

 

一、hadoop集群在namenode格式化(bin/hadoop namenode -format)后重启集群会出现如下

Incompatible namespaceIDS in … :namenode namespaceID = … ,datanode namespaceID=…

错误,原因是格式化namenode后会重新创建一个新的namespaceID,以至于和datanode上原有的不一致。

解决方法:

  1. 删除datanode dfs.data.dir目录(默认为tmp/dfs/data)下的数据文件
  2. 修改dfs.data.dir/current/VERSION 文件,把namespaceID修成与namenode上相同即可(log错误里会有提示)
  3. 重新指定新的dfs.data.dir目录

二、hadoop集群启动start-all.sh的时候,slave总是无法启动datanode,并会报错:

… could only be replicated to 0 nodes, instead of 1 …

就是有节点的标识可能重复(个人认为这个错误的原因)。也可能有其他原因,一下解决方法请依次尝试,我是解决了。
解决方法:

  1. 删除所有节点dfs.data.dir和dfs.tmp.dir目录(默认为tmp/dfs/data和tmp/dfs/tmp)下的数据文件;然后重新hadoop namenode -format 格式化节点;然后启动。
  2. 如果是端口访问的问题,你应该确保所用的端口都打开,比如hdfs://machine1:9000/、50030、50070之类的。执行#iptables -I INPUT -p tcp –dport 9000 -j ACCEPT 命令。如果还有报错:hdfs.DFSClient: Exception in createBlockOutputStream java.net.ConnectException: Connection refused;应该是datanode上的端口不能访问,到datanode上修改iptables:#iptables -I INPUT -s machine1 -p tcp -j ACCEPT
  3. 还有可能是防火墙的限制集群间的互相通信。尝试关闭防火墙。/etc/init.d/iptables stop
  4. 最后还有可能磁盘空间不够了,请查看 df -al
  5. 我在解决这个问题的时候还有人说:先后启动namenode、datanode可以解决这个问题(本人尝试发现没用,大家可以试试)$hadoop-daemon.sh start namenode ; $hadoop-daemon.sh start datanode

三、程序执行出现Error: java.lang.NullPointerException
空指针异常,确保java程序的正确。变量什么的使用前先实例化声明,不要有数组越界之类的现象。检查程序。

四、执行自己的程序的时候,(各种)报错,请确保一下情况:

  1. 前提都是你的程序是正确通过编译的
  2. 集群模式下,请把要处理的数据写到HDFS里,并且确保HDFS路径正确
  3. 指定执行的jar包的入口类名(我不知道为什么有时候不指定也是可以运行的)

正确的写法类似:

$ hadoop jar myCount.jar myCount input output

五、ssh无法正常通信的问题,这个问题我在搭建篇里有详细提到过。

六、程序编译问题,各种包没有的情况,请确保你把hadoop目录下 和hadoop/lib目录下的jar包都有引入。详细情况也是看搭建篇里的操作。

七、Hadoop启动datanode时出现Unrecognized option: -jvm 和 Could not create the Java virtual machine.
在hadoop安装目录/bin/hadoop中有如下一段shell:

View Code SHELL
1
2
3
4
5
6
CLASS='org.apache.hadoop.hdfs.server.datanode.DataNode'
  if [[ $EUID -eq 0 ]]; then
    HADOOP_OPTS="$HADOOP_OPTS -jvm server $HADOOP_DATANODE_OPTS"
  else
    HADOOP_OPTS="$HADOOP_OPTS -server $HADOOP_DATANODE_OPTS"
  fi

$EUID 这里的用户标识,如果是root的话,这个标识会是0,所以尽量不要使用root用户来操作hadoop就好了。这也是我在配置篇里提到不要使用root用户的原因。

八、如果出现终端的错误信息是:

ERROR hdfs.DFSClient: Exception closing file /user/hadoop/musicdata.txt : java.io.IOException: All datanodes 10.210.70.82:50010 are bad. Aborting…

还有jobtracker log的报错信息

Error register getProtocolVersion
java.lang.IllegalArgumentException: Duplicate metricsName:getProtocolVersion

和可能的一些警告信息:

WARN hdfs.DFSClient: DataStreamer Exception: java.io.IOException: Broken pipe
WARN hdfs.DFSClient: DFSOutputStream ResponseProcessor exception for block blk_3136320110992216802_1063java.io.IOException: Connection reset by peer
WARN hdfs.DFSClient: Error Recovery for block blk_3136320110992216802_1063 bad datanode[0] 10.210.70.82:50010 put: All datanodes 10.210.70.82:50010 are bad. Aborting…

解决办法:

  1. 查看dfs.data.dir属性所指的路径是否磁盘已经满了,如果满了则进行处理后再次尝试hadoop fs -put数据。
  2. 如果相关磁盘没有满,则需要排查相关磁盘没有坏扇区,需要检测。

九、如果在执行hadoop的jar程序时得到报错信息:

java.io.IOException: Type mismatch in key from map: expected org.apache.hadoop.io.NullWritable, recieved org.apache.hadoop.io.LongWritable
或者类似:
Status : FAILED java.lang.ClassCastException: org.apache.hadoop.io.LongWritable cannot be cast to org.apache.hadoop.io.Text

那么你需要学习hadoop数据类型和 map/reduce模型的基本知识。我的这篇读书笔记里边中间部分有介绍hadoop定义的数据类型和自定义数据类型的方法(主要是对writable类的学习和了解);和这篇里边说的MapReduce的类型和格式。也就是《hadoop权威指南》这本书的第四章Hadoop I/O和第七章MapReduce的类型和格式。如果你急于解决这个问题,我现在也可以告诉你迅速的解决之道,但这势必影响你以后开发:
确保一下数据的一致:

… extends Mapper…
public void map(k1 k, v1 v, OutputCollector output)…

…extends Reducer…
public void reduce(k2 k,v2 v,OutputCollector output)…

job.setMapOutputKeyClass(k2.class);
job.setMapOutputValueClass(k2.class);

job.setOutputKeyClass(k3.class);
job.setOutputValueClass(v3.class);

注意 k* 和 v*的对应。建议还是看我刚才说的两个章节。详细知道其原理。

十、如果碰到datanode报错如下:

ERROR org.apache.hadoop.hdfs.server.datanode.DataNode: java.io.IOException: Cannot lock storage /data1/hadoop_data. The directory is already locked.

根据错误提示来看,是目录被锁住,无法读取。这时候你需要查看一下是否有相关进程还在运行或者slave机器的相关hadoop进程还在运行,结合linux这俩命令来进行查看:

netstat -nap
ps -aux | grep 相关PID

如果有hadoop相关的进程还在运行,就使用kill命令干掉即可。然后再重新使用start-all.sh。

十一、如果碰到jobtracker报错如下:

Shuffle Error: Exceeded MAX_FAILED_UNIQUE_FETCHES; bailing-out.

解决方式,修改datanode节点里/etc/hosts文件。
简单介绍下hosts格式:
每行分为三个部分:第一部分网络IP地址、第二部分主机名或域名、第三部分主机别名
操作的详细步骤如下:
1、首先查看主机名称:

cat /proc/sys/kernel/hostname

会看到一个HOSTNAME的属性,把后边的值改成IP就OK,然后退出。
2、使用命令:

hostname ***.***.***.***

星号换成相应的IP。
3、修改hosts配置类似内容如下:

127.0.0.1  localhost.localdomain       localhost
::1      localhost6.localdomain6  localhost6
10.200.187.77   10.200.187.77   hadoop-datanode

如果配置后出现IP地址就表示修改成功了,如果还是显示主机名就有问题了,继续修改这个hosts文件,
如下图:


上图提醒下,chenyi是主机名。
Hadoop使用常见问题以及解决方法 (转)_第1张图片

当在测试环境里,自己再去部署一个域名服务器(个人觉得很繁琐),所以简单地方式,就直接用IP地址比较方便。如果有了域名服务器的话,那就直接进行映射配置即可。

如果还是出现洗牌出错这个问题,那么就试试别的网友说的修改配置文件里的hdfs-site.xml文件,添加以下内容:

dfs.http.address
*.*.*.*:50070 端口不要改,星号换成IP,因为hadoop信息传输都是通过HTTP,这个端口是不变的。

十一、如果碰到jobtracker报错如下:

java.lang.RuntimeException: PipeMapRed.waitOutputThreads(): subprocess failed with code *

这是java抛出的系统返回的错误码,错误码表示的意思详细的请看这里。
我这里是些streaming的php程序时遇到的,遇到的错误码是code 2: No such file or directory。即找不到文件或者目录。发现命令竟然忘记使用’php ****’ 很坑,另外网上看到也可能是include、require等命令造成。详细的请根据自身情况和错误码修改。

你可能感兴趣的:(Hadoop使用常见问题以及解决方法 (转))