一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|數(shù)據(jù)庫技術(shù)|

服務(wù)器之家 - 數(shù)據(jù)庫 - 數(shù)據(jù)庫技術(shù) - 一篇學(xué)會(huì) Hive SQL 參數(shù)與性能調(diào)優(yōu)

一篇學(xué)會(huì) Hive SQL 參數(shù)與性能調(diào)優(yōu)

2022-03-03 22:57五分鐘學(xué)大數(shù)據(jù)園陌 數(shù)據(jù)庫技術(shù)

Hive作為大數(shù)據(jù)平臺(tái)舉足輕重的框架,以其穩(wěn)定性和簡單易用性也成為當(dāng)前構(gòu)建企業(yè)級數(shù)據(jù)倉庫時(shí)使用最多的框架之一。

如果我們只局限于會(huì)使用Hive,而不考慮性能問題,就難搭建出一個(gè)完美的數(shù)倉,所以Hive性能調(diào)優(yōu)是我們大數(shù)據(jù)從業(yè)者必須掌握的技能。本文將給大家講解Hive參數(shù)與性能調(diào)優(yōu)的一些方法及技巧。

一、Limit 限制調(diào)整

一般情況下,limit語句還是需要執(zhí)行整個(gè)查詢語句,然后再返回部分結(jié)果。

有一個(gè)配置屬性可以開啟,避免這種情況:對數(shù)據(jù)源進(jìn)行抽樣。

hive.limit.optimize.enable=true -- 開啟對數(shù)據(jù)源進(jìn)行采樣的功能

hive.limit.row.max.size -- 設(shè)置最小的采樣容量

hive.limit.optimize.limit.file -- 設(shè)置最大的采樣樣本數(shù)

缺點(diǎn):有可能部分?jǐn)?shù)據(jù)永遠(yuǎn)不會(huì)被處理到

二、JOIN優(yōu)化

1. 使用相同的連接鍵

當(dāng)對3個(gè)或者更多個(gè)表進(jìn)行join連接時(shí),如果每個(gè)on子句都使用相同的連接鍵的話,那么只會(huì)產(chǎn)生一個(gè)MapReduce job。

2. 盡量盡早地過濾數(shù)據(jù)

減少每個(gè)階段的數(shù)據(jù)量,對于分區(qū)表要加分區(qū),同時(shí)只選擇需要使用到的字段。

3. 盡量原子化操作

盡量避免一個(gè)SQL包含復(fù)雜邏輯,可以使用中間表來完成復(fù)雜的邏輯。

三、小文件優(yōu)化

1.小文件過多產(chǎn)生的影響

  • 首先對底層存儲(chǔ)HDFS來說,HDFS本身就不適合存儲(chǔ)大量小文件,小文件過多會(huì)導(dǎo)致namenode元數(shù)據(jù)特別大, 占用太多內(nèi)存,嚴(yán)重影響HDFS的性能
  • 對 Hive 來說,在進(jìn)行查詢時(shí),每個(gè)小文件都會(huì)當(dāng)成一個(gè)塊,啟動(dòng)一個(gè)Map任務(wù)來完成,而一個(gè)Map任務(wù)啟動(dòng)和初始化的時(shí)間遠(yuǎn)遠(yuǎn)大于邏輯處理的時(shí)間,就會(huì)造成很大的資源浪費(fèi)。而且,同時(shí)可執(zhí)行的Map數(shù)量是受限的

2.怎么解決小文件過多

1)使用 hive 自帶的 concatenate 命令,自動(dòng)合并小文件

使用方法:

#對于非分區(qū)表 alter table A concatenate; #對于分區(qū)表 alter table B partition(day=20201224) concatenate; 

注意:

  • concatenate 命令只支持 RCFILE 和 ORC 文件類型。
  • 使用concatenate命令合并小文件時(shí)不能指定合并后的文件數(shù)量,但可以多次執(zhí)行該命令。
  • 當(dāng)多次使用concatenate后文件數(shù)量不在變化,這個(gè)跟參數(shù)mapreduce.input.fileinputformat.split.minsize=256mb 的設(shè)置有關(guān),可設(shè)定每個(gè)文件的最小size。

2)調(diào)整參數(shù)減少M(fèi)ap數(shù)量

設(shè)置map輸入合并小文件的相關(guān)參數(shù):

