問題描述: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函數內部賦值
附錄:框架
例如這樣一個問題,在集羣上壓縮(zipping)一些文件,你可使用如下幾種方法:eclipse
FileOutputFormat.setCompressOutput(conf, true); FileOutputFormat.setOutputCompressorClass(conf, org.apache.hadoop.io.compress.GzipCodec.class); conf.setOutputFormat(NonSplitableTextInputFormat.class); conf.setNumReduceTasks(0);
public void map(WritableComparable key, Writable value, OutputCollector output, Reporter reporter) throws IOException { output.collect((Text)value, null); }