成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

數(shù)據(jù)分析工具篇-HQL原理及優(yōu)化

大數(shù)據(jù) 數(shù)據(jù)分析
本文我們就深入HQL的原理中,探索HQL優(yōu)化的方法和邏輯。

[[375711]]

 HQL是數(shù)據(jù)分析過程中的必備技能,隨著數(shù)據(jù)量增加,這一技能越來越重要,熟練應用的同時會帶來效率的問題,動輒十幾億的數(shù)據(jù)量如果處理不完善的話有可能導致一個作業(yè)運行幾個小時,更嚴重的還有可能因占用過多資源而引發(fā)生產(chǎn)問題,所以HQL優(yōu)化就變得非常重要,本文我們就深入HQL的原理中,探索HQL優(yōu)化的方法和邏輯。

group by的計算原理

代碼為:

  1. SELECT uid, SUM(COUNTFROM logs GROUP BY uid; 

 

可以看到,group by本身不是全局變量,任務會被分到各個map中進行分組,然后再在reduce中聚合。

默認設置了hive.map.aggr=true,所以會在mapper端先group by一次,最后再把結果merge起來,為了減少reducer處理的數(shù)據(jù)量。注意看explain的mode是不一樣的。mapper是hash,reducer是mergepartial。如果把hive.map.aggr=false,那將groupby放到reducer才做,他的mode是complete。

優(yōu)化點:

Group by主要是面對數(shù)據(jù)傾斜的問題。

很多聚合操作可以現(xiàn)在map端進行,最后在Reduce端完成結果輸出:

  1. Set hive.map.aggr = true;  # 是否在Map端進行聚合,默認為true; 
  2. Set hive.groupby.mapaggr.checkinterval = 1000000;  # 在Map端進行聚合操作的條目數(shù)目; 

當使用Group by有數(shù)據(jù)傾斜的時候進行負載均衡:

  1. Set hive.groupby.skewindata = true; # hive自動進行負載均衡; 

策略就是把MR任務拆分成兩個MR Job:第一個先做預匯總,第二個再做最終匯總;

第一個Job:

Map輸出結果集中緩存到maptask中,每個Reduce做部分聚合操作,并輸出結果,這樣處理的結果是相同Group by Key有可能被分到不同的reduce中,從而達到負載均衡的目的;

第二個Job:

根據(jù)第一階段處理的數(shù)據(jù)結果按照group by key分布到reduce中,保證相同的group by key分布到同一個reduce中,最后完成最終的聚合操作。

join的優(yōu)化原理

代碼為:

  1. SELECT a.id,a.dept,b.age FROM a join b ON (a.id = b.id); 

 

1)Map階段:

讀取源表的數(shù)據(jù),Map輸出時候以Join on條件中的列為key,如果Join有多個關聯(lián)鍵,則以這些關聯(lián)鍵的組合作為key;

Map輸出的value為join之后所關心的(select或者where中需要用到的)列;同時在value中還會包含表的Tag信息,用于標明此value對應哪個表;

按照key進行排序;

2)Shuffle階段:

根據(jù)key的值進行hash,并將key/value按照hash值推送至不同的reduce中,這樣確保兩個表中相同的key位于同一個reduce中。

3)Reduce階段:

根據(jù)key的值完成join操作,期間通過Tag來識別不同表中的數(shù)據(jù)。

在多表join關聯(lián)時:

如果 Join 的 key 相同,不管有多少個表,都會合并為一個 Map-Reduce,例如:

  1. SELECT pv.pageid, u.age  
  2. FROM page_view p  
  3. JOIN user u  
  4. ON (pv.userid = u.userid)  
  5. JOIN newuser x  
  6. ON (u.userid = x.userid); 

如果 Join 的 key不同,Map-Reduce 的任務數(shù)目和 Join 操作的數(shù)目是對應的,例如:

  1. SELECT pv.pageid, u.age  
  2. FROM page_view p  
  3. JOIN user u  
  4. ON (pv.userid = u.userid)  
  5. JOIN newuser x  
  6. on (u.age = x.age); 

優(yōu)化點:

1)應該將條目少的表/子查詢放在 Join 操作符的左邊。

