我試圖使用Hadoop來格式化和排序非常大的數據集,但它似乎在跳過排序步驟。該映射器將Avro輸入文件轉換爲JSON中的一些有趣的字段。什麼會導致Hadoop跳過排序步驟?
void map(AvroWrapper<Datum> wrappedAvroDatum, NullWritable nothing,
OutputCollector<Text, Text> collector, Reporter reporter) {
Datum datum = wrappedAvroDatum.datum();
if (interesting(datum)) {
Long time = changeTimeZone(datum.getTime());
String key = "%02d".format(month(time));
String value = "{\"time\": %d, \"other-stuff\": %s, ...}".format(time, datum.getOtherStuff());
collector.collect(new Text(key), new Text(value));
}
}
減速器假定每個鍵的值是字典順序(適用於org.apache.hadoop.io.Text
,對吧?),只是去掉了按鍵,使我得到一個文本文件,每行一個JSON對象。
void reduce(Text key, java.util.Iterator<Text> values,
OutputCollector<NullWritable, Text> collector, Reporter reporter) {
while (values.hasNext()) {
collector.collect(NullWritable.get, new Text(values.next()));
}
}
我期待的是在一個月塊排序文本文件(也就是,我並不指望幾個月是爲了,但我希望每一個月內的時間是按順序)。我得到的是按月份分組但卻完全未排序的文本文件。顯然,Hadoop將Text
記錄按其鍵值分組,但不會對它們進行排序。
(已知問題:我依靠的事實是"time"
在我的JSON對象中排在第一位,並且所有記錄的位數都完全相同,所以詞典順序是數字順序。 )
當我使用Hadoop Streaming(不是該項目中的選項)時,文本行被自動排序---排序可以配置,但默認情況下它做了我想要的。在原始Hadoop中,排序是否需要以某種方式打開?如果是這樣,怎麼樣?如果它應該默認打開,我可以從哪裏開始調試這個問題?
我正在觀察Cloudera的CDH4 Hadoop-0.20軟件包在僞分佈式模式和Amazon Elastic Map-Reduce(EMR)中的這種行爲。
認真?!?在過去的一兩年Hadoop使用中,我不知何故錯過了這個基本觀點。我將不得不回過頭去看看Hadoop Streaming是否因做了一些不同的事情而誤導了我,或者我真的很無心以至於沒有注意到這一點。儘管如此,我將密鑰更改爲「%15d」.format(time)',現在我可以得到完全有序的結果,無需逐月塊(一個不錯的獎勵)。 –
我懷疑,當你使用流媒體時,你使用文本行作爲鍵,這就是爲什麼他們被排序。你可以看到[這個流教程](http://www.michael-noll.com/tutorials/writing-an-hadoop-mapreduce-program-in-python/)並檢查排序步驟是否與'sort - k1,1',即對鍵進行排序(按值排序將是'sort -k2,2')。 – cabad
@ jim-pivarski另請參閱我剛添加的最後一段。它鏈接到另一個SO問題,更多關於洗牌和排序階段的細節。 – cabad