#執(zhí)行Map前進(jìn)行小文件合并
#CombineHiveInputFormat底層是 Hadoop的 CombineFileInputFormat 方法
#此方法是在mapper中將多個(gè)文件合成一個(gè)split作為輸入 set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; -- 默認(rèn) #每個(gè)Map最大輸入大小(這個(gè)值決定了合并后文件的數(shù)量) set mapred.max.split.size=256000000; -- 256M #一個(gè)節(jié)點(diǎn)上split的至少的大小(這個(gè)值決定了多個(gè)DataNode上的文件是否需要合并) set mapred.min.split.size.per.node=100000000; -- 100M #一個(gè)交換機(jī)下split的至少的大小(這個(gè)值決定了多個(gè)交換機(jī)上的文件是否需要合并) set mapred.min.split.size.per.rack=100000000; -- 100M 

設(shè)置map輸出和reduce輸出進(jìn)行合并的相關(guān)參數(shù):

#設(shè)置map端輸出進(jìn)行合并,默認(rèn)為true set hive.merge.mapfiles = true; #設(shè)置reduce端輸出進(jìn)行合并,默認(rèn)為false set hive.merge.mapredfiles = true; #設(shè)置合并文件的大小 set hive.merge.size.per.task = 256*1000*1000; -- 256M #當(dāng)輸出文件的平均大小小于該值時(shí),啟動(dòng)一個(gè)獨(dú)立的MapReduce任務(wù)進(jìn)行文件merge set hive.merge.smallfiles.avgsize=16000000; -- 16M  

啟用壓縮:

# hive的查詢結(jié)果輸出是否進(jìn)行壓縮 set hive.exec.compress.output=true; # MapReduce Job的結(jié)果輸出是否使用壓縮 set mapreduce.output.fileoutputformat.compress=true; 

3)減少Reduce的數(shù)量

#reduce 的個(gè)數(shù)決定了輸出的文件的個(gè)數(shù),所以可以調(diào)整reduce的個(gè)數(shù)控制hive表的文件數(shù)量,
#hive中的分區(qū)函數(shù) distribute by 正好是控制MR中partition分區(qū)的,
#然后通過設(shè)置reduce的數(shù)量,結(jié)合分區(qū)函數(shù)讓數(shù)據(jù)均衡的進(jìn)入每個(gè)reduce即可。

#設(shè)置reduce的數(shù)量有兩種方式,第一種是直接設(shè)置reduce個(gè)數(shù) set mapreduce.job.reduces=10; #第二種是設(shè)置每個(gè)reduce的大小,Hive會(huì)根據(jù)數(shù)據(jù)總大小猜測確定一個(gè)reduce個(gè)數(shù) set hive.exec.reducers.bytes.per.reducer=5120000000; -- 默認(rèn)是1G,設(shè)置為5G #執(zhí)行以下語句,將數(shù)據(jù)均衡的分配到reduce中 set mapreduce.job.reduces=10; insert overwrite table A partition(dt) select * from B
distribute by rand(); 解釋:如設(shè)置reduce數(shù)量為10,則使用 rand(), 隨機(jī)生成一個(gè)數(shù) x % 10 ,
這樣數(shù)據(jù)就會(huì)隨機(jī)進(jìn)入 reduce 中,防止出現(xiàn)有的文件過大或過小

4)使用hadoop的archive將小文件歸檔

Hadoop Archive簡稱HAR,是一個(gè)高效地將小文件放入HDFS塊中的文件存檔工具,它能夠?qū)⒍鄠€(gè)小文件打包成一個(gè)HAR文件,這樣在減少namenode內(nèi)存使用的同時(shí),仍然允許對文件進(jìn)行透明的訪問。

#用來控制歸檔是否可用 set hive.archive.enabled=true; #通知Hive在創(chuàng)建歸檔時(shí)是否可以設(shè)置父目錄 set hive.archive.har.parentdir.settable=true; #控制需要?dú)w檔文件的大小 set har.partfile.size=1099511627776; #使用以下命令進(jìn)行歸檔 ALTER TABLE A ARCHIVE PARTITION(dt='2022-02-24', hr='12'); #對已歸檔的分區(qū)恢復(fù)為原文件 ALTER TABLE A UNARCHIVE PARTITION(dt='2022-02-24', hr='12'); 

注意:

歸檔的分區(qū)可以查看不能 insert overwrite,必須先unarchive

四、本地模式

有時(shí)hive的輸入數(shù)據(jù)量是非常小的。在這種情況下,為查詢出發(fā)執(zhí)行任務(wù)的時(shí)間消耗可能會(huì)比實(shí)際job的執(zhí)行時(shí)間要多的多。對于大多數(shù)這種情況,hive可以通過本地模式在單臺(tái)機(jī)器上處理所有的任務(wù)。對于小數(shù)據(jù)集,執(zhí)行時(shí)間會(huì)明顯被縮短。