2)我們知道文件數(shù)目小,容易在文件存儲端造成瓶頸,給 HDFS 帶來壓力,影響處理效率。對此,可以通過合并Map和Reduce的結果文件來消除這樣的影響。用于設置合并屬性的參數(shù)有:

  1. 合并Map輸出文件:hive.merge.mapfiles=true(默認值為真) 
  2. 合并Reduce端輸出文件:hive.merge.mapredfiles=false(默認值為假) 
  3. 合并文件的大小:hive.merge.size.per.task=256*1000*1000(默認值為 256000000) 

3) Common join即普通的join,性能較差,因為涉及到了shuffle的過程(Hadoop/spark開發(fā)的過程中,有一個原則:能避免不使用shuffle就不使用shuffle),可以轉化成map join。

  1. hive.auto.convert.join=true;# 表示將運算轉化成map join方式 

使用的前提條件是需要的數(shù)據(jù)在 Map 的過程中可以訪問到。

 

1)啟動Task A:Task A去啟動一個MapReduce的local task;通過該local task把small table data的數(shù)據(jù)讀取進來;之后會生成一個HashTable Files;之后將該文件加載到分布式緩存(Distributed Cache)中來;

2)啟動MapJoin Task:去讀大表的數(shù)據(jù),每讀一個就會去和Distributed Cache中的數(shù)據(jù)去關聯(lián)一次,關聯(lián)上后進行輸出。

整個階段,沒有reduce 和 shuffle,問題在于如果小表過大,可能會出現(xiàn)OOM。

Union與union all優(yōu)化原理

union將多個結果集合并為一個結果集,結果集去重。代碼為:

  1. select id,name  
  2. from t1  
  3. union  
  4. select id,name  
  5. from t2  
  6. union  
  7. select id,name  
  8. from t3 

對應的運行邏輯為:


union all將多個結果集合并為一個結果集,結果集不去重。使用時多與group by結合使用,代碼為:

  1. select all.id, all.name  
  2. from
  3.    select id,name  
  4.    from t1  
  5.    union all  
  6.    select id,name  
  7.    from t2  
  8.    union all  
  9.    select id,name  
  10.    from t3 
  11. )all  
  12. group by all.id ,all.name 

對應的運行邏輯為:


從上面的兩個邏輯圖可以看到,第二種寫法性能要好。union寫法每兩份數(shù)據(jù)都要先合并去重一次,再和另一份數(shù)據(jù)合并去重,會產(chǎn)生較多次的reduce。第二種寫法直接將所有數(shù)據(jù)合并再一次性去重。

對union all的操作除了與group by結合使用還有一些細節(jié)需要注意:

1)對 union all 優(yōu)化只局限于非嵌套查詢。

原代碼:job有3個:

  1. SELECT *  
  2. FROM 
  3.   SELECT *  
  4.   FROM t1  
  5.   GROUP BY c1,c2,c3  
  6.   UNION ALL  
  7.   SELECT *  
  8.   FROM t2  
  9.   GROUP BY c1,c2,c3 
  10. )t3 
  11. GROUP BY c1,c2,c3 

這樣的結構是不對的,應該修改為:job有1個:

  1. SELECT *  
  2. FROM  
  3.   SELECT *  
  4.   FROM t1  
  5.   UNION ALL  
  6.   SELECT *  
  7.   FROM t2 
  8. )t3  
  9. GROUP BY c1,c2,c3 

這樣的修改可以減少job數(shù)量,進而提高效率。

2)語句中出現(xiàn)count(distinct …)結構時:

原代碼為:

  1. SELECT *  
  2. FROM 
  3.   SELECT * FROM t1 
  4.   UNION ALL 
  5.   SELECT c1,c2,c3,COUNT(DISTINCT c4)  
  6.   FROM t2 GROUP BY c1,c2,c3 
  7. ) t3 
  8. GROUP BY c1,c2,c3; 

修改為:(采用臨時表消滅 COUNT(DISTINCT)作業(yè)不但能解決傾斜問題,還能有效減少jobs)。

  1. INSERT t4 SELECT c1,c2,c3,c4 FROM t2 GROUP BY c1,c2,c3; 
  2.  
  3. SELECT c1,c2,c3,SUM(income),SUM(uv) FROM 
  4. SELECT c1,c2,c3,income,0 AS uv FROM t1 
  5. UNION ALL 
  6. SELECT c1,c2,c3,0 AS income,1 AS uv FROM t2 
  7. ) t3 
  8. GROUP BY c1,c2,c3; 

