csh10301989 寫:
各位先進好!
最近有個想法,
map輸入輸出為<Object, Text, Text, IntWritable>時
就map輸出出來的形式就類似於<A, 1>
他所佔的byte數應為1byte(Text佔的大小)+4byte(IntWritable佔的大小)=5byte
那個1只是為了要讓map知道說我存在一個A這個key的話, 浪費的byte也太多了吧!!!
於是我就想說, 我要將map輸出為" ", 也就是empty string,這樣的話就可以大量的減少記憶體的消耗了!!
可是實際在測試的時候, 我發現宣告的部分卻有些問題
首先第一, 目前我寫的手法是, 因為我輸出是" ",
所以我把value宣告為Text格式,
可是Text格式所佔的byte應該是1byte,
也就是說我浪費了7個bits在那個七個零,
有辦法宣告只有一個bits的型式嗎?
再來第二, 假使我使用了combiner函式, 就書上來說,
map輸出格式=combiner輸入格式, combiner輸出格式=reduce輸入格式,
我根據這樣做了, 雖說解決一些問題關於main的setMapOutputKey以及Value的宣告,
卻無法執行, 我在一篇國外的論壇回文上看到了這說法"map的輸出型式需與combiner輸出形式相同",
我果斷將combiner註解掉....可以work了, 但是why...?我想用combiner啊!!(吶喊)
還請各位先進幫忙解惑..!!
1. 如果真的想要減少 Value 所佔的資料量,可以改用 NullWritable。Reducer 中,改計算拿到幾個 value。
只是我必須說....Text 跟 IntWritable 還有 NullWritable 都是「物件」不是「資料型態」
所以大小差多少....可能要跑跑 Debuger 才知道了
2. 關於
"map的輸出型式需與combiner輸出形式相同"的限制是因為您直接拿 Reducer 類別當 Combiner 吧?
根據出錯的情形,數學邏輯是這樣:
<Object, Text> -> map() -> <Text, Text>
您設計的 reducer 拿來當 combiner 會是 <Text, list(Text)> -> reduce() -> <Text, IntWritable>
此時所有 mapper 經過 combiner 後的結果是 <Text, list(IntWritable)>
跟 reducer 所需要的輸入 <Text, list(Text)> 是不相符的。
解法:另外設計一個類別給 Combiner 用。
- Jazz