[hadoop] map函数中使用FileSystem对象出现java.lang.NullPointerException的缘由及解决办法

问题描述:html

      在hadoop中处理多个文件,其中每一个文件一个map。java

      我使用的方法为生成一个文件,文件中包含全部要压缩的文件在HDFS上的完整路径。每一个map 任务得到一个路径名做为输入。apache

      在eclipse中调试时,map中处理hdfs上的文件用到的FileSystem对象为整个class中的静态成员变量,在eclipse中运行没有错误,打包成jar提交到集群运行,就会在map函数中   app

FileStatus fileStatus = tmpfs.getFileStatus(inputdir); 
这一句报错
tmpfs是一个空对象,没有赋值。
虽然tmpfs 在最外层的类中声明为静态变量,而且在main函数中有赋值,然而在map函数内仍是tmpfs赋值就解决了问题。java.lang.NullPointerException 卡了2天,不知到是哪错了。

昨天下午才想到应
NullPointer。
以后改成在map函数内部给
这也验证了eclipse中调试运行程序是在本地运行,只不过是调用了hadoop的类库,在8088端口的监控网页上也看不到提交应用的信息。
必须打包成jar,用bin/hadoop jar运行才能真正提交到集群运行。并且main函数内部初始化的静态变量,在map中仍是未初始化状态,猜想是集群上运行的map任务,和本地的main函数是互相独立的关系。


改正后的代码:
 1 @Override
 2         public void map(Object key, Text value,
 3                 Context context)
 4         throws
 5         IOException, InterruptedException {
 6             Configuration conf = context. getConfiguration();
 7             FileSystem tmpfs = FileSystem.get(URI.create("hdfs://192.168.2.2:9000"), conf); 
 8             
 9             Path inputdir = new Path(value.toString());    //获取待处理的文件的Path对象
10             FileStatus fileStatus = tmpfs.getFileStatus(inputdir);
11 
12                 //作相应处理
13 
14             context.write(new Text(value.toString()), new Text("  "));
15 }    
Configuration conf = context. getConfiguration();//经过context获取job中配置的Configuration对象
FileSystem tmpfs = FileSystem.get(URI.create("hdfs://192.168.2.2:9000"), conf); //须要在map函数内部赋值

 

附录:框架

如何处理多个文件,其中每一个文件一个map?

例如这样一个问题,在集群上压缩(zipping)一些文件,你可使用如下几种方法:eclipse

  1. 使用Hadoop Streaming和用户编写的mapper脚本程序:
    • 生成一个文件,文件中包含全部要压缩的文件在HDFS上的完整路径。每一个map 任务得到一个路径名做为输入。
    • 建立一个mapper脚本程序,实现以下功能:得到文件名,把该文件拷贝到本地,压缩该文件并把它发到指望的输出目录。
  2. 使用现有的Hadoop框架:
    • 在main函数中添加以下命令:
             FileOutputFormat.setCompressOutput(conf, true);
             FileOutputFormat.setOutputCompressorClass(conf, org.apache.hadoop.io.compress.GzipCodec.class);
             conf.setOutputFormat(NonSplitableTextInputFormat.class);
             conf.setNumReduceTasks(0);
      
    • 编写map函数:
             public void map(WritableComparable key, Writable value, 
                                     OutputCollector output, 
                                     Reporter reporter) throws IOException {
                  output.collect((Text)value, null);
             }
      
    • 注意输出的文件名和原文件名不一样
相关文章
相关标签/搜索