日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Hive學(xué)習(xí)之路 (十九)Hive的數(shù)據(jù)傾斜

 HK123COM 2019-02-14

目錄

 

正文

1、什么是數(shù)據(jù)傾斜?

由于數(shù)據(jù)分布不均勻,造成數(shù)據(jù)大量的集中到一點(diǎn),造成數(shù)據(jù)熱點(diǎn)

2、Hadoop 框架的特性

  A、不怕數(shù)據(jù)大,怕數(shù)據(jù)傾斜

  B、Jobs 數(shù)比較多的作業(yè)運(yùn)行效率相對比較低,如子查詢比較多

  C、 sum,count,max,min 等聚集函數(shù),通常不會有數(shù)據(jù)傾斜問題

3、主要表現(xiàn)

任務(wù)進(jìn)度長時間維持在 99%或者 100%的附近,查看任務(wù)監(jiān)控頁面,發(fā)現(xiàn)只有少量 reduce 子任務(wù)未完成,因?yàn)槠涮幚淼臄?shù)據(jù)量和其他的 reduce 差異過大。 單一 reduce 處理的記錄數(shù)和平均記錄數(shù)相差太大,通常達(dá)到好幾倍之多,最長時間遠(yuǎn)大 于平均時長。

4、容易數(shù)據(jù)傾斜情況

  A、group by 不和聚集函數(shù)搭配使用的時候

  B、count(distinct),在數(shù)據(jù)量大的情況下,容易數(shù)據(jù)傾斜,因?yàn)?count(distinct)是按 group by 字段分組,按 distinct 字段排序

  C、 小表關(guān)聯(lián)超大表 join

5、產(chǎn)生數(shù)據(jù)傾斜的原因

  A:key 分布不均勻

  B:業(yè)務(wù)數(shù)據(jù)本身的特性

  C:建表考慮不周全

  D:某些 HQL 語句本身就存在數(shù)據(jù)傾斜

6、業(yè)務(wù)場景

(1)空值產(chǎn)生的數(shù)據(jù)傾斜

場景說明

在日志中,常會有信息丟失的問題,比如日志中的 user_id,如果取其中的 user_id 和用戶表中的 user_id 相關(guān)聯(lián),就會碰到數(shù)據(jù)傾斜的問題。

解決方案

解決方案 1:user_id 為空的不參與關(guān)聯(lián)

select * from log a join user b on a.user_id is not null and a.user_id = b.user_id
union all
select * from log c where c.user_id is null;

解決方案 2:賦予空值新的 key 值

select * from log a left outer join user b on
case when a.user_id is null then concat('hive',rand()) else a.user_id end = b.user_id

總結(jié)

方法 2 比方法 1 效率更好,不但 IO 少了,而且作業(yè)數(shù)也少了,方案 1 中,log 表 讀了兩次,jobs 肯定是 2,而方案 2 是 1。這個優(yōu)化適合無效 id(比如-99,’’,null)產(chǎn) 生的數(shù)據(jù)傾斜,把空值的 key 變

成一個字符串加上一個隨機(jī)數(shù),就能把造成數(shù)據(jù)傾斜的 數(shù)據(jù)分到不同的 reduce 上解決數(shù)據(jù)傾斜的問題。

改變之處:使本身為 null 的所有記錄不會擁擠在同一個 reduceTask 了,會由于有替代的 隨機(jī)字符串值,而分散到了多個 reduceTask 中了,由于 null 值關(guān)聯(lián)不上,處理后并不影響最終結(jié)果。

(2)不同數(shù)據(jù)類型關(guān)聯(lián)產(chǎn)生數(shù)據(jù)傾斜

場景說明

用戶表中 user_id 字段為 int,log 表中 user_id 為既有 string 也有 int 的類型, 當(dāng)按照兩個表的 user_id 進(jìn)行 join 操作的時候,默認(rèn)的 hash 操作會按照 int 類型的 id 進(jìn) 行分配,這樣就會導(dǎo)致所有的 string 類型的 id 就被分到同一個 reducer 當(dāng)中

