Hive入門到剖析(三)

8 Hive Shell操作

8.1 Hive bin下腳本介紹

wKiom1fJEWeRigS9AAAZ0cMic6g783.jpg-wh_50


8.2 Hive Shell 基本操作

1、Hive 命令行

hive [-hiveconf x=y]* [<-ifilename>]* [<-f filename>|<-e query-string>] [-S]

-i  從文件初始化HQL

-e  從命令行執行指定的HQL

-f  執行HQL腳本

-v  輸出執行的HQL語句到控制檯

-p <port> connect to HiveServer on port number -hiveconf x=y Use this to set hive/hadoop configurationvariables.

Hive 命令行示例

從命令行執行指定的sql語句

$HIVE_HOME/bin/hive -e 'select a.colfrom tab1 a'

以指定的hive環境變量執行指定的sql語句

$HIVE_HOME/bin/hive -e 'select a.colfrom tab1 a' -hiveconf hive.exec.scratchdir=/home/my/hive_scratch -hiveconfmapred.reduce.tasks=32

以沉默模式執行指定的sql語句,並將執行結果導出到指定文件:

HIVE_HOME/bin/hive  -e'select a.col from tab1 a' > a.txt

以非交互式模式執行sql文件

HIVE_HOME/bin/hive -f/home/my/hive-script.sql

在進入交互模式之前,執行初始化sql文件

HIVE_HOME/bin/hive -i/home/my/hive-init.sql

 

Hive 交互式Shell命令

當命令 $HIVE_HOME/bin/hive以不帶 -e/-f 選項的方式運行時, hive將進入到交互模式

以(;)冒號結束命令行


8.3  日誌

Hive使用Log4J來處理日誌

我們可以通過下面的命令設計Hive的日誌級別

$HIVE_HOME/bin/hive -hiveconfhive.root.logger=INFO,console

hive.root.logger的有INFO,DEBUG, 等

 

8.4  資源

Hive添加資源

Hive可以動態的添加資源,如文件

一般情況下,我們是在與Hive進行交互時添加文件

實際上是使用Hadoop的 Distributed Cache來控制的

 

例子

ADD { FILE[S] | JAR[S] | ARCHIVE[S]} <filepath1> [<filepath2>]*

LIST { FILE[S] | JAR[S] | ARCHIVE[S]} [<filepath1> <filepath2> ..]

DELETE { FILE[S] | JAR[S] |ARCHIVE[S] } [<filepath1> <filepath2> ..]


9 Hive優化

9.1  Hadoop 計算框架的特性

1、什麼是數據傾斜

由於數據的不均衡原因,導致數據分佈不均勻,造成數據大量的集中到一點,造成數據熱點。

 

2、Hadoop框架的特性

不怕數據大,怕數據傾斜

jobs數比較多的作業運行效率相對比較低,比如即使有幾百行的表,如果多次關聯多次彙總,產生十幾個jobs,耗時很長。原因是map reduce作業初始化的時間是比較長的

sum,count,max,min等UDAF,不怕數據傾斜問題,hadoop在map端的彙總合併優化,使數據傾斜不成問題

count(distinct ),在數據量大的情況下,效率較低,因爲count(distinct)是按group by 字段分組,按distinct字段排序,一般這種分佈方式是很傾斜的。

 

9.2  優化的常用手段

解決數據傾斜問題

減少job數

設置合理的map reduce的task數,能有效提升性能。

瞭解數據分佈,自己動手解決數據傾斜問題是個不錯的選擇

數據量較大的情況下,慎用count(distinct)。

對小文件進行合併,是行至有效的提高調度效率的方法。

優化時把握整體,單個作業最優不如整體最優。


9.3  Hive的數據類型方面的優化--優化原則

按照一定規則分區(例如根據日期)。通過分區,查詢的時候指定分區,會大大減少在無用數據上的掃描, 同時也非常方便數據清理。

合理的設置Buckets。在一些大數據join的情況下,map join有時候會內存不夠。如果使用Bucket Map Join的話,可以只把其中的一個bucket放到內存中,內存中原來放不下的內存表就變得可以放下。這需要使用buckets的鍵進行join的條件連結,並且需要如下設置

 set hive.optimize.bucketmapjoin = true


