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

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.IO Exception : 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:IO写操作出现问题 
0-1246359584298, infoPort=50075, ipcPort=50020):Got exception while serving blk_-5911099437886836280_1292 to /172.16.100.165:
java.net.SocketTimeoutException: 480000 millis timeout while waiting for channel to be ready for write. ch : java.nio.channels.SocketChannel[connected local=/
172.16.100.165:50010 remote=/172.16.100.165:50930]
        at org.apache.hadoop.net.SocketIOWithTimeout.waitForIO(SocketIOWithTimeout.java:185)
        at org.apache.hadoop.net.SocketOutputStream.waitForWritable(SocketOutputStream.java:159)
        at org.apache.hadoop.net.SocketOutputStream.transferToFully(SocketOutputStream.java:198)
        at org.apache.hadoop.hdfs.server.datanode.BlockSender.sendChunks(BlockSender.java:293)
        at org.apache.hadoop.hdfs.server.datanode.BlockSender.sendBlock(BlockSender.java:387)
        at org.apache.hadoop.hdfs.server.datanode.DataXceiver.readBlock(DataXceiver.java:179)
        at org.apache.hadoop.hdfs.server.datanode.DataXceiver.run(DataXceiver.java:94)
        at java.lang.Thread.run(Thread.java:619)

It seems there are many reasons that it can timeout, the example given in 
HADOOP-3831 is a slow reading client.
解决办法:在hadoop-site.xml中设置dfs.datanode.socket.write.timeout=0试试; 
My understanding is that this issue should be fixed in Hadoop 0.19.1 so that
we should leave the standard timeout. However until then this can help
resolve issues like the one you're seeing.

8:hadoop OutOfMemoryError:
解决方法:<property>
   <name>mapred.child.java.opts</name>
   <value>-Xmx800M -server</value>
</property>
With the right JVM size in your hadoop-site.xml , you will have to copy this
to all mapred nodes and restart the cluster.
或者:hadoop jar jarfile [main class] -D mapred.child.java.opts=-Xmx800M 

9: Hadoop java.io.IOException: Job failed! at org.apache.hadoop.mapred.JobClient.runJob(JobClient.java:1232) while indexing. 
when i use nutch1.0,get this error:
Hadoop java.io.IOException: Job failed! at org.apache.hadoop.mapred.JobClient.runJob(JobClient.java:1232) while indexing.
这个也很好解决:
可以删除conf/log4j.properties,然后可以看到详细的错误报告
我这儿出现的是out of memory
解决办法是在给运行主类org.apache.nutch.crawl.Crawl加上参数:-Xms64m -Xmx512m
你的或许不是这个问题,但是能看到详细的错误报告问题就好解决了

其他问题
status of 255 error 
错误类型:
java.io.IOException: Task process exit with nonzero status of 255.
        at org.apache.hadoop.mapred.TaskRunner.run(TaskRunner.java:424)

错误原因: 
Set mapred.jobtracker.retirejob.interval and mapred.userlog.retain.hours to higher value. By default, their values are 24 hours. These might be the reason for failure, though I'm not sure

split size 
FileInputFormat input splits: (详见 《the definitive guide》P190)
mapred.min.split.size: default=1, the smallest valide size in bytes for a file split.
mapred.max.split.size: default=Long.MAX_VALUE, the largest valid size.
dfs.block.size: default = 64M, 系统中设置为128M。
如果设置 minimum split size > block size, 会增加块的数量。(猜想从其他节点拿去数据的时候,会合并block,导致block数量增多) 
如果设置maximum split size < block size, 会进一步拆分block。

split size = max(minimumSize, min(maximumSize, blockSize)); 
其中 minimumSize < blockSize < maximumSize.

sort by value 
hadoop 不提供直接的sort by value方法,因为这样会降低mapreduce性能。
但可以用组合的办法来实现,具体实现方法见《the definitive guide》, P250
基本思想:
1. 组合key/value作为新的key;
2. 重载partitioner,根据old key来分割;
conf.setPartitionerClass(FirstPartitioner.class);
3. 自定义keyComparator:先根据old key排序,再根据old value排序;
conf.setOutputKeyComparatorClass(KeyComparator.class);
4. 重载GroupComparator, 也根据old key 来组合;  conf.setOutputValueGroupingComparator(GroupComparator.class);

