日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HIVE查询优化

發(fā)布時間:2023/12/20 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HIVE查询优化 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

所有的調(diào)優(yōu)都離不開對CPU、內(nèi)存、IO這三樣資源的權(quán)衡及調(diào)整

Hive QL的執(zhí)行本質(zhì)上是MR任務(wù)的運行,因此優(yōu)化主要考慮到兩個方面:Mapreduce任務(wù)優(yōu)化、SQL語句優(yōu)化

一、Mapreduce任務(wù)優(yōu)化

1、設(shè)置合理的task數(shù)量(map task、reduce task)

這里有幾個考慮的點,一方面Hadoop MR task的啟動及初始化時間較長,如果task過多,可能會導致任務(wù)啟動和初始化時間遠超邏輯處理時間,這種情況白白浪費了計算資源。另一方面,如果任務(wù)復雜,task過少又會導致任務(wù)遲遲不能完成,這種情況又使計算資源沒有充分利用。

因為其讀取輸入使用Hadoop API,所以其map數(shù)量由以下參數(shù)共同決定:

minSize = Math.max(job.getLong(“mapred.min.split.size”, 1), minSplitSize);
mapred.min.split.size:設(shè)置每個map處理的最小數(shù)據(jù)量
minSplitSize:一般默認為都為1,可由子類復寫函數(shù)protected void setMinSplitSize(long minSplitSize) 重新設(shè)置。

blockSize:默認的HDFS文件塊大小

goalSize=totalSize/numSplits 期望的每個Map處理的split大小,僅僅是期望的
numSplits :是在 job 啟動時通過JobConf.setNumMapTasks(int n) 設(shè)置的值,是給框架的map數(shù)量的提示 totalSize :整個job所有輸入的總大小

splitSize的計算方式如下:
max( minSize, min(blockSize, goalSize) )

最終map數(shù)量由以下方式計算得出:
map數(shù)量=totalSize/splitSize

可以看出在調(diào)整map數(shù)量時,可通過調(diào)整blockSize和mapred.min.split.size的方式實現(xiàn),但是調(diào)整blockSize可能并不現(xiàn)實,所以程序執(zhí)行時通過設(shè)置mapred.min.split.size參數(shù)來設(shè)定。

當然,需要特別注意的是,如果文件特別大,需要支持分割才能進行分片,產(chǎn)生多個map,否則單個文件不可分割那就一個map。如果文件都特別小(比blockSize都小),可以使用CombineFileInputFormat將input path中的小文件合并成再送給mapper處理。

reduce task個數(shù)確定:
1)設(shè)置set mapred.reduce.tasks=?
2)若1)沒有設(shè)置,hive通過下面兩個參數(shù)來計算
set hive.exec.reducers.maxs=? (每個job最大的task數(shù)量)
set hive.exec.reducers.bytes.per.reducer = ? (每個reduce任務(wù)處理的數(shù)據(jù)量,默認為1G)

2、對小文件合并

過多的小文件對于執(zhí)行引擎起map reduce任務(wù)進行處理非常不利,一個是每個小文件起一個task去處理,非常浪費資源,另一個是過多的小文件也對NameNode造成很大壓力(每個小文件都要記錄一個元數(shù)據(jù) 150 byte)。所以,減少小文件的數(shù)量也是一個優(yōu)化措施。

盡可能避免產(chǎn)生:
1)在執(zhí)行hive查詢時合理設(shè)置reduce的數(shù)量
2)可以使用hadoop archive命令將多個小文件進行歸檔
3)動態(tài)分區(qū)插入數(shù)據(jù)可能會產(chǎn)生大量小文件,所以在使用時盡量避免動態(tài)分區(qū)
4)對map和reduce的輸出進行merge

set hive.merge.mapfiles = true //設(shè)置map端輸出進行合并,默認為true
set hive.merge.mapredfiles = true //設(shè)置reduce端輸出進行合并,默認為false
set hive.merge.size.per.task = 25610001000 //設(shè)置合并文件的大小
set hive.merge.smallfiles.avgsize=16000000 //當輸出文件的平均大小小于該值時,啟動一個獨立的MapReduce任務(wù)進行文件merge