Order by的優(yōu)化原理

如果指定了hive.mapred.mode=strict(默認值是nonstrict),這時就必須指定limit來限制輸出條數(shù),原因是:所有的數(shù)據(jù)都會在同一個reducer端進行,數(shù)據(jù)量大的情況下可能不能出結果,那么在這樣的嚴格模式下,必須指定輸出的條數(shù)。

所以數(shù)據(jù)量大的時候能不用order by就不用,可以使用sort by結合distribute by來進行實現(xiàn)。

sort by是局部排序;

distribute by是控制map怎么劃分reducer。

  1. cluster by=distribute by + sort by 

被distribute by設定的字段為KEY,數(shù)據(jù)會被HASH分發(fā)到不同的reducer機器上,然后sort by會對同一個reducer機器上的每組數(shù)據(jù)進行局部排序。


例如:

  1. select mid, money, name  
  2. from store  
  3. cluster by mid 
  4.  
  5. select mid, money, name  
  6. from store  
  7. distribute by mid  
  8. sort by mid 

如果需要獲得與上面的中語句一樣的效果:

  1. select mid, money, name  
  2. from store  
  3. cluster by mid  
  4. sort by money 

注意被cluster by指定的列只能是降序,不能指定asc和desc。

不過即使是先distribute by然后sort by這樣的操作,如果某個分組數(shù)據(jù)太大也會超出reduce節(jié)點的存儲限制,常常會出現(xiàn)137內存溢出的錯誤,對大數(shù)據(jù)量的排序都是應該避免的。

Count(distinct …)優(yōu)化

如下的sql會存在性能問題:

  1. SELECT COUNTDISTINCT id ) FROM TABLE_NAME WHERE ...; 

主要原因是COUNT這種“全聚合(full aggregates)”計算時,它會忽略用戶指定的Reduce Task數(shù),而強制使用1,這會導致最終Map的全部輸出由單個的ReduceTask處理。這唯一的Reduce Task需要Shuffle大量的數(shù)據(jù),并且進行排序聚合等處理,這使得它成為整個作業(yè)的IO和運算瓶頸。

圖形如下:


為了避免這一結構,我們采用嵌套的方式優(yōu)化sql:

  1. SELECT COUNT(*)  
  2. FROM ( 
  3.   SELECT DISTINCT id FROM TABLE_NAME WHERE …  
  4. ) t; 

這一結構會將任務切分成兩個,第一個任務借用多個reduce實現(xiàn)distinct去重并進行初步count計算,然后再將計算結果輸出到第二個任務中進行計數(shù)。

 

另外,再有的方法就是用group by()嵌套代替count(distinct a)。

如果能用group by的就盡量使用group by,因為group by性能比distinct更好。

HiveSQL細節(jié)優(yōu)化

1) 設置合理的mapreduce的task數(shù),能有效提升性能。

  1. set mapred.reduce.tasks=n 

2) 在sql中or的用法需要加括號,否則可能引起無分區(qū)限制:

  1. Select x 
  2. from t  
  3. where ds=d1  
  4. and (province=’gd’ or province=’gx’) 

3) 對運算結果進行壓縮:

  1. set hive.exec.compress.output=true

4) 減少生成的mapreduce步驟:

4.1)使用CASE…WHEN…代替子查詢;

4.2)盡量盡早地過濾數(shù)據(jù),減少每個階段的數(shù)據(jù)量,對于分區(qū)表要加分區(qū),同時只選擇需要使用到的字段;

5) 在map階段讀取數(shù)據(jù)前,F(xiàn)ileInputFormat會將輸入文件分割成split。split的個數(shù)決定了map的個數(shù)。

  1. mapreduce.input.fileinputformat.split.minsize 默認值 0 
  2. mapreduce.input.fileinputformat.split.maxsize 默認值 Integer.MAX_VALUE 
  3. dfs.blockSize 默認值 128M,所以在默認情況下 map的數(shù)量=block數(shù) 

6) 常用的參數(shù):

  1. hive.exec.reducers.bytes.per.reducer=1000000; 

