中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

hive使用過程中有哪些調優策略

發布時間:2021-12-10 14:49:21 來源:億速云 閱讀:286 作者:小新 欄目:大數據

這篇文章主要介紹hive使用過程中有哪些調優策略,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

下面是hive使用過程中一些調優策略

一、fetch抓取

Fetch抓取是指,Hive中對某些情況的查詢可以不必使用MapReduce計算。例如:SELECT * FROM employees;在這種情況下,Hive可以簡單地讀取employee對應的存儲目錄下的文件,然后輸出查詢結果到控制臺。
  在hive-default.xml.template文件中hive.fetch.task.conversion默認是more,老版本hive默認是minimal,該屬性修改為more以后,在全局查找、字段查找、limit查找等都不走mapreduce。

<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     禁用fetch抓取
      1. minimal : SELECT STAR, FILTER on partition columns, LIMIT 
                   只有select分區字段,以及limit時才能使用fetch(不走MapReduce)
      2. more  : SELECT, FILTER, LIMIT only (support TABLESAMPLE and virtual columns)
                  字段查找,limit都不走MapReduce
    </description>
  </property>

也可以通過在hive命令行下臨時修改該參數的值:

hive (default)> set hive.fetch.task.conversion=more;

二、本地模式

有時Hive的輸入數據量是非常小的。在這種情況下,為查詢觸發執行任務消耗的時間可能會比實際job的執行時間要多的多。對于大多數這種情況,Hive可以通過本地模式在單臺機器上處理所有的任務。對于小數據集,執行時間可以明顯被縮短。即只啟動一個map和reduce任務,且在單臺主機上執行。相關參數設置如下:

//開啟本地mr,自動根據下面的配置決定是否使用本地模式
set hive.exec.mode.local.auto=true;  

//設置local mr的最大輸入數據量,當輸入數據量小于這個值時采用local  mr的方式,默認為134217728bytes,即128M
set hive.exec.mode.local.auto.inputbytes.max=50000000;

//設置local mr的最大輸入文件個數,當輸入文件個數小于這個值時采用local mr的方式,默認為4
set hive.exec.mode.local.auto.input.files.max=10;

三、表的優化

3.1 小表join大表

將key相對分散,并且數據量小的表放在join的左邊,這樣可以有效減少內存溢出錯誤發生的幾率,因為是將左邊的表先讀取的;再進一步,可以使用Group變小的維度表(1000條以下的記錄條數)先進內存。在map端完成reduce。
實際測試發現:新版的hive已經對小表JOIN大表和大表JOIN小表進行了優化。小表放在左邊和右邊已經沒有明顯區別。

3.2 大表join大表

這個實驗過程中可以打開hadoop的jobhistory server來查看job的執行情況,包括執行的時間等。

配置 mapred-site.xml
<property>
<name>mapreduce.jobhistory.address</name>
<value>bigdata111:10020</value>
</property>
<property>
    <name>mapreduce.jobhistory.webapp.address</name>
    <value>bigdata111:19888</value>
</property>

啟動歷史服務器:
mr-jobhistory-daemon.sh start historyserver

進入historyserver 的web頁面:
http://192.168.1.102:19888

hive使用過程中有哪些調優策略

圖 3.1 hive大表join結果圖

可以看到job結果有很多執行結果狀態參數,比如執行時間等。

3.2.1 空key過濾

有時join超時是因為某些key對應的數據太多,而相同key對應的數據都會發送到相同的reducer上,從而導致內存不夠。此時我們應該仔細分析這些異常的key,很多情況下,這些key對應的數據是異常數據,我們需要在SQL語句中進行過濾。比如說key是null,如果是異常數據的話,就應該過濾掉。例如:

 insert overwrite table jointable 
select n.* from (select * from nullidtable where id is not null ) n  left join ori o on n.id = o.id;
這里就事先對 nullidtable 表中 id 為null 的行過濾掉。
但是要注意,確定key是null的數據是無效數據時才過濾,如果是有效數據就不能采用這種方式了

3.2.2空key轉換

有時雖然某個key為空對應的數據很多,但是相應的數據不是異常數據,必須要包含在join的結果中,此時我們可以表a中key為空的字段賦一個隨機的值,使得數據隨機均勻地分不到不同的reducer上。例如:

insert overwrite table jointable
select n.* from nullidtable n full join ori o on 
case when n.id is null then concat('hive', rand()) else n.id end = o.id;

