
數據量大的時候,對數據進行采樣,然后再做模型分析。作為數據倉庫的必備品hive,我們如何對其進行采樣呢?
當然,浪尖寫本文還有另一個目的就是復習hive的四by。不止是否有印象呢?
Hive : SORT BY vs ORDER BY vs DISTRIBUTE BY vs CLUSTER BY
歡迎點擊閱讀原文,加入浪尖知識星球。

如果不對表進行排序,Hive不保證數據的順序,但在實踐中,它們按照它們在文件中的順序返回,所以這遠非真正隨機。那么接着可以嘗試:
這確實提供了真正的隨機數據,但性能並不是那么好。為了實現總排序,Hive必須將所有數據強制傳輸到單個reducer。該reducer將對整個數據集進行排序。這很不好。幸運的是,Hive有一個非標准SQL“sort by”子句,它只在單個reducer中排序,並且不保證數據跨多個reducers中排序:
這要好得多,但我不相信它真的是隨機的。問題是Hive的將數據拆分為多個reducer的方法是未定義的。它可能是真正隨機的,它可能基於文件順序,它可能基於數據中的某些值。Hive如何在reducers中實現limit子句也是未定義的。也許它按順序從reducer中獲取數據 - 即,reducer 0中的所有數據,然后全部來reducer1,等等。也許它通過它們循環並將所有內容混合在一起。
在最壞的情況下,假設reduce 的key是基於數據列,而limit子句是reducers的順序。然后樣品會非常傾斜。
解決方案是另一個非標准的Hive功能:“distribute by”。對於reduce key不是由查詢結構確定的查詢(沒有“group by”,沒有join),可以准確指定reduce key的內容。如果我們隨機分布,並在每個reducer中隨機排序,那么“limit”功能如何無關緊要。
最后,作為最后一次優化,可以在map-side做一些過濾。如果表的總大小是已知的,全球高校排名輕松設置一個隨機閾值條件來進行數據過濾,如下所示:
在這種情況下,由於總大小是100億,樣本大小是一萬,我可以很容易地計算出樣本占總數據的0.000001。但是,如果where子句是“rand()<0.000001”,則最終輸出的行數可能少於10000行。“rand()<0.000002”可能會起作用,但這確實依賴於rand()有非常好的實現。最后它並不重要,因為瓶頸是全表掃描,而不是傳輸給reducer的這點數據。
推薦閱讀:
Hive鮮為人知的寶石-Hooks
Hive性能優化(全面)
不可不知的spark shuffle

文章來源:https://blog.csdn.net/rlnLo2pNEfx9c/article/details/82121139