set hive.exec.mode.local.auto=true; 

當(dāng)一個(gè)job滿足如下條件才能真正使用本地模式:

  • job的輸入數(shù)據(jù)大小必須小于參數(shù):hive.exec.mode.local.auto.inputbytes.max (默認(rèn)128MB)
  • job的map數(shù)必須小于參數(shù):hive.exec.mode.local.auto.tasks.max (默認(rèn)4)
  • job的reduce數(shù)必須為0或者1

可用參數(shù) hive.mapred.local.mem (默認(rèn)0)控制child jvm使用的最大內(nèi)存數(shù)。

五、strict模式

開啟嚴(yán)格模式對分區(qū)表進(jìn)行查詢,在where子句中沒有加分區(qū)過濾的話,將禁止提交任務(wù)(默認(rèn):nonstrict)

set hive.mapred.mode=strict 開啟嚴(yán)格模式

注:使用嚴(yán)格模式可以禁止以下三種類型的查詢:

1. 對分區(qū)表的查詢必須使用到分區(qū)相關(guān)的字段

分區(qū)表的數(shù)據(jù)量通常都比較大,對分區(qū)表的查詢必須使用到分區(qū)相關(guān)的字段,不允許掃描所有分區(qū),想想也是如果掃描所有分區(qū)的話那么對表進(jìn)行分區(qū)還有什么意義呢。

當(dāng)然某些特殊情況可能還是需要掃描所有分區(qū),這個(gè)時(shí)候就需要記得確保嚴(yán)格模式被關(guān)閉。

2. order by必須帶limit

因?yàn)橐WC全局有序需要將所有的數(shù)據(jù)拉到一個(gè)Reducer上,當(dāng)數(shù)據(jù)集比較大時(shí)速度會(huì)很慢。個(gè)人猜測可能是設(shè)置了limit N之后就會(huì)有一個(gè)很簡單的優(yōu)化算法:每個(gè)Reducer排序取N然后再合并排序取N即可,可大大減少數(shù)據(jù)傳輸量。

3. 禁止笛卡爾積查詢(join必須有on連接條件)

Hive不會(huì)對where中的連接條件優(yōu)化為on,所以join必須帶有on連接條件,不允許兩個(gè)表直接相乘。

六、并行執(zhí)行優(yōu)化

Hive會(huì)將一個(gè)查詢轉(zhuǎn)化成一個(gè)或者多個(gè)階段。這樣的階段可以是MapReduce階段、抽樣階段、合并階段、limit階段。或者Hive執(zhí)行過程中可能需要的其他階段。默認(rèn)情況下,Hive一次只會(huì)執(zhí)行一個(gè)階段。不過,某個(gè)特定的job可能包含眾多的階段,而這些階段可能并非完全互相依賴的,也就是說有些階段是可以并行執(zhí)行的,這樣可能使得整個(gè)job的執(zhí)行時(shí)間縮短。如果有更多的階段可以并行執(zhí)行,那么job可能就越快完成。

通過設(shè)置參數(shù)hive.exec.parallel值為true,就可以開啟并發(fā)執(zhí)行。在共享集群中,需要注意下,如果job中并行階段增多,那么集群利用率就會(huì)增加。

set hive.exec.parallel=true; //打開任務(wù)并行執(zhí)行 set hive.exec.parallel.thread.number=16; //同一個(gè)sql允許最大并行度,默認(rèn)為8。

當(dāng)然得是在系統(tǒng)資源比較空閑的時(shí)候才有優(yōu)勢,否則沒資源,并行也起不來。

七、JVM優(yōu)化

JVM重用是Hadoop調(diào)優(yōu)參數(shù)的內(nèi)容,其對Hive的性能具有非常大的影響,特別是對于很難避免小文件的場景或task特別多的場景,這類場景大多數(shù)執(zhí)行時(shí)間都很短。

Hadoop的默認(rèn)配置通常是使用派生JVM來執(zhí)行map和Reduce任務(wù)的。這時(shí)JVM的啟動(dòng)過程可能會(huì)造成相當(dāng)大的開銷,尤其是執(zhí)行的job包含有成百上千task任務(wù)的情況。JVM重用可以使得JVM實(shí)例在同一個(gè)job中重新使用N次。N的值可以在Hadoop的mapred-site.xml文件中進(jìn)行配置。通常在10-20之間,具體多少需要根據(jù)具體業(yè)務(wù)場景測試得出。