設置每個reduce處理的數(shù)據(jù)量,reduce個數(shù)=map端輸出數(shù)據(jù)總量/參數(shù);

  1. set hive.mapred.mode=nonstrict; 
  2. set hive.exec.dynamic.partition=true
  3. set hive.exec.dynamic.partition.mode=nonstrict; 
  4. set mapred.job.name=p_${v_date}; 
  5. set mapred.job.priority=HIGH; 
  6. set hive.groupby.skewindata=true
  7. set hive.merge.mapredfiles=true
  8. set hive.exec.compress.output=true
  9. set mapred.output.compression.codec=org.apache.hadoop.io.compress.SnappyCodec; 
  10. set mapred.output.compression.type=BLOCK; 
  11. set mapreduce.map.memory.mb=4096; 
  12. set mapreduce.reduce.memory.mb=4096; 
  13. set hive.hadoop.supports.splittable.combineinputformat=true
  14. set mapred.max.split.size=16000000; 
  15. set mapred.min.split.size.per.node=16000000; 
  16. set mapred.min.split.size.per.rack=16000000; 
  17. set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; 
  18. set hive.exec.reducers.bytes.per.reducer=128000000; 

7)設置map個數(shù):

map個數(shù)和來源表文件壓縮格式有關,.gz格式的壓縮文件無法切分,每個文件會生成一個map;

  1. set hive.hadoop.supports.splittable.combineinputformat=true; 只有這個參數(shù)打開,下面的3個參數(shù)才能生效 
  2. set mapred.max.split.size=16000000; 每個map負載; 
  3. set mapred.min.split.size.per.node=100000000; 每個節(jié)點map的最小負載,這個值必須小于set mapred.max.split.size的值; 
  4. set mapred.min.split.size.per.rack=100000000; 每個機架map的最小負載; 
  5. set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; 

 

責任編輯:姜華 來源: 數(shù)據(jù)python與算法
相關推薦

2021-01-25 20:20:35

數(shù)據(jù)分析SparkHadoop

2018-03-20 13:32:22

數(shù)據(jù)分析IT企業(yè)數(shù)據(jù)存儲

2015-08-14 14:29:00

數(shù)據(jù)分析

2015-09-08 09:24:26

大數(shù)據(jù)分析采購

2016-11-08 09:16:54

數(shù)據(jù)倉庫優(yōu)化

2012-06-15 10:13:03

2022-05-06 12:01:01

優(yōu)化小程序

2021-03-15 10:43:20

大數(shù)據(jù)數(shù)據(jù)分析工具

2011-06-21 16:58:09

外鏈

2019-05-06 16:28:05

數(shù)據(jù)分析python

2020-06-11 07:00:00

數(shù)據(jù)分析BI平臺

2021-04-25 21:11:48

數(shù)據(jù)工具技術

2020-05-15 15:18:25

matlab數(shù)據(jù)分析

2017-01-11 08:51:26

數(shù)據(jù)分析職業(yè)規(guī)劃

2020-04-22 13:27:20

數(shù)據(jù)分析模塊解決

2015-07-08 15:07:23

大數(shù)據(jù)分析多少種工具

2015-08-21 13:54:38

大數(shù)據(jù)

2020-11-26 14:02:43

數(shù)據(jù)分析工具

2015-08-21 14:34:46

Excel

2015-08-14 10:28:09

大數(shù)據(jù)
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品免费大片 | 美日韩免费 | 刘亦菲国产毛片bd | 久久精品在线播放 | 网站黄色av | 在线一区观看 | 2019精品手机国产品在线 | 一级一片在线观看 | 亚洲天堂精品久久 | 91免费版在线 | a a毛片| 做a视频在线观看 | 精品国产欧美一区二区三区成人 | 久久久免费少妇高潮毛片 | 亚洲精品自拍视频 | 亚洲成a| 国产精品九九九 | 国产激情福利 | 91毛片在线看 | 日韩毛片免费看 | 欧美二区在线 | 亚洲精彩视频在线观看 | 欧美日韩视频一区二区 | 欧美成人一区二区 | yiren22 亚洲综合 | 国产一区二区高清在线 | 欧美一区二区在线看 | 亚洲一区中文字幕 | 国产毛片av| 日韩在线小视频 | 中国美女av| 亚洲精品一区二区三区中文字幕 | 天天爽夜夜爽精品视频婷婷 | 午夜免费视频 | 成人在线视频观看 | 男人的天堂avav | 爱爱视频在线观看 | 男人的天堂中文字幕 | 欧美在线观看一区二区 | 亚洲视频在线观看一区二区三区 | 国产日韩欧美一区 |