Taiwan Hadoop Forum

台灣 Hadoop 技術討論區
現在的時間是 2022-05-24, 08:10

所有顯示的時間為 UTC + 8 小時




發表新文章 回覆主題  [ 2 篇文章 ] 
發表人 內容
 文章主題 : WordCount程式,基礎問題。
文章發表於 : 2013-07-20, 14:31 
離線

註冊時間: 2013-06-03, 12:40
文章: 15
Jazz,我想針對wordcount程式碼,先弄懂它的運作然後再一起把Inverted Index學起來,希望我這種學習態度沒有錯誤了。所以針對程式碼部分,就我所了解運作後,我想問幾個問題。
以下WordCount程式碼,紅色部分是您在這(附網一)網站上的程式碼:
附網一:http://trac.nchc.org.tw/cloud/wiki/Hadoop_Lab5_1
然後其他黑色部分,我是看您(附網二)網站上,Map Reduce程式設計的程式碼:
附網二:http://www.classcloud.org/media/
然後我發現程式碼有些不同,針對不同的地方我有些問題:


import java.io.IOException;
import java.util.*;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.conf.*;
import org.apache.hadoop.io.*;
import org.apache.hadoop.mapred.*;
import org.apache.hadoop.util.*;

問題一: 請問我要怎麼判斷,我要怎麼加入 import 的這些內容,因為我知道是”包”的概念。有用到的包,才需要加入,但是並不是說每個包都會用到吧? 所以我該怎麼判斷,我什麼時候該用什麼包的說?

public class WordCount {

public static class Map extends MapReduceBase implements Mapper<LongWritable, Text, Text, IntWritable> {
private final static IntWritable one = new IntWritable(1);
// 告訴程式說 one 代表 1。
private Text word = new Text();
// 把word 也設成全域變數,因為等等collector要當output出去的。
// 建立一個word的物件來存放mapper的結果。

public void map(LongWritable key, Text value, OutputCollector<Text, IntWritable> output, Reporter reporter) throws IOException {
String line = value.toString();
String line = ((Text.value).toString;
問題二: 請問為什麼value 可以取代 (Text.value) ,是同一個東西嗎? 因為在Text.value由於傳進來的value是Text類型,所以不是需要先得知傳進來的類型再做轉型(toString)嗎? 還是這是新寫法?
StringTokenizer tokenizer = new StringTokenizer(line);
StringTokenizer itr = new StringTokenizer(line);
問題三: 請問tokenizer 和 itr 的作用是一樣的嗎? 因為我知道itr 物件,會讓取出來的某一行變成一串指標串列。 但是,tokenizer只是將字串資料的內容分解,所以用意是一樣的嗎?
while (tokenizer.hasMoreTokens()) {
while (itr.hasMoreTokens()) { //當還有字元尚未被傳出時繼續。
word.set(tokenizer.nextToken());
word.set(itr.nextToken()); //將分割出來的字元取出存放到word裡面。
output.collect(word, one);
// output.collect(New key, New value)。利用output.collect這個方法,做輸出。
問題四: 請問您在pdf檔裡說這裡的位置是New key 和New value請問代表的是什麼意思? 因為我知道map output 即 reduce input。我想是和這有關嗎?
}
}
}

public static class Reduce extends MapReduceBase implements Reducer<Text, IntWritable, Text, IntWritable> {
//全域
IntWritable SumValue = new IntWritable();
//另外一版沒有全域變數~

public void reduce(Text key, Iterator<IntWritable> values, OutputCollector<Text, IntWritable> output, Reporter reporter) throws IOException {

int sum = 0;
while (values.hasNext()) {
sum += values.next().get();
}
output.collect(key, new IntWritable(sum));
output.collect(key, SumValue);
// output.collect(New key, New value)。
問題五: 請問您在這裡用new IntWritable(sum)取代了SumValue。請問是因為使用new IntWritable 不用再到全域變數區宣告的關係嗎? 由於您在使用SumValue時有在全域變數區宣告 SumValue,所以不知到是不是因為使用了new IntWritable(sum)就不用宣告的關係,所以才這樣用呢?
}
}

public static void main(String[] args) throws Exception {
JobConf conf = new JobConf(WordCount.class);
conf.setJobName("wordcount");
conf.setOutputKeyClass(Text.class);
conf.setOutputValueClass(IntWritable.class);


conf.setMapperClass(Map.class);
// 告訴程式跑map的位置在Map.class裡。
conf.setCombinerClass(Reduce.class);
conf.setReducerClass(Reduce.class);
// 告訴程式跑reduace的位置在Reduce.class裡。
conf.setInputFormat(TextInputFormat.class);
conf.setOutputFormat(TextOutputFormat.class);

問題六: 請問以上除了conf.setCombinerClass(Reduce.class); 您說比較不會用到外,其它是不是應該都是必需的?
FileInputFormat.setInputPaths(conf, new Path(args[0]));
FileOutputFormat.setOutputPath(conf, new Path(args[1]));
JobClient.runJob(conf);
}

}
問題七: 請問hadoop 程式開發 (eclipse plugin)這網站中:
http://trac.nchc.org.tw/cloud/wiki/Hadoop_Lab5_1
您說到hadoop版本和eclipse版本會因為版本不對應而有有些功能無法使用。所以,到目前為止只有eclipse 3.3.2和hadoop 0.18.3沒問題嗎? 還是還有其它的版本搭配?


回頂端
 個人資料 E-mail  
 
