如何通俗地理解Hive的工作原理?

時間 2021-05-08 08:48:47

1樓:普適極客

謂詞下推

就是將SQL語句中的where謂詞邏輯都盡可能提前執行,減少下游處理的資料量。Hive中有謂詞下推優化的配置項hive.optimize.

ppd,預設值true,與它對應的邏輯優化器是PredicatePushDown。該優化器就是將OperatorTree中的FilterOperator向上提,見下圖。

Group by

(1) map端預聚合

group by時,如果先起乙個combiner在map端做部分預聚合,可以有效減少shuffle資料量。預聚合的配置項是hive.map.

aggr,預設值true。通過hive.groupby.

mapaggr.checkinterval引數也可以設定map端預聚合的行數閾值,超過該值就會分拆job,預設值100000。

(2) 傾斜均衡配置項

group by時如果某些key對應的資料量過大,就會發生資料傾斜。配置均衡資料傾斜的配置項hive.groupby.skewindata=true。

其實現方法是在group by時啟動兩個MR job。第乙個job會將map端資料隨機輸入reducer,每個reducer做部分聚合,相同的key就會分布在不同的reducer中。第二個job再將前面預處理過的資料按key聚合並輸出結果,這樣就起到了均衡的效果。

Join

1、多表join時key相同

如果多表的join時候用的key相同,只會啟動乙個MR job來處理。

select *

from calendar_event_code a

inner join calendar_record_log b

on a.event_type = b.event_type

inner join calendar_record_log_2 c

on a.event_type = c.event_type;

如果上面兩個join的條件不相同,比如改成a.event_code = c.event_code,就會拆成兩個MR job計算。

2、利用map join

Map join特別適合大小表join的情況。Hive會將大小表在map端直接完成join過程,避免shuffle過程和reduce端計算,大大的提高效率。

map join,配置hive.auto.convert.

join=true。還有一些引數用來控制map join的行為,比如hive.mapjoin.

smalltable.filesize,當小表大小小於該值就會啟用map join,預設值25000000(25MB)。還有hive.

mapjoin.cache.numrows,表示快取小表的多少行資料到記憶體,預設值25000。

3、傾斜均衡配置項

配置hive.optimize.skewjoin=true

4、優化sql處理join的資料傾斜

(1) 空值或者無意義值

若不需要空值資料,就提前寫where語句過濾掉。需要保留的話,將空值key用隨機方式打散

select a.uid,a.event_type,b.nickname,b.age

from (select

(case when uid is null then cast(rand()*-10240 as int) else uid end) as uid,

event_type from calendar_record_log

) aleft outer join user_info b

on a.uid = b.uid;

(2) 單獨處理資料傾斜key

這其實是上面處理空值方法的拓展,不過傾斜的key變成了有意義的。我們可以將它們抽樣出來,對應的行單獨存入臨時表中,然後打上乙個較小的隨機數字首(比如0~9),最後再進行聚合。SQL語句與上面的相仿

(3) 不同資料型別

舉個例子,假如我們有一舊一新兩張日曆記錄表,舊表的記錄型別欄位是(event_type int),新錶的是(event_type string)。為了相容舊版記錄,新錶的event_type也會以字串形式儲存舊版的值,比如'17'。當這兩張表join時,經常要耗費很長時間。

其原因就是如果不轉換型別,計算key的hash值時預設是以int型做的,這就導致所有「真正的」string型key都分配到乙個reducer上。

select a.uid,a.event_type,b.record_data

from calendar_record_log a

left outer join calendar_record_log_2 b

on a.uid = b.uid and b.event_type = cast(a.event_type as string);

(4) 小表過大

小表會大到無法直接使用map join的地步,而使用普通join又有資料分布不均的問題。這時就要充分利用大表的限制條件,削減小表的資料量,再使用map join解決。代價就是需要進行兩次join。

select /*+mapjoin(b)*/ a.uid,a.event_type,b.status,b.extra_info

from calendar_record_log a

left outer join

( select /*+mapjoin(s)*/ t.uid,t.status,t.extra_info

from

( select distinct uid from calendar_record_log

where pt_date = 20190228

) sinner join user_info t

on s.uid = t.uid

) bon a.uid = b.uid

where a.pt_date = 20190228;

總結:本文主要介紹hql語句本身優化和hive配置優化來提高hive效率。但job或者I/O過多,MapReduce分配不合理等都會影響到hive效率。

無論哪一種優化方法都要根據具體的應用場景決定。

2樓:寸頭哥

理解了下面兩點就可以理解hive的工作原理:

1,hive把結構化資料對映為一張表, 然後使用類sql語言進行查詢;

2,hive的將sql查詢語言轉化為mapreduce實現;

對於第一點, 什麼是結構化資料. 我的理解: 就像是mysql中的資料, 方方正正(就像軍訓時候的方隊),整整齊齊,各個資料之間統一分隔開,每行資料統一的分隔符分隔;

這樣的資料, ,和mysql中的資料是不是幾乎一樣了呢??給這個資料加個字段, 約束啥的, 就完全是mysql中的資料了吧??

但是, 轉化為mysql中的資料行不行呢?? 不是特別好.

對於這些資料, 我的用途和mysql中儲存的用途不一樣!! (資料量太大, 主要用來分析,不需要天天去增刪改查,blabla ), 所以, 就那樣放著吧, 我使用另外一種方式去研究它;

怎麼研究?? mapreduce??

然鵝, mapreduce實在是太冗長了, 寫起來鍵盤消耗太大,於是我們寫sql, 然後hive將sql轉化為mapreduce(至於怎麼轉化的, AST抽象語法樹有興趣的了解一波)執行,這樣就簡單多了;

sql是一種程式語言, mapreduce也是一種程式設計方式, 雖然他們屬於不同的語言, 但是其反映的邏輯,可以是一樣的.就好像乙個喝水的東西, 叫"cup", 也叫"杯子". 給你乙個任務, 你可以使用兩種語言實現;

如何通俗簡單地理解 Inbound Marketing 和 Outbound Marketing

吳嘉陽 簡單一句話,以客戶需求的強烈程度分 主動營銷 inbound marketing 使用者需求相對較高,使用者主動索取產品相關資訊 和被動營銷 outbound marketing 使用者需求相對較低,被動被強推來索取產品資訊 劉延飛 Inbound marketing會慢慢成為marketi...

如何最簡單 通俗地理解Softmax演算法?

老杜 softmax就是soft版本的max,理解了soft的含義就理解softmax了。什麼叫soft版本?我們先看看普通的max,以及普通max hard在什麼地方。比如說三個數x 2,1,5 求max x 小學生都會,答案是5,很簡單.如果以向量的方式表達這個對映關係,也可以表示成max x ...

如何最簡單 通俗地理解C 的結構體?

小王同學在積累 一 筆記 二 筆記目錄 結構體屬於使用者自定義的資料型別,允許使用者儲存不同的資料型別。語法 struct 結構體名 通過結構體建立變數的方式有三種 1 struct 結構體名變數名 2 struct 結構體名變數名 3 定義結構體時順便建立變數 結構體變數利用點.訪問成員 incl...