9.4  Hive的操作方面的優化

全排序

怎樣做笛卡爾積

怎樣決定map個數

怎樣決定reducer個數

合併MapReduce操作

Bucket 與sampling

Partition

JOIN

Group By

合併小文件

1、全排序

Hive的排序關鍵字是SORTBY,它有意區別於傳統數據庫的ORDER BY也是爲了強調兩者的區別–SORT BY只能在單機範圍內排序。

 

2、怎樣做笛卡爾積

當Hive設定爲嚴格模式(hive.mapred.mode=strict)時,不允許在HQL語句中出現笛卡爾積

MapJoin是的解決辦法

MapJoin,顧名思義,會在Map端完成Join操作。這需要將Join操作的一個或多個表完全讀入內存

MapJoin的用法是在查詢/子查詢的SELECT關鍵字後面添加/*+MAPJOIN(tablelist) */提示優化器轉化爲MapJoin(目前Hive的優化器不能自動優化MapJoin)

其中tablelist可以是一個表,或以逗號連接的表的列表。tablelist中的表將會讀入內存,應該將小表寫在這裏

在大表和小表做笛卡爾積時,規避笛卡爾積的方法是,給Join添加一個Join key,原理很簡單:將小表擴充一列join key,並將小表的條目複製數倍,join key各不相同;將大表擴充一列join key爲隨機數

 

3、控制Hive的Map數

通常情況下,作業會通過input的目錄產生一個或者多個map任務

主要的決定因素有: input的文件總個數,input的文件大小,集羣設置的文件塊大小(目前爲128M, 可在hive中通過setdfs.block.size;命令查看到,該參數不能自定義修改)


是不是map數越多越好

答案是否定的。如果一個任務有很多小文件(遠遠小於塊大小128m),則每個小文件也會被當做一個塊,用一個map任務來完成,而一個map任務啓動和初始化的時間遠遠大於邏輯處理的時間,就會造成很大的資源浪費。而且,同時可執行的map數是受限的


是不是保證每個map處理接近128m的文件塊,就高枕無憂了?

     答案也是不一定。比如有一個127m的文件,正常會用一個map去完成,但這個文件只有一個或者兩個小字段,卻有幾千萬的記錄,

如果map處理的邏輯比較複雜,用一個map任務去做,肯定也比較耗時。 

針對上面的問題3和4,我們需要採取兩種方式來解決:即減少map數和增加map數;


是不是保證每個map處理接近128m的文件塊,就高枕無憂了?

     答案也是不一定。比如有一個127m的文件,正常會用一個map去完成,但這個文件只有一個或者兩個小字段,卻有幾千萬的記錄,

如果map處理的邏輯比較複雜,用一個map任務去做,肯定也比較耗時。 

針對上面的問題3和4,我們需要採取兩種方式來解決:即減少map數和增加map數;


舉例

    a) 假設input目錄下有1個文件a,大小爲780M,那麼hadoop會將該文件a分隔成7個塊(6個128m的塊和1個12m的塊),從而產生7個map數

    b)    假設input目錄下有3個文件a,b,c,大小分別爲10m,20m,130m,那麼hadoop會分隔成4個塊(10m,20m,128m,2m),從而產生4個map數

即,如果文件大於塊大小(128m),那麼會拆分,如果小於塊大小,則把該文件當成一個塊


4、怎樣決定reducer個數

Hadoop MapReduce程序中,reducer個數的設定極大影響執行效率

不指定reducer個數的情況下,Hive會猜測確定一個reducer個數,基於以下兩個設定:

     參數1:hive.exec.reducers.bytes.per.reducer(默認爲1G)

     參數2 :hive.exec.reducers.max(默認爲999)

計算reducer數的公式

N=min(參數2,總輸入數據量/參數1)

依據Hadoop的經驗,可以將參數2設定爲0.95*(集羣中TaskTracker個數)

reduce個數並不是越多越好