若已產(chǎn)生小文件:
1)set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat 用于設(shè)置在執(zhí)行map前對小文件進行合并,以下參數(shù)設(shè)置決定了合并文件的大小,并最終減小map任務(wù)數(shù)

set mapred.max.split.size=256000000 //每個Map最大輸入大小(這個值決定了合并后文件的數(shù)量)
set mapred.min.split.size.per.node=100000000 //一個節(jié)點上split的最小大小(這個值決定了多個DataNode上的文件是否需要合并)
set mapred.min.split.size.per.rack=100000000 //一個機架下split的最小大小(這個值決定了多個機架上的文件是否需要合并)

3、避免數(shù)據(jù)傾斜

不管task數(shù)量是多少,發(fā)生數(shù)據(jù)傾斜就會大大影響查詢效率。

1)設(shè)置hive.map.aggr=true
該配置可將頂層的聚合操作放在map端進行,以減輕reduce端的壓力。

4、并行執(zhí)行

Hive會將查詢轉(zhuǎn)化成一個或者多個階段,這些階段可能包括:MR階段、抽樣階段、合并階段、limit階段等。默認單次執(zhí)行一個階段,可進行如下配置,使得兩個并不沖突的階段可以并行執(zhí)行,提高查詢效率。

set hive.exec.parallel=true // 可以開啟并行執(zhí)行
set hive.exec.parallel.thread.number=16 // 同一個sql允許最大并行度,默認為8

5、本地模式

這一情況適用于數(shù)據(jù)集小的情況,并且啟動和運行MR任務(wù)消耗的時間可能超過邏輯處理的時候,可配置hive在適當情況下自動進行此項優(yōu)化

條件如下:
輸入數(shù)據(jù)量大小必須小于 hive.exec.mode.local.auto.inputbytes.max(默認128MB)
map任務(wù)數(shù)量必須小于 hive.exec.mode.local.auto.tasks.max(默認4)

需開啟設(shè)置:
set hive.exec.mode.local.auto=true // 默認為false

6、JVM重用

hadoop也通過JVM來執(zhí)行map或者reduce任務(wù),當任務(wù)非常多時,啟動并初始化任務(wù)的耗時會大大增加,有時甚至比邏輯執(zhí)行時間都要長,所以可通過JVM重用使得JVM實例在同一個job時可以由多task重用,避免增加過多的啟動和初始化時間。可通過如下參數(shù)設(shè)置:
set mapred.job.reuse.jvm.num.tasks=10; // 10為重用個數(shù)

二、SQL語句優(yōu)化

SQL優(yōu)化有些原則是通用的,部分可參考前一篇總結(jié):

這里針對HIVE來進行一些說明:

1、列裁剪分區(qū)裁剪這些基本縮小查找范圍的自不必說。

2、join優(yōu)化

1)在查詢語句中如果小表在join的左邊,那么hive可能將小表放入分布式緩存,實現(xiàn)map-side join。我們不用考慮哪張表是小表而調(diào)整join順序,新版hive提供了 hive.auto.convert.join 可以來優(yōu)化,默認是啟動的。

hive.mapjoin.smalltable.filesize=25000000(默認值) // 小于該值的表在join時被hive認為是小表

2)在特定情況下,大表也可以使用map-side join,需要滿足以下條件

  • 表數(shù)據(jù)必須按照ON語句中的鍵進行分桶
  • 其中一張表的分桶數(shù)必須是另一張表的分桶數(shù)的倍數(shù)
    hive這種情況下在map階段可以進行分桶連接,這一功能需要通過如下設(shè)置進行開啟
    set hive.enforce.sortmergebucketmapjoin=true

如果分桶表數(shù)據(jù)是按照連接鍵或者桶的鍵進行排序的,hive可以進行一個更快的合并-連接(sort-merge join),需要如下配置
hive.input.format=org.apache.hadoop.hive.ql.io.BucketizedHiveInputFormat
hive.auto.convert.sortmerge.join=true
hive.enforce.sortmergebucketmapjoin=true

3、group by操作