 文章主題 : Re: WordCount程式,基礎問題。
文章發表於 : 2013-07-20, 22:22 
離線

註冊時間: 2009-11-09, 19:52
文章: 2897
首先,您參考的 trac 頁面已經有一段時間沒更新了,屬於 0.18~0.19 過渡期的程式碼。
只要前面 import 是 org.apache.mapred 則為舊版。org.apache.mapreduce 則為新版。

rocker81317 寫:
問題一: 請問我要怎麼判斷,我要怎麼加入 import 的這些內容,因為我知道是”包”的概念。有用到的包,才需要加入,但是並不是說每個包都會用到吧? 所以我該怎麼判斷,我什麼時候該用什麼包的說?


這就跟寫 C 是一樣的,該 #include 哪個 .h 檔,看您要呼叫什麼函數。
在 C++ 就看您要使用哪個類別(Class),在 Java 也一樣,有使用到的類別,就必須 import。
至於該怎麼判斷,我覺得學習 Java 就是得習慣查 java doc
所以往往在寫 Java 程式的時候,得先學會查 API - 例如:http://docs.oracle.com/javase/6/docs/api/
要用到 Hadoop 的 API 時,就得查 Hadoop 的 java doc - 例如:http://hadoop.nchc.org.tw/hadoop-doc/api/index.html

rocker81317 寫:
問題二: 請問為什麼value 可以取代 (Text.value) ,是同一個東西嗎? 因為在Text.value由於傳進來的value是Text類型,所以不是需要先得知傳進來的類型再做轉型(toString)嗎? 還是這是新寫法?


我不確定您在哪裡看到 ((Text.value).toString) 這種語法,就我瞭解,那應該是 Java 另一種語法,我沒用過。應該是直接用 value.toString() 這是呼叫 Text 類別的 toString() 函數。
http://hadoop.nchc.org.tw/hadoop-doc/api/org/apache/hadoop/io/Text.html
宣告是 public String toString()

rocker81317 寫:
問題三: 請問tokenizer 和 itr 的作用是一樣的嗎? 因為我知道itr 物件,會讓取出來的某一行變成一串指標串列。 但是,tokenizer只是將字串資料的內容分解,所以用意是一樣的嗎?


Java 語法,<類別名稱> <物件參考 Object Reference>,
StringTokenizer tokenizer 跟 StringTokenizer itr 只是「物件參考」命名不同....沒什麼差別 XD
C 語法 <型態> <變數名稱> Ex. int a 跟 int b

rocker81317 寫:
問題四: 請問您在pdf檔裡說這裡的位置是New key 和New value請問代表的是什麼意思? 因為我知道map output 即 reduce input。我想是和這有關嗎?


那只是「註解」... 代表送出新一筆 (key, value) 記錄

rocker81317 寫:
問題五: 請問您在這裡用new IntWritable(sum)取代了SumValue。請問是因為使用new IntWritable 不用再到全域變數區宣告的關係嗎? 由於您在使用SumValue時有在全域變數區宣告 SumValue,所以不知到是不是因為使用了new IntWritable(sum)就不用宣告的關係,所以才這樣用呢?


邏輯上,兩種語法的意義相同。
但仔細深究的話,會有很細微的效能差異。這已經是 Java Virtual Machine 的效能議題了,這裡就不談了。

rocker81317 寫:
問題六: 請問以上除了conf.setCombinerClass(Reduce.class); 您說比較不會用到外,其它是不是應該都是必需的?


除了 Combiner 之外,其他就先當它們是必須吧~

rocker81317 寫:
問題七: 請問hadoop 程式開發 (eclipse plugin)這網站中:
http://trac.nchc.org.tw/cloud/wiki/Hadoop_Lab5_1
您說到hadoop版本和eclipse版本會因為版本不對應而有有些功能無法使用。所以,到目前為止只有eclipse 3.3.2和hadoop 0.18.3沒問題嗎? 還是還有其它的版本搭配?


plugin 會挑 Eclipse 版本,這答案是確定的。至於哪幾個版本是相容的,目前沒看過有人整理版本相容表。
我個人與 Facebook 的回覆一樣:用 Eclipse 寫程式,用 command line 編譯。因此,目前沒有用到 Eclipse Plugin。
無法給太多意見。

- Jazz


回頂端
 個人資料 E-mail  
 
顯示文章 :  排序  
發表新文章 回覆主題  [ 2 篇文章 ] 

所有顯示的時間為 UTC + 8 小時


誰在線上

正在瀏覽這個版面的使用者:沒有註冊會員 和 1 位訪客


不能 在這個版面發表主題
不能 在這個版面回覆主題
不能 在這個版面編輯您的文章
不能 在這個版面刪除您的文章
不能 在這個版面上傳附加檔案

搜尋:
前往 :  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
正體中文語系由 竹貓星球 維護製作