同map一樣,啓動和初始化reduce也會消耗時間和資源;

另外,有多少個reduce,就會有多少個輸出文件,如果生成了很多個小文件,那麼如果這些小文件作爲下一個任務的輸入,則也會出現小文件過多的問題

什麼情況下只有一個reduce

    很多時候你會發現任務中不管數據量多大,不管你有沒有設置調整reduce個數的參數,任務中一直都只有一個reduce任務;

其實只有一個reduce任務的情況,除了數據量小於

      hive.exec.reducers.bytes.per.reducer參數值的情況外,還有以下原因:

        a)    沒有group by的彙總

        b)    用了Order by

5、合併 MapReduce操作

Multi-group by

Multi-group by是Hive的一個非常好的特性,它使得Hive中利用中間結果變得非常方便

FROM log

 insert overwrite table test1 select log.id group by log.id

  insert  overwrite table test2select log.name group by log.name

上述查詢語句使用了Multi-group by特性連續group by了2次數據,使用不同的groupby key。這一特性可以減少一次MapReduce操作。

 

6、Bucket 與 Sampling

Bucket是指將數據以指定列的值爲key進行hash,hash到指定數目的桶中。這樣就可以支持高效採樣了

Sampling可以在全體數據上進行採樣,這樣效率自然就低,它還是要去訪問所有數據。而如果一個表已經對某一列製作了bucket,就可以採樣所有桶中指定序號的某個桶,這就減少了訪問量。

如下例所示就是採樣了test中32個桶中的第三個桶。

SELECT * FROM test 、、、TABLESAMPLE(BUCKET 3 OUT OF 32);

 

7、JOIN 原則

在使用寫有 Join 操作的查詢語句時有一條原則:應該將條目少的表/子查詢放在 Join 操作符的左邊

原因是在 Join 操作的 Reduce 階段,位於 Join 操作符左邊的表的內容會被加載進內存,將條目少的表放在左邊,可以有效減少發生 OOM 錯誤的機率。

8、Map Join

Join 操作在 Map階段完成,不再需要Reduce,前提條件是需要的數據在 Map的過程中可以訪問到

例如:

INSERT OVERWRITE TABLE phone_traffic
SELECT /*+MAPJOIN(phone_location) */ l.phone,p.location,l.traffic from phone_location p join log l on(p.phone=l.phone)

相關的參數爲:

hive.join.emit.interval = 1000How many rows in the right-most join operand Hive should buffer before emittingthe join result.
hive.mapjoin.size.key = 10000
hive.mapjoin.cache.numrows =10000

 

9、Group By

Map 端部分聚合

並不是所有的聚合操作都需要在 Reduce 端完成,很多聚合操作都可以先在 Map 端進行部分聚合,最後在 Reduce 端得出最終結果

 

基於 Hash

參數包括:

hive.map.aggr = true 是否在 Map 端進行聚合,默認爲 True

hive.groupby.mapaggr.checkinterval =100000 在 Map 端進行聚合操作的條目數目

有數據傾斜的時候進行負載均衡

hive.groupby.skewindata = false

當選項設定爲 true,生成的查詢計劃會有兩個 MR Job。第一個 MR Job 中,Map 的輸出結果集合會隨機分佈到 Reduce 中,每個 Reduce 做部分聚合操作,並輸出結果,這樣處理的結果是相同的 Group ByKey 有可能被分發到不同的 Reduce 中,從而達到負載均衡的目的;第二個 MR Job 再根據預處理的數據結果按照 Group By Key 分佈到 Reduce 中(這個過程可以保證相同的 Group By Key 被分佈到同一個 Reduce 中),最後完成最終的聚合操作。

 

10、合併小文件

文件數目過多,會給 HDFS 帶來壓力,並且會影響處理效率,可以通過合併 Map 和 Reduce 的結果文件來消除這樣的影響:

hive.merge.mapfiles = true 是否和並 Map 輸出文件,默認爲 True

hive.merge.mapredfiles = false 是否合併 Reduce 輸出文件,默認爲 False

hive.merge.size.per.task =256*1000*1000 合併文件的大小


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章