<property> <name>mapreduce.job.jvm.numtasksname> <value>10value> <description>How many tasks to run per jvm. If set to -1, there is no limit. description> property> 

我們也可以在Hive中設(shè)置:

set mapred.job.reuse.jvm.num.tasks=10 設(shè)置jvm重用

這個(gè)功能的缺點(diǎn)是,開啟JVM重用將一直占用使用到的task插槽,以便進(jìn)行重用,直到任務(wù)完成后才能釋放。如果某個(gè)“不平衡的”job中有某幾個(gè)reduce task執(zhí)行的時(shí)間要比其他Reduce task消耗的時(shí)間多的多的話,那么保留的插槽就會(huì)一直空閑著卻無法被其他的job使用,直到所有的task都結(jié)束了才會(huì)釋放。

八、推測執(zhí)行優(yōu)化

在分布式集群環(huán)境下,因?yàn)槌绦騜ug(包括Hadoop本身的bug),負(fù)載不均衡或者資源分布不均等原因,會(huì)造成同一個(gè)作業(yè)的多個(gè)任務(wù)之間運(yùn)行速度不一致,有些任務(wù)的運(yùn)行速度可能明顯慢于其他任務(wù)(比如一個(gè)作業(yè)的某個(gè)任務(wù)進(jìn)度只有50%,而其他所有任務(wù)已經(jīng)運(yùn)行完畢),則這些任務(wù)會(huì)拖慢作業(yè)的整體執(zhí)行進(jìn)度。為了避免這種情況發(fā)生,Hadoop采用了推測執(zhí)行(Speculative Execution)機(jī)制,它根據(jù)一定的法則推測出“拖后腿”的任務(wù),并為這樣的任務(wù)啟動(dòng)一個(gè)備份任務(wù),讓該任務(wù)與原始任務(wù)同時(shí)處理同一份數(shù)據(jù),并最終選用最先成功運(yùn)行完成任務(wù)的計(jì)算結(jié)果作為最終結(jié)果。

設(shè)置開啟推測執(zhí)行參數(shù):Hadoop的mapred-site.xml文件中進(jìn)行配置:

<property> <name>mapreduce.map.speculativename> <value>truevalue> <description>If true, then multiple instances of some map tasks 
               may be executed in parallel.description> property> <property> <name>mapreduce.reduce.speculativename> <value>truevalue> <description>If true, then multiple instances of some reduce tasks 
               may be executed in parallel.description> property> 

Hive本身也提供了配置項(xiàng)來控制reduce-side的推測執(zhí)行:

set hive.mapred.reduce.tasks.speculative.execution=true 

關(guān)于調(diào)優(yōu)這些推測執(zhí)行變量,還很難給一個(gè)具體的建議。如果用戶因?yàn)檩斎霐?shù)據(jù)量很大而需要執(zhí)行長時(shí)間的map或者reduce task的話,那么啟動(dòng)推測執(zhí)行造成的浪費(fèi)是非常巨大的。

九、數(shù)據(jù)傾斜優(yōu)化

數(shù)據(jù)傾斜的原理都知道,就是某一個(gè)或幾個(gè)key占據(jù)了整個(gè)數(shù)據(jù)的90%,這樣整個(gè)任務(wù)的效率都會(huì)被這個(gè)key的處理拖慢,同時(shí)也可能會(huì)因?yàn)橄嗤膋ey會(huì)聚合到一起造成內(nèi)存溢出。

Hive的數(shù)據(jù)傾斜一般的處理方案:

常見的做法,通過參數(shù)調(diào)優(yōu):

set hive.map.aggr=true; set hive.groupby.skewindata = ture; 

當(dāng)選項(xiàng)設(shè)定為true時(shí),生成的查詢計(jì)劃有兩個(gè)MapReduce任務(wù)。

在第一個(gè)MapReduce中,map的輸出結(jié)果集合會(huì)隨機(jī)分布到reduce中,每個(gè)reduce做部分聚合操作,并輸出結(jié)果。

這樣處理的結(jié)果是,相同的Group By Key有可能分發(fā)到不同的reduce中,從而達(dá)到負(fù)載均衡的目的

第二個(gè)MapReduce任務(wù)再根據(jù)預(yù)處理的數(shù)據(jù)結(jié)果按照Group By Key分布到reduce中(這個(gè)過程可以保證相同的Group By Key分布到同一個(gè)reduce中),最后完成最終的聚合操作。

但是這個(gè)處理方案對于我們來說是個(gè)黑盒,無法把控。

