寫mapreduce程序時,如果reduce個數>1,想要實現全排序需要控制好map的輸出,詳見Hadoop簡單實現全排序。
現在學了hive,寫sql大家都很熟悉,如果一個order by解決了全排序還用那么麻煩寫mapreduce函數嗎?
事實上,hive使用order by會默認設置reduce的個數=1,既然reducer的個數都是1了,結果自然全排序!
這也違背了充分利用分布式計算進行海量數據排序的初衷,效率低下。
那么hive又提供了一個可供選擇的方式:sort by
它會保證每個reducer的輸出文件是有序的(其實是廢話,每個reducer的輸出當然是有序的!),要想實現全排序,還得加一個order by的過程,就是對sort by的reduce輸出結果再進行一次排序。
所以:
要想用hive實現全排序:
要么用order by,但這樣默認了reducer個數為1,效率低下。
要么用sort by+order by,sort by過程可以設置reducer個數(n),order by過程用n個reducer的輸出文件進行一次全排序,得到最終的結果。
(個人理解,如有錯誤請不吝賜教,感謝!)
注:
(1)對於order by,sort by:
我們可以使用limit進行限制返回的行數,從而實現抓出數據的top N的情形。
(2)對於distribute by:
sort by為每個reducer產生一個排序文件。在有些情況下,你需要控制某個特定行應該到哪個reducer,通常是為了進行后續的聚集操作。hive的distribute by就派上用場了:
from table select year, temperature distribute by year sort by year asc, temperature desc;
上面實現了局部排序,且規定了:根據年份和氣溫對氣象數據進行排序,以確保所有具有相同年份的行最終都在一個reducer分區中(文件下),可以看出,distribute by經常與sort by一起使用。
需要注意的是,hive要求distribute by要寫在sort by之前。
(3)對於cluster by:
簡而言之:cluster by column=distribute by column+sort by column(注意,都是針對column列,且采用默認ASC)
即對於上面例子:
from table select year, temperature cluster by year;
就等於:
from table select year, temperature distribute by year sort by year;
當然這失去了按照氣溫排序的要求。
參考:https://www.jianshu.com/p/1a3625a71118 僅供個人學習,有改動