使用 case when xxx then value1 else id end  語句判斷id是否為空,為空則用隨機數替代,否則直接

3.3 開啟自動map join

如果不指定MapJoin或者不符合MapJoin的條件,那么Hive解析器會將Join操作轉換成Common Join,即:在Reduce階段完成join。容易發生數據傾斜。可以用MapJoin把小表全部加載到內存在map端進行join,避免reducer處理。
  我們可以指定當小表超過多少時采用reduce join,小于就采用map join

(1)設置自動選擇Mapjoin
set hive.auto.convert.join = true; 默認為true

(2)大表小表的閾值設置(默認25M一下認為是小表):
set hive.mapjoin.smalltable.filesize=25000000;

3.4 group by自動負載均衡

采取reduce聚合默認情況下,Map階段同一Key數據分發給一個reduce,當一個key數據過大時就傾斜了。并不是所有的聚合操作都需要在Reduce端完成,很多聚合操作都可以先在Map端進行部分聚合,最后在Reduce端得出最終結果。

(1)是否在Map端進行聚合,默認為True
    hive.map.aggr = true
(2)在Map端進行聚合操作的條目數目
    hive.groupby.mapaggr.checkinterval = 100000
(3)有數據傾斜的時候進行負載均衡(默認是false)
    hive.groupby.skewindata = true
當這一項設置為true時,生成的查詢計劃會有兩個MR Job。第一個MR Job中,Map的輸出結果會隨機分布到Reduce中,每個Reduce做部分聚合操作,并輸出結果,這樣處理的結果是相同的Group By Key有可能被分發到不同的Reduce中,從而達到負載均衡的目的;第二個MR Job再根據預處理的數據結果按照Group By Key分布到Reduce中(這個過程可以保證相同的Group By Key被分布到同一個Reduce中),最后完成最終的聚合操作。

3.5 去重統計先group by再count

普通情況選,我們統計去重后的數據行數時,是這樣的統計的:

select count(distinct id) from bigtable;

這種方式有一個巨大的缺陷,因為是整體去重的,所以MapReduce時,無法使用多個reducer任務,如果使用了,就變成局部去重,但整體不能保證去重。這樣的話一個reducer 的負載其實是很大的,可以采用下面的方式優化:

select count(id) from (select id from bigtable group by id) a;

先啟動MapReduce根據id進行group by,這個過程中其實已經去重了,而且group by中是可以用多個reducer任務,這樣的就可以減輕單個reducer 的壓力。接著再啟動另外一個MapReduce,用于count統計group by之后的數據的行數。所以這里是變成兩個MapReduce job執行的任務,所以要注意僅當數據量大時采用這種方式,否則多任務的調度反而占用更多資源,并且效率也不好。

3.6 join之前進行行列過濾

列過濾:盡量不使用select * 而是指定要查詢的字段
行過濾:在我們進行外部join時,如果某個表要過濾到某些行。要先在join之前進行過濾,不要兩表join之后再過濾,因為join之后數據量比原來增大了,過濾要更久。
join之后過濾:

select o.id from bigtable b
join ori o on o.id = b.id
where o.id <= 10;

所以where語句不要放在join之后,這是不好的,大數據量的時候耗時很長

join之前過濾:

select b.id from bigtable b
join (select id from ori where id <= 10 ) o on b.id = o.id;

這里就是先對ori表進行id列的過濾,過濾后的數據再和bigtable表join

3.7 開啟動態分區調整

如果hive表是一張分區表,一般情況下,我們進行insert插入時間時,需要明顯指定插入到哪個分區中。而如果開啟了動態分區,那么就會根據導入數據的分區字段,自動導入到指定分區,如果分區不存在,就自動創建。

(1)開啟動態分區功能(默認true,開啟)
hive.exec.dynamic.partition=true

(2)設置為非嚴格模式(動態分區的模式,默認strict,表示必須指定至少一個分區為靜態分區,nonstrict模式表示允許所有的分區字段都可以使用動態分區。)
hive.exec.dynamic.partition.mode=nonstrict

(3)在所有執行MR的節點上,最大一共可以創建多少個動態分區。
hive.exec.max.dynamic.partitions=1000

(4)在每個執行MR的節點上,最大可以創建多少個動態分區。該參數需要根據實際的數據來設定。比如:源數據中包含了一年的數據,即day字段有365個值,那么該參數就需要設置成大于365,如果使用默認值100,則會報錯。
hive.exec.max.dynamic.partitions.pernode=100

