Hadoop使用常見問題以及解決方法(轉載)

sw6425999發表於2015-03-13


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工程也能跑起來了,慢慢估計會了解。留此權當筆記!

相關文章