2013-04-17 95 views
1

分佈式文件我試圖在Hadoop中的以下內容:閱讀Hadoop中

  1. 我已經實現了一個文件輸出到目錄「foo」的一個地圖,減少工作。
  2. foo文件帶有一個鍵= IntWriteable,value = IntWriteable格式(使用SequenceFileOutputFormat)。
  3. 現在,我想開始另一個map-reduce作業。映射器是好的,但每個reducer都需要在啓動時讀取整個「foo」文件(我正在使用HDFS在reducer之間共享數據)。

我用了「公共無效配置(JobConf CONF)」這樣的代碼:

String uri = "out/foo"; 
FileSystem fs = FileSystem.get(URI.create(uri), conf); 
FileStatus[] status = fs.listStatus(new Path(uri)); 
for (int i=0; i<status.length; ++i) { 
    Path currFile = status[i].getPath(); 
    System.out.println("status: " + i + " " + currFile.toString()); 
    try { 
     SequenceFile.Reader reader = null; 
     reader = new SequenceFile.Reader(fs, currFile, conf); 
     IntWritable key = (IntWritable) ReflectionUtils.newInstance(reader.getKeyClass(), conf); 
     IntWritable value = (IntWritable) ReflectionUtils.newInstance(reader.getValueClass(), conf); 
     while (reader.next(key, value)) { 
     // do the code for all the pairs. 
     } 
    } 
} 

的代碼運行良好,一臺機器上,但我notsure是否會在集羣上運行。 換句話說,這個代碼是從當前機器讀取文件還是從分佈式系統讀取ID?

有什麼我想要做的更好的解決方案?

在此先感謝,

Arik。

+0

這似乎是一個可行的方法來做到這一點。如果defaultFS配置爲hdfs,則out/foo將位於HDFS上。我建議閱讀setup()方法中的文件,所以你只做一次。 –

+0

謝謝,我該如何設置defaultFS爲HDFS ?,此外,在configure()和setup()方法之間還有什麼區別 - 它只是舊vs新API,因爲它們提供了相同的功能? –

+0

你在你的core-site.xml中設置它。 fs.default.name類似hdfs:// hadoop -nn:8020。默認情況下,如果你運行在僞分佈模式下,它會被設置爲這個(也許是hdfs:// localhost:8020)。配置和設置基本上是一樣的,是的。 –

回答

0

FileSystem.get()的URI沒有定義方案,因此使用的文件系統取決於配置參數fs.defaultFS。如果沒有設置,則將使用默認設置,即LocalFile系統。

您的程序在workingDir/out/foo下寫入本地文件系統。它也應該在羣集中工作,但是會查找本地文件系統。

與上述說,我不知道爲什麼你需要從foo目錄的整個文件。您可能會考慮其他設計。如果需要,應首先將這些文件複製到HDFS,然後從減速器的重寫設置方法中讀取文件。毋庸置疑,要關閉在reducer的重寫特寫方法中打開的文件。雖然可以在縮減器中讀取文件,但map/reduce程序不是爲這種功能而設計的。

+0

謝謝,我如何設置fs.defaultFS爲分佈式HDFS? –

+0

謝謝,我如何設置fs.defaultFS爲分佈式HDFS?另外,對於我的需求是否有更好的設計:簡言之,我的程序使用了兩個map-reduce作業,第一個作業的全部輸出需要被第二個作業reducer訪問(全部),這是某種動態生成的共享資源,需要共享不同機器上的所有reducer –

+0

您可以使用hadoop配置文件或自定義配置文件,然後使用org.apache.hadoop.conf.Configuration上的addResource()方法加載它們,也可以使用set( )方法org.apache.hadoop.conf.Configuration –