(5)整個MR Job中,最大可以創建多少個HDFS文件。
hive.exec.max.created.files=100000

(6)當有空分區生成時,是否拋出異常。一般不需要設置。
hive.error.on.empty.partition=false

例子:
需求:將ori中的數據按照時間(如:20111230000008),插入到目標表ori_partitioned_target的相應分區中

(1)創建分區表
create table ori_partitioned(id bigint, time bigint, uid string, keyword string, url_rank int, click_num int, click_url string) 
partitioned by (p_time bigint) 
row format delimited fields terminated by '\t';
(2)加載數據到分區表中
hive (default)> load data local inpath '/opt/module/datas/ds1' into table ori_partitioned partition(p_time='20111230000010') ;
hive (default)> load data local inpath '/opt/module/datas/ds2' into table ori_partitioned partition(p_time='20111230000011') ;
(3)創建目標分區表
create table ori_partitioned_target(id bigint, time bigint, uid string, keyword string, url_rank int, click_num int, click_url string) PARTITIONED BY (p_time STRING) row format delimited fields terminated by '\t';
(4)設置動態分區
set hive.exec.dynamic.partition = true;
set hive.exec.dynamic.partition.mode = nonstrict;
set hive.exec.max.dynamic.partitions = 1000;
set hive.exec.max.dynamic.partitions.pernode = 100;
set hive.exec.max.created.files = 100000;
set hive.error.on.empty.partition = false;

hive (default)> 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;

四、數據傾斜

4.1 合理設置map數

4.1.1 大量小文件導致大量map

這個問題在MapReduce中說過了,默認是按每個文件一個整體去切片的,一個文件至少是一個切片,大量小文件時,勢必產生很多map任務。這個問題在hive中也是一樣的。
解決方案:
在map執行前合并小文件,減少map數:CombineHiveInputFormat具有對小文件進行合并的功能(系統默認的格式)。HiveInputFormat沒有對小文件合并功能。
set hive.input.format= org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;

4.1.2 單個map工作量過大

當每個map執行都非常緩慢時,可能是因為處理邏輯復雜,這時候可以考慮將切片大小設置的小點,增加map數目,減輕每個map工作量。
  增加map的方法為:根據computeSliteSize(Math.max(minSize,Math.min(maxSize,blocksize)))=blocksize=128M公式,調整maxSize最大值。讓maxSize最大值低于blocksize就可以增加map的個數。

設置最大切片值為100個字節
hive (default)> set mapreduce.input.fileinputformat.split.maxsize=100;

這里只是例子,具體設置為多大,根據具體情況決定

4.2 合理設置reduce數

調整方式:

(1)每個Reduce處理的數據量默認是256MB
hive.exec.reducers.bytes.per.reducer=256000000
(2)每個任務最大的reduce數,默認為1009
hive.exec.reducers.max=1009
(3)計算reducer數的公式
N=min(參數2,總輸入數據量/參數1)

要注意:

1)過多的啟動和初始化reduce也會消耗時間和資源;
2)另外,有多少個reduce,就會有多少個輸出文件,如果生成了很多個小文件,那么如果這些小文件作為下一個任務的輸入,則也會出現小文件過多的問題;
在設置reduce個數的時候也需要考慮這兩個原則:處理大數據量利用合適的reduce數;使單個reduce任務處理數據量大小要合適;

五、開啟并發執行

Hive會將一個查詢轉化成一個或者多個階段。這樣的階段可以是MapReduce階段、抽樣階段、合并階段、limit階段。或者Hive執行過程中可能需要的其他階段。默認情況下,Hive一次只會執行一個階段。不過,某個特定的job可能包含眾多的階段,而這些階段可能并非完全互相依賴的,也就是說有些階段是可以并行執行的,這樣可能使得整個job的執行時間縮短。不過,如果有更多的階段可以并行執行,那么job可能就越快完成。
  通過設置參數hive.exec.parallel值為true,就可以開啟并發執行。不過,在共享集群中,需要注意下,如果job中并行階段增多,那么集群利用率就會增加。

set hive.exec.parallel=true;              //打開任務并行執行
set hive.exec.parallel.thread.number=16;  //同一個sql允許最大并行度,默認為8。

六、開啟嚴格模式

Hive提供了一個嚴格模式,可以防止用戶執行那些可能意向不到的不好的影響的查詢。通過設置屬性hive.mapred.mode值為默認是非嚴格模式nonstrict 。開啟嚴格模式需要修改hive.mapred.mode值為strict,開啟嚴格模式可以禁止3種類型的查詢。