可先進行map端部分聚合,然后在reduce端最終聚合,進行如下設(shè)置
set hive.map.aggr=true; // 開啟Map端聚合參數(shù)設(shè)置
set hive.grouby.mapaggr.checkinterval=100000; // 聚合的鍵對應的記錄條數(shù)超過這個值則會進行分拆

如下設(shè)置可在出現(xiàn)數(shù)據(jù)傾斜時分兩個MR作業(yè)來完成,而不是在一個job中完成
set hive.groupby.skewindata = true (默認為false) // 在第一步mapreduce中map的結(jié)果隨機分布于到reduce,于是這一步中每個reduce只做部分聚合,在下一個mapreduce中再進行最終聚合。

4、使用LEFT SEMI JOIN (左半連接)替代 IN/EXISTS 子查詢

hive中前者 LEFT SEMI JOIN 是后者 IN/EXISTS 更高效的實現(xiàn)
例如:
select a.id, a.name from a where a.id in (select b.id from b);
應該改為 select a.id, a.name from a left semi job b on a.id=b.id;

5、選擇合適的分區(qū)、分桶、排序方式

distribute by : 用來在map端按鍵對數(shù)據(jù)進行拆分,根據(jù)reduce的個數(shù)進行數(shù)據(jù)分發(fā),默認是采用hash算法
cluster by :除了有distribute by的功能外,還能對查詢結(jié)果進行排序,等于distribute by + sort by
sort by :數(shù)據(jù)在進入reducer之前就排好序,根據(jù)指定值對進入到同一reducer的所有行進行排序
order by :對所有數(shù)據(jù)進行排序(全局有序),若數(shù)據(jù)量很大,可能需要很多時間
注:嚴格模式( hive.mapred.mode=strict 默認為 nonstrict ) 用于 hive 在特定情況下阻止任務(wù)的提交,針對以下三種情況
(1)對于分區(qū)表,不加分區(qū)字段過濾條件,不能執(zhí)行
(2)對于order by語句,必須使用limit語句
(3)限制笛卡爾積的查詢(join的時候不使用on,而使用where的)

三、其它

1、存儲格式

優(yōu)先選擇列式存儲格式如orc、parquet,這將使hive查詢時避免全部掃描,列數(shù)據(jù)存儲在一起,只需拿相應列即可,能夠大大縮短響應時間

2、壓縮方式

在mapreduce的世界中,性能瓶頸主要來自于磁盤IO和網(wǎng)絡(luò)IO,CPU基本不構(gòu)成壓力,根據(jù)需要選擇合適的壓縮方式,如下圖可參考

3、vectorized query( 向量化查詢 Hive 0.13中引入 )

通過一次性批量執(zhí)行1024行而不是每次單行執(zhí)行,提供掃描、聚合、篩選器和連接等操作的性能。通過如下方式啟用:
set hive.vectorized.execution.enabled = true;
set hive.vectorized.execution.reduce.enabled = true;

4、CBO(cost based query optimization)基于成本的優(yōu)化

hive 0.14.0 加入,hive1.1.0 后默認開啟,hive底層自動優(yōu)化多個join的順序并選擇合適的join算法,優(yōu)化每個查詢的執(zhí)行邏輯和物理執(zhí)行計劃。使用時需進行如下設(shè)置
set hive.cbo.enable = true;
set hive.compute.query.using.stats = true;
set hive.stats.fetch.column.stats = true;
set hive.stats.fetch.partition.stats = true;

5、推測執(zhí)行

偵測執(zhí)行緩慢的任務(wù)(通常由于負載不均衡或者資源分布原因?qū)е?#xff09;,通過執(zhí)行其備份任務(wù)對相同數(shù)據(jù)進行重算,加速獲取單個task的結(jié)果,以此來提高整體的執(zhí)行效率,可由如下參數(shù)控制:
set mapred.map.tasks.speculative.execution=true
set mapred.reduce.tasks.speculative.execution=true

以上內(nèi)容,如有錯誤,請看到的小伙伴幫忙指正,多謝。

總結(jié)

以上是生活随笔為你收集整理的HIVE查询优化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。