small input files的处理 
对于一系列的small files作为input file,会降低hadoop效率。
有3种方法可以将small file合并处理:
1. 将一系列的small files合并成一个sequneceFile,加快mapreduce速度。
详见WholeFileInputFormat及SmallFilesToSequenceFileConverter,《the definitive guide》, P194
2. 使用CombineFileInputFormat集成FileinputFormat,但是未实现过;
3. 使用hadoop archives(类似打包),减少小文件在namenode中的metadata内存消耗。(这个方法不一定可行,所以不建议使用)
   方法:
   将/my/files目录及其子目录归档成files.har,然后放在/my目录下
   bin/hadoop archive -archiveName files.har /my/files /my
   
   查看files in the archive:
   bin/hadoop fs -lsr har://my/files.har

skip bad records 
JobConf conf = new JobConf(ProductMR.class);
conf.setJobName("ProductMR");
conf.setOutputKeyClass(Text.class);
conf.setOutputValueClass(Product.class);
conf.setMapperClass(Map.class);
conf.setReducerClass(Reduce.class);
conf.setMapOutputCompressorClass(DefaultCodec.class);
conf.setInputFormat(SequenceFileInputFormat.class);
conf.setOutputFormat(SequenceFileOutputFormat.class);
String objpath = "abc1";
SequenceFileInputFormat.addInputPath(conf, new Path(objpath));
SkipBadRecords.setMapperMaxSkipRecords(conf, Long.MAX_VALUE);
SkipBadRecords.setAttemptsToStartSkipping(conf, 0);
SkipBadRecords.setSkipOutputPath(conf, new Path("data/product/skip/"));
String output = "abc";
SequenceFileOutputFormat.setOutputPath(conf, new Path(output));
JobClient.runJob(conf);

For skipping failed tasks try : mapred.max.map.failures.percent 

restart 单个datanode 
如果一个datanode 出现问题,解决之后需要重新加入cluster而不重启cluster,方法如下:
bin/hadoop-daemon.sh start datanode
bin/hadoop-daemon.sh start jobtracker

reduce exceed 100% 
"Reduce Task Progress shows > 100% when the total size of map outputs (for a
single reducer) is high "
造成原因:
在reduce的merge过程中,check progress有误差,导致status > 100%,在统计过程中就会出现以下错误:java.lang.ArrayIndexOutOfBoundsException: 3
        at org.apache.hadoop.mapred.StatusHttpServer$TaskGraphServlet.getReduceAvarageProgresses(StatusHttpServer.java:228)
        at org.apache.hadoop.mapred.StatusHttpServer$TaskGraphServlet.doGet(StatusHttpServer.java:159)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:689)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
        at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:427)
        at org.mortbay.jetty.servlet.WebApplicationHandler.dispatch(WebApplicationHandler.java:475)
        at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:567)
        at org.mortbay.http.HttpContext.handle(HttpContext.java:1565)
        at org.mortbay.jetty.servlet.WebApplicationContext.handle(WebApplicationContext.java:635)
        at org.mortbay.http.HttpContext.handle(HttpContext.java:1517)
        at org.mortbay.http.HttpServer.service(HttpServer.java:954)

jira地址: https://issues.apache.org/jira/browse/HADOOP-5210 

counters 
1. built-in counters: Map input bytes, Map output records...
2. enum counters
   调用方式:
  enum Temperature {
    MISSING,
    MALFORMED
  }

reporter.incrCounter(Temperature.MISSING, 1) 
   结果显示:
09/04/20 06:33:36 INFO mapred.JobClient:   Air Temperature Recor
09/04/20 06:33:36 INFO mapred.JobClient:     Malformed=3
09/04/20 06:33:36 INFO mapred.JobClient:     Missing=66136856
3. dynamic countes:
   调用方式:
   reporter.incrCounter("TemperatureQuality", parser.getQuality(),1);
   
   结果显示:
09/04/20 06:33:36 INFO mapred.JobClient:   TemperatureQuality
09/04/20 06:33:36 INFO mapred.JobClient:     2=1246032
09/04/20 06:33:36 INFO mapred.JobClient:     1=973422173
09/04/20 06:33:36 INFO mapred.JobClient:     0=1

 

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

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

