hadoop 问题汇总

来源:互联网 发布:短信变号软件 编辑:程序博客网 时间:2024/06/04 20:07

1.在运行hadoop时遇到问题,首先要查询位于 %hadoop安装目录%\logs\userlogs\中的日志信息。控制台输出的日志的内容并不全面。
2.链接hdfs,访问hdfs上面的文件时,出现链接失败。Connection refused。这时需要查看core-site.xml中的fs.defaultFS要改成hdfs://localhost:8020。8020端口是hadoop的namenode的RPC调用端口。然后重新启动hadoop。
3.maven 打包时出错
https://stackoverflow.com/questions/12687797/how-do-i-fix-a-unexpected-end-of-zlib-input-stream-with-the-maven-shade-plugin
4.maven测试
注意方法命名是用test+方法名.否则无法进行测试
在执行测试之前,一定要对源码进行编译
5.No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK:使用maven构建项目时,碰到的错误。问题原因:eclipse官网看了看,发现eclipse默认是运行在jre上的,
但是maven插件需要使用jdk,因此需要在eclipse修改Installed JRES
位置在–>【Window】–>【Prefrences】–>【Java】–>【Installed JREs】,在其中添加jdk的路径便可。
6.java.io.IOException: No FileSystem for scheme:hdfs
https://stackoverflow.com/questions/17265002/hadoop-no-filesystem-for-scheme-file
这里写图片描述
7.FileSystem 中的append方法会在单机情况下,无法对文件追加,原因就是需要添加
conf.set(“dfs.client.block.write.replace-datanode-on-failure.policy”,”NEVER”);
conf.set(“dfs.client.block.write.replace-datanode-on-failure.enable”,”true”);
conf.setInt(“dfs.replication”, 1);
就算加上这三个还是有时行,有时不行。坑

8.
http://localhost:8088/
http://localhost:50070/
9.hadoop_conf_dir用于制定指定hadoop启动时配置文件的目录,默认情况下是%hadoop_home%/etc/hadoop
但是可以自行设定。
在G:\hadoop-2.8.0\etc\hadoop中编辑hadoop-env.cmd中的SET hadoop_conf_dir=”自己设定的目录”
然后将%hadoop_home%/etc/hadoop中的xml后缀的文件全部复制到”自己设定的目录”;
注意在打开终端时,使用管理员权限打开。否则可能会启动hadoop失败。
10.configuration 配置文件
注意 同样的代码在eclipse端和在命令行下运行的结果是不一样的
针对如下的代码

public class ConfigurationPrinter extends Configured implements Tool {    public int run(String[] args) throws Exception {        Configuration conf=getConf();        //conf.addResource("hdfs-default.xml");        conf.addResource("hdfs-site.xml");        int  tmp=0;        for(Entry<String,String> entry:conf){            System.out.printf("%d+%s=%s\n",tmp,entry.getKey(),entry.getValue());            tmp++;        }        System.out.println(conf.toString());        return 0;    }    public static void main(String[] args) throws Exception{        int exitCode=ToolRunner.run(new ConfigurationPrinter(), args);        System.out.println();    }}

如果在eclipse中直接运行,是不会加载hdfs-site.xml,Configuration默认加载的只有core-default.xml, core-site.xml,但是在命令行中是可以加载的,原因是命令行使用 hadoop jar命令时,会运行hadoop-config.cmd,设置classpath,其中的一段就是

if not defined HADOOP_CONF_DIR (  set HADOOP_CONF_DIR=%HADOOP_HOME%\etc\hadoop)...set CLASSPATH=%HADOOP_CONF_DIR%

那么首先hadoop会将classpath初始化为%HADOOP_CONF_DIR%,这个HADOOP_CONF_DIR可以由我们自己来定,如果不设置,那就使用%HADOOP_HOME%\etc\hadoop ,而使用conf.addResource(String resource)加载配置文件时,hadoop会去classpath中搜索,但是如果在eclipse中直接运行的话,根本不会运行hadoop-config.cmd.
另外的配置文件中的property的最终值确认顺序如下:首先从Configuration对象中的默认加载的,然后是代码中通过Configuration对象的set方法加载的,最后是通过命令行-D 加载的。后面的property覆盖前面的property.
另外如果有自设的一些配置文件,建议放在HADOOP_CONF_DIR环境变量指向的目录下,这样子,我们就发现设置HADOOP_CONF_DIR环境变量是很方便的。将%HADOOP_HOME%\etc\hadoop中的配置文件复制到HADOOP_CONF_DIR中,然后将自设的一些配置文件也放在HADOOP_CONF_DIR中.

11 在运行mapreduce是,出现了一个奇怪的现象,程序并没有报错,但是确也没有输出正确结果。原因出在混用了一些类。 FileSplit类在旧版hadoop和新版hadoop中都有,分别是在org.apache.hadoop.mapred.
FileSplit和org.apache.hadoop.mapreduce.lib.input.FileSplit; 在对新版的inputSplit进行FileSplit强制转换时,出现问题,是因为使用了旧版的FileSplit而不是新版的FileSplit。
12 Unable to initialize any output collector
http://blog.csdn.net/infovisthinker/article/details/45152919
这里写图片描述
13 Type mismatch in key from map
首先查看key值是否正确 ,然后查找是否已经在job设置

job.setOutputKeyClass(Text.class);job.setOutputValueClass(Text.class);job.setMapOutputKeyClass(MonthTemperaturePair.class);job.setMapOutputValueClass(NullWritable.class); 

14 .使用java写泛型循环队列
需要注意的点.

1.需要判断队列是否已满,或者已空,如果已满的队列,不允许再添加新元素,如果队列已空,不允许出队列。虽然是循环队列,但是在一个元素还么有出队列的情况下,不允许覆盖这个元素。

2.明确循环队列大小,比如需要的循环队列为maxSize,在构造方法中令this.maxSize=maxSize+1;
原因在于循环队列需要判断队列是否已经满了。举个例子如果需要的循环队列大小为1,但是在构造函数中
this.maxSize=1;
那么在进队列的时候,会发现队列已满。(0+1)%1==0,因此进不了队列。

3.java 中ArrayList的set方法是在现有的位置上进行元素替换,前台必须是该位置已经有一个元素。add方法是在某个位置上添加一个元素。但是如果这个位置上已经有一个元素,那么这个元素后面的元素(包含这个)统一向后移一个单位,然后再把新元素添加进去。因此在进队列的时候需要注意如果队列大小小于maxSize,就使用add方法。否则就使用set方法。

import java.io.IOException;import java.util.ArrayList;public class MoveAverageCycQueue<T> {    private int maxSize;    private ArrayList<T> queue;    private int posLast;    private int posFirst;    public MoveAverageCycQueue(int maxSize){        this.maxSize=maxSize+1;        this.posLast=0;        this.posFirst=0;        queue=new ArrayList<T>(maxSize);    }    public boolean isEmpty(){        return posLast==posFirst?true:false;    }    public boolean isFull(){        return (posLast+1) % maxSize == posFirst?true:false;     }    public void  enqueue(T t)  throws Exception{        if(isFull()){            throw new Exception("queue is full!!!");        }        else{            if(queue.size()<maxSize)                queue.add(posLast,t);            else                 queue.set(posLast,t);            posLast=(posLast+1) % maxSize;          }    }    public T dequeue()   throws Exception{        if(isEmpty()){            throw new Exception("queue is empty!!!");        }        else{            T t=queue.get(posFirst);            posFirst=(posFirst+1) % maxSize;             return t;        }    }}