- Fetch抓取(Hive可以避免進(jìn)行MapReduce)
Hive中對(duì)某些情況的查詢(xún)可以不必使用MapReduce計(jì)算耸序。(計(jì)算需要時(shí)間)
例如:SELECT * FROM user; Hive可以簡(jiǎn)單地讀取user對(duì)應(yīng)的存儲(chǔ)目錄下的文件,然后輸出查詢(xún)結(jié)果到控制臺(tái)。
在hive-default.xml.template文件中hive.fetch.task.conversion默認(rèn)是more,老版本hive默認(rèn)是minimal君丁,該屬性修改為more以后,在全局查找将宪、字段查找绘闷、limit查找等
都不走M(jìn)apReduce。
<property>
<name>hive.fetch.task.conversion</name>
<value>more</value>
<description>
Expects one of [none, minimal, more].
Some select queries can be converted to single FETCH task minimizing latency.
Currently the query should be single sourced not having any subquery and should not have
any aggregations or distincts (which incurs RS), lateral views and joins.
0. none : disable hive.fetch.task.conversion
1. minimal : SELECT STAR, FILTER on partition columns, LIMIT only 所有的都要走M(jìn)R
2. more : SELECT, FILTER, LIMIT only (support TABLESAMPLE and virtual columns)
</description>
</property>
- 本地模式
當(dāng)Hive的輸入數(shù)據(jù)量非常小的情況下涧偷,為查詢(xún)觸發(fā)執(zhí)行任務(wù)時(shí)消耗的時(shí)間可能會(huì)比實(shí)際job的執(zhí)行時(shí)間要多的多簸喂。對(duì)于大多數(shù)這種情況,Hive可以通過(guò)本地模式在單臺(tái)機(jī)器上處理所有的任務(wù)燎潮。對(duì)于小數(shù)據(jù)集喻鳄,執(zhí)行時(shí)間可以明顯縮短。
可以設(shè)置hive.exec.mode.local.auto
的值為true确封,來(lái)讓Hive在適當(dāng)?shù)臅r(shí)候自動(dòng)啟動(dòng)這個(gè)優(yōu)化除呵。
set hive.exec.mode.local.auto=true; //開(kāi)啟本地MR
//設(shè)置local MR的最大輸入數(shù)據(jù)量,當(dāng)輸入數(shù)據(jù)量小于這個(gè)值時(shí)采用local MR的方式爪喘,默認(rèn)為134217728颜曾,即128M
set hive.exec.mode.local.auto.inputbytes.max=51234560;
//設(shè)置local MR的最大輸入文件個(gè)數(shù),當(dāng)輸入文件個(gè)數(shù)小于這個(gè)值時(shí)采用local MR的方式秉剑,默認(rèn)為4
set hive.exec.mode.local.auto.input.files.max=10;
- 并行執(zhí)行
Hive會(huì)將一個(gè)查詢(xún)轉(zhuǎn)化成一個(gè)或多個(gè)階段泛豪。可能是MapReduce階段侦鹏、抽樣階段诡曙、合并階段、limit階段略水〖勐保或者Hive執(zhí)行過(guò)程中可能需要的其他階段。默認(rèn)情況下渊涝,Hive一次只會(huì)執(zhí)行一個(gè)階段慎璧。不過(guò)有的job可能包含眾多的階段,而這些階段可能并非完全互相依賴(lài)的跨释,也就是說(shuō)有些階段是可以并行執(zhí)行的胸私,這樣可能使得整個(gè)job的執(zhí)行時(shí)間縮短。
可以設(shè)置參數(shù)hive.exec.parallel值為true開(kāi)啟并發(fā)執(zhí)行鳖谈。不過(guò)岁疼,在共享集群中,如果job中并行階段增多蚯姆,那么集群利用率就會(huì)增加五续。在系統(tǒng)資源比較空閑的時(shí)候才有優(yōu)勢(shì),否則龄恋,沒(méi)資源疙驾,并行也起不來(lái)。
set hive.exec.parallel=true; //打開(kāi)任務(wù)并行執(zhí)行
set hive.exec.parallel.thread.number=16; //同一個(gè)sql允許最大并行度郭毕,默認(rèn)為8它碎。
- 嚴(yán)格模式
Hive提供了嚴(yán)格模式,可以防止用戶(hù)執(zhí)行那些可能意向不到的不好的影響的查詢(xún)显押。
通過(guò)設(shè)置屬性hive.mapred.mode的值扳肛,默認(rèn)是非嚴(yán)格模式nonstrict 。開(kāi)啟嚴(yán)格模式需要修改hive.mapred.mode值為strict乘碑,開(kāi)啟嚴(yán)格模式可以禁止3種類(lèi)型的查詢(xún)挖息。
<property>
<name>hive.mapred.mode</name>
<value>strict</value>
</property>
- 分區(qū)表上沒(méi)有指定了分區(qū)(分區(qū)表數(shù)量很大)
- 沒(méi)有l(wèi)imit限制的order by語(yǔ)句
- 笛卡爾積:JOIN時(shí)沒(méi)有ON語(yǔ)句
- 動(dòng)態(tài)分區(qū)
以第一個(gè)表的分區(qū)規(guī)則,來(lái)對(duì)應(yīng)第二個(gè)表的分區(qū)規(guī)則兽肤,將第一個(gè)表的所有分區(qū)角骤,全部拷貝到第二個(gè)表中來(lái)啥纸,第二個(gè)表在加載數(shù)據(jù)的時(shí)候,不需要指定分區(qū)了,直接用第一個(gè)表的分區(qū)即可弊仪。
(1)開(kāi)啟動(dòng)態(tài)分區(qū)功能(默認(rèn)true,開(kāi)啟)
set hive.exec.dynamic.partition=true;
(2)設(shè)置為非嚴(yán)格模式(動(dòng)態(tài)分區(qū)的模式齿椅,默認(rèn)strict戈轿,表示必須指定至少一個(gè)分區(qū)為靜態(tài)分區(qū),nonstrict模式表示允許所有的分區(qū)字段都可以使用動(dòng)態(tài)分區(qū)店雅。)
set hive.exec.dynamic.partition.mode=nonstrict;
(3)在所有執(zhí)行MR的節(jié)點(diǎn)上政基,最大一共可以創(chuàng)建多少個(gè)動(dòng)態(tài)分區(qū)。
set hive.exec.max.dynamic.partitions=1000;
(4)在每個(gè)執(zhí)行MR的節(jié)點(diǎn)上底洗,最大可以創(chuàng)建多少個(gè)動(dòng)態(tài)分區(qū)腋么。該參數(shù)需要根據(jù)實(shí)際的數(shù)據(jù)來(lái)設(shè)定。比如:源數(shù)據(jù)中包含了一年的數(shù)據(jù)亥揖,即day字段有365個(gè)值珊擂,那么該參數(shù)就需要設(shè)置成大于365,如果使用默認(rèn)值100费变,則會(huì)報(bào)錯(cuò)摧扇。
set hive.exec.max.dynamic.partitions.pernode=100
(5)整個(gè)MR Job中,最大可以創(chuàng)建多少個(gè)HDFS文件挚歧。
在linux系統(tǒng)當(dāng)中扛稽,每個(gè)linux用戶(hù)最多可以開(kāi)啟1024個(gè)進(jìn)程,每一個(gè)進(jìn)程最多可以打開(kāi)2048個(gè)文件滑负,即持有2048個(gè)文件句柄在张,下面這個(gè)值越大用含,就可以打開(kāi)文件句柄越大
set hive.exec.max.created.files=100000;
(6)當(dāng)有空分區(qū)生成時(shí),是否拋出異常帮匾。一般不需要設(shè)置啄骇。
set hive.error.on.empty.partition=false;
- 推測(cè)執(zhí)行
它根據(jù)一定的法則推測(cè)出“拖后腿”的任務(wù),并為這樣的任務(wù)啟動(dòng)一個(gè)備份任務(wù)瘟斜,讓該任務(wù)與原始任務(wù)同時(shí)處理同一份數(shù)據(jù)缸夹,并最終選用最先成功運(yùn)行完成任務(wù)的計(jì)算結(jié)果作為最終結(jié)果。
設(shè)置開(kāi)啟推測(cè)執(zhí)行參數(shù):Hadoop的mapred-site.xml文件中進(jìn)行配置
<property>
<name>mapreduce.map.speculative</name>
<value>true</value>
</property>
<property>
<name>mapreduce.reduce.speculative</name>
<value>true</value>
</property>
hive本身也提供了配置項(xiàng)來(lái)控制reduce-side的推測(cè)執(zhí)行
<property>
<name>hive.mapred.reduce.tasks.speculative.execution</name>
<value>true</value>
</property>
- 分組(Group By)
默認(rèn)情況下螺句,Map階段同一Key數(shù)據(jù)分發(fā)給一個(gè)reduce虽惭,當(dāng)一個(gè)key數(shù)據(jù)過(guò)大時(shí)就傾斜了。
并不是所有的聚合操作都需要在Reduce端完成蛇尚,很多聚合操作都可以先在Map端進(jìn)行部分聚合芽唇,最后在Reduce端得出最終結(jié)果。
(1)是否在Map端進(jìn)行聚合佣蓉,默認(rèn)為T(mén)rue
set hive.map.aggr = true;
(2)在Map端進(jìn)行聚合操作的條目數(shù)目
set hive.groupby.mapaggr.checkinterval = 100000;
(3)有數(shù)據(jù)傾斜的時(shí)候進(jìn)行負(fù)載均衡(默認(rèn)是false)
set hive.groupby.skewindata = true;
當(dāng)設(shè)定為 true披摄,生成的查詢(xún)計(jì)劃會(huì)有兩個(gè)MR Job。第一個(gè)MR Job中勇凭,Map的輸出結(jié)果會(huì)隨機(jī)分布到Reduce中疚膊,每個(gè)Reduce做部分聚合操作,并輸出結(jié)果虾标,這樣處理的結(jié)果是相同的Group By Key有可能被分發(fā)到不同的Reduce中寓盗,從而達(dá)到負(fù)載均衡的目的;第二個(gè)MR Job再根據(jù)預(yù)處理的數(shù)據(jù)結(jié)果按照Group By Key分布到Reduce中(這個(gè)過(guò)程可以保證相同的Group By Key被分布到同一個(gè)Reduce中)璧函,最后完成最終的聚合操作傀蚌。
- 小文件進(jìn)行合并
在Map執(zhí)行前合并小文件,可以減少M(fèi)ap數(shù)蘸吓。
hive.merg.mapfiles=true:合并map輸出
hive.merge.mapredfiles=false:合并reduce輸出
hive.merge.size.per.task=256*1000*1000:合并文件的大小
hive.mergejob.maponly=true:如果支持CombineHiveInputFormat則生成只有Map的任務(wù)執(zhí)行merge
hive.merge.smallfiles.avgsize=16000000:文件的平均大小小于該值時(shí)善炫,會(huì)啟動(dòng)一個(gè)MR任務(wù)執(zhí)行merge。
- 適當(dāng)?shù)脑黾覯ap數(shù)
當(dāng)input的文件很大库继,任務(wù)邏輯復(fù)雜箩艺,Map執(zhí)行非常慢的時(shí)候,可以考慮增加Map數(shù)宪萄,來(lái)使得每個(gè)Map處理的數(shù)據(jù)量減少艺谆,從而提高任務(wù)的執(zhí)行效率“萦ⅲ控制map數(shù)量需要遵循兩個(gè)原則:使大數(shù)據(jù)量利用合適的map數(shù)静汤;使單個(gè)map任務(wù)處理合適的數(shù)據(jù)量;
set mapreduce.job.reduces =10;
- 調(diào)整reduce數(shù)
- 調(diào)整reduce個(gè)數(shù)方法一
(1)每個(gè)Reduce處理的數(shù)據(jù)量默認(rèn)是256MB
hive.exec.reducers.bytes.per.reducer=256123456
(2)每個(gè)任務(wù)最大的reduce數(shù),默認(rèn)為1009
hive.exec.reducers.max=1009
(3)計(jì)算reducer數(shù)的公式
N=min(參數(shù)2虫给,總輸入數(shù)據(jù)量/參數(shù)1)
- 調(diào)整reduce個(gè)數(shù)方法二
在hadoop的mapred-default.xml文件中修改
設(shè)置每個(gè)job的Reduce個(gè)數(shù)
set mapreduce.job.reduces = 15;
reduce個(gè)數(shù)并不是越多越好藤抡,啟動(dòng)和初始化reduce會(huì)消耗時(shí)間和資源;有多少個(gè)reduce抹估,就會(huì)有多少個(gè)輸出文件杰捂,如果生成了很多個(gè)小文件,那么如果這些小文件作為下一個(gè)任務(wù)的輸入棋蚌,則也會(huì)出現(xiàn)小文件過(guò)多的問(wèn)題;在設(shè)置reduce個(gè)數(shù)的時(shí)候也需要考慮這兩個(gè)原則:處理大數(shù)據(jù)量利用合適的reduce數(shù)挨队;使單個(gè)reduce任務(wù)處理數(shù)據(jù)量大小要合適谷暮;