那么在日常需求的情況下如何處理這種數(shù)據(jù)傾斜的情況呢;

  • sample采樣,獲取哪些集中的key;
  • 將集中的key按照一定規(guī)則添加隨機(jī)數(shù);
  • 進(jìn)行join,由于打散了,所以數(shù)據(jù)傾斜避免了;
  • 在處理結(jié)果中對之前的添加的隨機(jī)數(shù)進(jìn)行切分,變成原始的數(shù)據(jù)。

十、動(dòng)態(tài)分區(qū)調(diào)整

動(dòng)態(tài)分區(qū)屬性:設(shè)置為true表示開啟動(dòng)態(tài)分區(qū)功能(默認(rèn)為false)

hive.exec.dynamic.partition=true; 

動(dòng)態(tài)分區(qū)屬性:設(shè)置為nonstrict,表示允許所有分區(qū)都是動(dòng)態(tài)的(默認(rèn)為strict) 設(shè)置為strict,表示必須保證至少有一個(gè)分區(qū)是靜態(tài)的

hive.exec.dynamic.partition.mode=strict; 

動(dòng)態(tài)分區(qū)屬性:每個(gè)mapper或reducer可以創(chuàng)建的最大動(dòng)態(tài)分區(qū)個(gè)數(shù)

hive.exec.max.dynamic.partitions.pernode=100; 

動(dòng)態(tài)分區(qū)屬性:一個(gè)動(dòng)態(tài)分區(qū)創(chuàng)建語句可以創(chuàng)建的最大動(dòng)態(tài)分區(qū)個(gè)數(shù)

hive.exec.max.dynamic.partitions=1000; 

動(dòng)態(tài)分區(qū)屬性:全局可以創(chuàng)建的最大文件個(gè)數(shù)

hive.exec.max.created.files=100000; 

十一、其他參數(shù)調(diào)優(yōu)

開啟CLI提示符前打印出當(dāng)前所在的數(shù)據(jù)庫名

set hive.cli.print.current.db=true; 

讓CLI打印出字段名稱

hive.cli.print.header=true; 

設(shè)置任務(wù)名稱,方便查找監(jiān)控

set mapred.job.name=P_DWA_D_IA_S_USER_PROD; 

決定是否可以在 Map 端進(jìn)行聚合操作

set hive.map.aggr=true; 

有數(shù)據(jù)傾斜的時(shí)候進(jìn)行負(fù)載均衡

set hive.groupby.skewindata=true; 

對于簡單的不需要聚合的類似SELECT col from table LIMIT n語句,不需要起MapReduce job,直接通過Fetch task獲取數(shù)據(jù)

set hive.fetch.task.conversion=more; 

最后

代碼優(yōu)化原則:

理透需求原則,這是優(yōu)化的根本;

把握數(shù)據(jù)全鏈路原則,這是優(yōu)化的脈絡(luò);

堅(jiān)持代碼的簡潔原則,這讓優(yōu)化更加簡單;

沒有瓶頸時(shí)談?wù)搩?yōu)化,這是自尋煩惱。

原文地址:https://mp.weixin.qq.com/s/F2WKvFxQBGlp-6nBuIU6lw

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: jizz 日本亚洲 | 亚洲精品老司机福利在线播放 | 草草影院免费 | 免费观看美景之屋 | 狠狠搞视频| 日日网| 国产东北3p真实在线456视频 | 久久99re热在线观看视频 | 顶级欧美做受xxx000大乳 | 欧美精品99 | 欧美18-19sex性处视频 | 热伊人99re久久精品最新地 | 水多多凹凸福利视频导航 | www.毛片在线观看 | 国产精品66福利在线观看 | 欧美激情影音先锋 | 精彩国产萝视频在线 | 精品久久成人 | h动态图男女啪啪27报 | chaopeng在线观看 | 国产高清一区二区三区免费视频 | 日本xxxⅹ69xxxx护士 | 日本在线观看视频 | 国产视频二 | 3d动漫美女被吸乳羞羞有 | 亚洲 欧美 另类 中文 在线 | 欧美亚洲国产另类在线观看 | 97福利社| 欧美日韩高清完整版在线观看免费 | sxx免费看视频在线播放 | 办公室恋情在线 | 视频高清在线观看 | 亚洲国产天堂久久精品网 | 王王的视频ivk | 四虎影视e456fcom四虎影视 | 日本在线观看www鲁啊鲁视频 | 美女脱了内裤让男桶爽 | 国产精品亚洲午夜一区二区三区 | 天美传媒在线视频 | 欧美在线观看网址 | 国产精品久久久久久影视 |