資料倉儲 Hive的調優

2021-09-25 09:14:58 字數 3828 閱讀 5593

hive的調優:

第乙個調優:fetch抓取,能夠避免使用mr的,就盡量不要用mr,因為mr太慢了

set hive.fetch.task.conversion=more  表示我們的全域性查詢,字段查詢,limit查詢都不走mr

這個屬性配置有三個取值  more  minimal  none  如果配置成none,所有的都要走mr程式

hive的本地模式:

set hive.exec.mode.local.auto=true  開啟本地模式,解決多個小檔案輸入的時候,分配資源時間超過資料的計算時間

set hive.exec.mode.local.auto.inputbytes.max=51234560; 設定輸入的資料臨界值,如果小於這值都認為是小任務模式,啟動本地模式來執行

set hive.exec.mode.local.auto.input.files.max=10;  設定輸入檔案個數的臨界值,如果小於這個數量,那麼也認為是小任務模式

第二個優化:hive表的優化

去重的優化:

select count(distinct s_id) from score;這種寫法所有的去重資料都會在乙個reduce當中去,造成資料處理比較慢

select count(1) from (select s_id from score group by s_id) bysid; 這種寫法,使用了乙個巢狀子查詢,先對資料進行group  by去重,然後再進行統計

盡量避免大sql,可以將乙個很大的sql拆成多段,分步的去執行

大表join大表的優化:

空key的過濾

不過濾:

insert overwrite table jointable

select a.* from nullidtable a join ori b on a.id = b.id;

結果:no rows affected (152.135 seconds)

過濾:過濾掉我們所有的為null的id,使得我們的輸入資料量變少

insert overwrite table jointable

select a.* from (select * from nullidtable where id is not null ) a join ori b on a.id = b.id;

結果:no rows affected (141.585 seconds)

空key的轉換

如果規定這些空key過濾不調,那麼我們可以對空key進行轉換

select a.*

from nullidtable a

left join ori b on case when a.id is null then 'hive' else a.id end = b.id;

如果空key比較多,那麼就會將大量的空key轉換成 hive,那麼就會遇到乙個問題,資料傾斜

資料傾斜的表現形式:有乙個reduce處理的資料量遠遠比其他reduce處理的資料量要大,造成其他的reduce資料都處理完了,這個還沒處理完

怎麼發現的資料傾斜,如何出現的資料傾斜,怎麼解決的資料傾斜

空key的打散

select a.*

from nullidtable a

left join ori b on case when a.id is null then concat('hive', rand()) else a.id end = b.id;

通過將空key打散成不同的隨記字串,就可以解決我們hive的資料傾斜的問題

hive第三個優化:map端的join

hive已經開啟了自動的map端的join功能,不管是我們的大表join小表,還是小表join大表,都會將我們的小表載入到記憶體當中來

首先第一步:啟動乙個local的task,尋找哪個表的資料是小表資料

hive的group  by優化:能在map端聚合的資料,就盡量在map端進行聚合

多加一層mr的程式,讓我們的資料實現均衡的負載,避免資料的傾斜

count(distinct)的優化:

這種寫法效率低下:select count(distinct id) from bigtable;

可以準換成這種寫法:select count(id) from (select id from bigtable group by id) a;

笛卡爾積:任何時候都要避免笛卡爾積,避免無效的on條件

select from   a   left join  b  -- on a.id  = b.id

使用分割槽裁剪,列裁剪:

分割槽裁剪:如果是我們的分割槽表,那麼查詢的時候,盡量帶上我們的分割槽條件

列裁剪:盡量避免使用select  * ,需要查詢哪些列,就選擇哪些列

動態分割槽調整:

分割槽表的資料載入兩種方式:

load  data  inpath  '/export/***' into table *** partition(month = '***')

insert  overwrite table  *** partition (month = '***') select  ***

使用動態分割槽動態的新增資料

如果要使用動態分割槽新增資料,最後乙個字段一定要是我們的分割槽字段

insert overwrite table ori_partitioned_target partition (p_time)

select id, time, uid, keyword, url_rank, click_num, click_url, p_time

from ori_partitioned;

資料的傾斜:

主要就是合理的控制我們的map個數以及reduce個數

第乙個問題:maptask的個數怎麼定的???與我們檔案的block塊相關,預設乙個block塊就是對應乙個maptask

第二個問題:reducetask的個數怎麼定的???是我們自己手動設定的,愛設幾個設幾個,沒人管你

第三個問題:是不是maptask的個數越多越好:不一定:有時候有些小檔案,都要啟動乙個maptask,分配資源的時間超過了資料處理的時間

減少maptask的個數:設定map端的小檔案合併:使用combinehiveinputformat來實現對我們小檔案的合併,減少maptask的個數  或者使用本地模式也可以解決小檔案的問題

增加maptask的個數:我們可以多設定幾個reduce,然後使用distribte  by將我們的資料打散

set mapreduce.job.reduces =10;

create table a_1 as

select * from a

distribute by rand(123);

第四個問題:控制reducetask的個數:

reduce個數設定方法:

(1)每個reduce處理的資料量預設是256mb

hive.exec.reducers.bytes.per.reducer=256123456

(2)每個任務最大的reduce數,預設為1009

hive.exec.reducers.max=1009

(3)計算reducer數的公式

n=min(引數2,總輸入資料量/引數1)

直接憑感覺設定reduce的個數:

set mapreduce.job.reduces = 15;

檢視執行計畫:

explain extended select * from course;

並行執行:有時候有些sql之間是不相關的,可以並行的一起執行,那麼就可以用並行執行

嚴格模式: 如果開啟hive的嚴格模式,有以下三個限制

1、分割槽表需要帶上分割槽字段

2、order by 必須使用limit

3、笛卡爾積不能執行

資料倉儲hive調優經驗總結

hive是資料倉儲,主要涉及到對海量資料的儲存和讀取,以及資料的處理。資料的儲存和讀取基本是基於hadoop的hdfs,所以要進行的優化就是提高資料的傳輸速度,可以通過配置引數 map和reduce階段 優化hive的效能 如 在map階段設定task的數量 mapred.min.split.siz...

Hive 資料倉儲

hive命令列模式 1 進入bin 執行.hiv 2 配置hive環境變數,直接執行命令 hive service cli 或 hive hive的web模式 執行hive service hwi 啟動後訪問http master 9999 hwi hive的遠端服務 預設埠 10000,執行啟動命...

資料倉儲Hive

資料倉儲是乙個面向主題的 整合的 相對穩定的 反映歷史變化的資料集合,用於支援管理決策。根本目的是為了支援企業內部的商業分析和決策,基於資料倉儲的分析結果,做出相關的經營決策.資料倉儲中的資料比較穩定,保留了大量歷史資料 而資料庫只儲存某一時刻的資料.對於傳統資料倉儲來說,既是資料儲存產品也是分析產...