解決方案

把數(shù)字類型 id 轉(zhuǎn)換成 string 類型的 id

select * from user a left outer join log b on b.user_id = cast(a.user_id as string)

(3)大小表關(guān)聯(lián)查詢產(chǎn)生數(shù)據(jù)傾斜 

 注意:使用map join解決小表關(guān)聯(lián)大表造成的數(shù)據(jù)傾斜問題。這個方法使用的頻率很高。

map join 概念:將其中做連接的小表(全量數(shù)據(jù))分發(fā)到所有 MapTask 端進(jìn)行 Join,從 而避免了 reduceTask,前提要求是內(nèi)存足以裝下該全量數(shù)據(jù)

以大表 a 和小表 b 為例,所有的 maptask 節(jié)點(diǎn)都裝載小表 b 的所有數(shù)據(jù),然后大表 a 的 一個數(shù)據(jù)塊數(shù)據(jù)比如說是 a1 去跟 b 全量數(shù)據(jù)做鏈接,就省去了 reduce 做匯總的過程。 所以相對來說,在內(nèi)存允許的條件下使用 map join 比直接使用 MapReduce 效率還高些, 當(dāng)然這只限于做 join 查詢的時候。

在 hive 中,直接提供了能夠在 HQL 語句指定該次查詢使用 map join,map join 的用法是 在查詢/子查詢的SELECT關(guān)鍵字后面添加/*+ MAPJOIN(tablelist) */提示優(yōu)化器轉(zhuǎn)化為map join(早期的 Hive 版本的優(yōu)化器是不能自動優(yōu)化 map join 的)。其中 tablelist 可以是一個 表,或以逗號連接的表的列表。tablelist 中的表將會讀入內(nèi)存,通常應(yīng)該是將小表寫在 這里。

MapJoin 具體用法:

select /* +mapjoin(a) */ a.id aid, name, age from a join b on a.id = b.id;
select /* +mapjoin(movies) */ a.title, b.rating from movies a join ratings b on a.movieid =
b.movieid;

在 hive0.11 版本以后會自動開啟 map join 優(yōu)化,由兩個參數(shù)控制:

set hive.auto.convert.join=true; //設(shè)置 MapJoin 優(yōu)化自動開啟

set hive.mapjoin.smalltable.filesize=25000000 //設(shè)置小表不超過多大時開啟 mapjoin 優(yōu)化

如果是大大表關(guān)聯(lián)呢?那就大事化小,小事化了。把大表切分成小表,然后分別 map join

那么如果小表不大不小,那該如何處理呢???

使用 map join 解決小表(記錄數(shù)少)關(guān)聯(lián)大表的數(shù)據(jù)傾斜問題,這個方法使用的頻率非常 高,但如果小表很大,大到 map join 會出現(xiàn) bug 或異常,這時就需要特別的處理

舉一例:日志表和用戶表做鏈接

select * from log a left outer join users b on a.user_id = b.user_id;

users 表有 600w+的記錄,把 users 分發(fā)到所有的 map 上也是個不小的開銷,而且 map join 不支持這么大的小表。如果用普通的 join,又會碰到數(shù)據(jù)傾斜的問題。

改進(jìn)方案:

復(fù)制代碼
select /*+mapjoin(x)*/* from log a
left outer join (
 select /*+mapjoin(c)*/ d.*
 from ( select distinct user_id from log ) c join users d on c.user_id = d.user_id
) x
on a.user_id = x.user_id;
復(fù)制代碼

假如,log 里 user_id 有上百萬個,這就又回到原來 map join 問題。所幸,每日的會員 uv 不會太多,有交易的會員不會太多,有點(diǎn)擊的會員不會太多,有傭金的會員不會太多等 等。所以這個方法能解決很多場景下的數(shù)據(jù)傾斜問題

 

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多