更改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地址

两个特别的异常:

异常1

hadoop@ubuntu:~$ hadoop/bin/hadoop jar hadoop-0.20.2-examples.jar wordcount input01 output01
Exception in thread "main" java.io.IOException: Error opening job jar: hadoop-0.20.2-examples.jar
    at org.apache.hadoop.util.RunJar.main(RunJar.java:90)
Caused by: java.util.zip.ZipException: error in opening zip file
    at java.util.zip.ZipFile.open(Native Method)
    at java.util.zip.ZipFile.<init>(ZipFile.java:131)
    at java.util.jar.JarFile.<init>(JarFile.java:150)
    at java.util.jar.JarFile.<init>(JarFile.java:87)
    at org.apache.hadoop.util.RunJar.main(RunJar.java:88)

发生这个异常后,找了很多帖子都没有解答,也有很多人遇到了类似的情况。其实这一般并不是java包有问题,问题也简单的可笑,就是上面的命令行中
hadoop-0.20.2-examples.jar

路径不完整造成的,需要注意一下命令行当前的位置,比如对于我的情况,改为hadoop/hadoop-0.20.2-examples.jar就可以了

异常2

hadoop@ubuntu:~$ hadoop/bin/hadoop jar hadoop/hadoop-0.20.2-examples.jar wordcount input01 output02

java.io.IOException: Task process exit with nonzero status of 1.
    at org.apache.hadoop.mapred.TaskRunner.run(TaskRunner.java:418)

11/03/15 12:54:09 WARN mapred.JobClient: Error reading task outputhttp://ubuntu.ubuntu-domain:50060/tasklog?plaintext=true&taskid=attempt_201103151252_0001_m_000004_1&filter=stdout
......

这个问题困扰了我整整一晚上,中文博客基本没搜到什么有参考价值的文章,老外的很多博客提到了,但是很多也没说清楚。其中有一些有提示作用,比如:

Just an FYI, found the solution to this problem.

Apparently, it's an OS limit on the number of sub-directories that can be reated in another directory.  In this case, we had 31998 sub-directories uder hadoop/userlogs/, so any new tasks would fail in Job Setup.

From the unix command line, mkdir fails as well: 
  $ mkdir hadoop/userlogs/testdir 
  mkdir: cannot create directory `hadoop/userlogs/testdir': Too many links

Difficult to track down because the Hadoop error message gives no hint whasoever.  And normally, you'd look in the userlog itself for more info, butin this case the userlog couldn't be created.

问题是,我可以通过这个小测试,在userlogs下面可以添加任意的文件夹和文件,当然也有可能某些人确实就是这个问题,不能添加。
然后我的解决办法是,直接把这个userlogs给去掉或者换一个文件夹名

hadoop@ubuntu:~$ mv /home/hadoop/hadoop/logs/uerlogs/ /home/hadoop/hadoop/logs/uerlogsOLD/

即,把原来的文件夹改名成userlogsOLD(相当于一种移除、保存方式了),重新运行

hadoop@ubuntu:~$ hadoop/bin/hadoop jar hadoop/hadoop-0.20.2-examples.jar wordcount input01 output03

11/03/15 14:21:23 INFO input.FileInputFormat: Total input paths to process : 3
11/03/15 14:21:23 INFO mapred.JobClient: Running job: job_201103151252_0004 
11/03/15 14:21:24 INFO mapred.JobClient:  map 0% reduce 0%
11/03/15 14:21:32 INFO mapred.JobClient:  map 66% reduce 0% 
11/03/15 14:21:35 INFO mapred.JobClient:  map 100% reduce 0%
11/03/15 14:21:44 INFO mapred.JobClient:  map 100% reduce 100% 11/03/15 14:21:46 INFO mapred.JobClient: Job complete: job_201103151252_0004
......

问题自此解决了!但是我还是不懂这是什么原因造成的,但可以肯定的是关于日志的存储量的问题。因为才开始学,eclpse下新建MapReduce工程也能跑起来了,慢慢估计会了解。留此权当笔记!

你可能感兴趣的:(hadoop,常见问题,解决办法)