zoukankan      html  css  js  c++  java
  • [hadoop] map函数中使用FileSystem对象出现java.lang.NullPointerException的原因及解决办法

    问题描述:

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

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

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

    FileStatus fileStatus = tmpfs.getFileStatus(inputdir); 
    这一句报错
    java.lang.NullPointerException 卡了2天,不知到是哪错了。

    昨天下午才想到应
    tmpfs是一个空对象,没有赋值。

    虽然tmpfs 在最外层的类中声明为静态变量,并且在main函数中有赋值,然而在map函数内还是NullPointer。
    之后改为在map函数内部给
    tmpfs赋值就解决了问题。
    这也验证了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)一些文件,你可以使用以下几种方法:

    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);
               }
        
      • 注意输出的文件名和原文件名不同
  • 相关阅读:
    linux下硬盘分区、格式化以及文件管理系统
    linux下的文档处理及tar命令
    linux文件及目录的权限管理
    linux用户和群组
    linux下mysql的安装与使用
    linux上uwsgi+nginx+django发布项目
    linux虚拟环境搭建
    linux目录文件操作
    linux基本命令
    rbac组件之权限初始化(五)
  • 原文地址:https://www.cnblogs.com/scw2901/p/4331605.html
Copyright © 2011-2022 走看看