<property>
    <name>hive.mapred.mode</name>
    <value>strict</value>
    <description>
      The mode in which the Hive operations are being performed. 
      In strict mode, some risky queries are not allowed to run. They include:
        Cartesian Product.
        No partition being picked up for a query.
        Comparing bigints and strings.
        Comparing bigints and doubles.
        Orderby without limit.
    </description>
  </property>

限制以下三種情況的sql語句的執行:
1)對于分區表,除非where語句中含有分區字段過濾條件來限制范圍,否則不允許執行。換句話說,就是用戶不允許掃描所有分區。進行這個限制的原因是,通常分區表都擁有非常大的數據集,而且數據增加迅速。沒有進行分區限制的查詢可能會消耗令人不可接受的巨大資源來處理這個表。
2)對于使用了order by語句的查詢,要求必須使用limit語句。因為order by為了執行排序過程會將所有的結果數據分發到同一個Reducer中進行處理,強制要求用戶增加這個LIMIT語句可以防止Reducer額外執行很長一段時間。
3)限制笛卡爾積的查詢。對關系型數據庫非常了解的用戶可能期望在執行JOIN查詢的時候不使用ON語句而是使用where語句,這樣關系數據庫的執行優化器就可以高效地將WHERE語句轉化成那個ON語句。不幸的是,Hive并不會執行這種優化,因此,如果表足夠大,那么這個查詢就會出現不可控的情況。

七、開啟JVM重用

JVM重用是Hadoop調優參數的內容,其對Hive的性能具有非常大的影響,特別是對于很難避免小文件的場景或task特別多的場景,這類場景大多數執行時間都很短。
  Hadoop的默認配置通常是使用派生JVM來執行map和Reduce任務的。這時JVM的啟動過程可能會造成相當大的開銷,尤其是執行的job包含有成百上千task任務的情況。JVM重用可以使得JVM實例在同一個job中重新使用N次。N的值可以在Hadoop的mapred-site.xml文件中進行配置。通常在10-20之間,具體多少需要根據具體業務場景測試得出。

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

當前這個也有缺點,這個功能的缺點是,開啟JVM重用將一直占用使用到的task插槽,以便進行重用,直到任務完成后才能釋放,也就說等整個job執行完畢后,占用的所有jvm才會釋放。如果某個“不平衡的”job中有某幾個reduce task執行的時間要比其他Reduce task消耗的時間多的多的話,那么整個job保留的插槽就會一直空閑著卻無法被其他的job使用,直到所有的task都結束了才會釋放。

八、推測執行

關于MapReduce的推測執行見MapReduce部分的推測執行相關的內容,這里不重復。
而hive自己也有提供了配置項來控制reduce-side的推測執行:

<property>
    <name>hive.mapred.reduce.tasks.lative.execution</name>
    <value>true</value>
    <description>Whether speculative execution for reducers should be turned on. </description>
  </property>

關于調優這些推測執行變量,還很難給一個具體的建議。如果用戶對于運行時的偏差非常敏感的話,那么可以將這些功能關閉掉。如果用戶因為輸入數據量很大而需要執行長時間的map或者Reduce task的話,那么啟動推測執行造成的浪費是非常巨大大。

九、啟用壓縮

這個可以看“hive--基本原理”中壓縮相關內容。主要就是從減少map和reduce傳遞的數據量,以及減少reduce輸出文件的大小進行優化。

十、查看執行計劃

執行sql任務時,可以使用 explain查看執行的預計過程,看看有沒有可優化的點。

(1)查看下面這條語句的執行計劃
hive (default)> explain select * from emp;

(2)查看詳細執行計劃
hive (default)> explain extended select * from emp;

以上是“hive使用過程中有哪些調優策略”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

定日县| 勐海县| 榕江县| 阜平县| 肃宁县| 四子王旗| 自贡市| 永昌县| 安宁市| 醴陵市| 惠州市| 松滋市| 宣化县| 清原| 宝山区| 贵南县| 新巴尔虎左旗| 开鲁县| 康马县| 通榆县| 离岛区| 连山| 繁峙县| 正阳县| 通山县| 九寨沟县| 大石桥市| 越西县| 和静县| 府谷县| 长治县| 吐鲁番市| 屏东市| 平远县| 县级市| 武鸣县| 宁乡县| 遵化市| 遂宁市| 平乡县| 长岛县|