1. 程式人生 > 其它 >hive相關總結

hive相關總結

Hive分割槽和分桶的區別?主要作用?

區別:

分割槽欄位不是實際的列,分桶欄位必須是實際的列 。

分割槽表的分割槽數量可以一直增長,而分桶表建立好後桶的數量就固定不變了 。

分割槽和分桶最大的區別就是分桶隨機分割資料庫,分割槽是非隨機分割資料庫。因為分桶是按照列的雜湊函式進行分割的,相對比較平均;而分割槽是按照列的值來進行分割的,容易造成資料傾斜。其次兩者的另一個區別就是分桶是對應不同的檔案(細粒度),分割槽是對應不同的資料夾(粗粒度)。

分割槽作用: 龐大的資料集可能需要耗費大量的時間去處理。在許多場景下,可以通過分割槽的方法減少每一次掃描總資料量,這種做法可以顯著地改善效能。

分桶作用:

HiveSQL轉化為MR的過程

(1)HiveSQL現有驅動模組中的編譯器對其進行SQL語句的詞法和語法解析,將HQL語句轉換成抽象語法樹(AST Tree)的形式;

(2)遍歷轉換成的抽象語法樹,將其轉換成QueryBlock查詢單元。查詢單元是一條最基本的SQL語法組成單元,包括輸入源、計算過程和輸出三個部分;

(3)遍歷查詢單元,將查詢單元轉換成OperatorTree操作樹,操作樹由很多邏輯操作組成;(例如select、join、groupby)

(4)驅動模組中的優化器會對操作樹進行優化,為了減少MR任務和Shuffle數量,合併多餘的操作符;

(5)遍歷優化後的操作樹,根據操作樹生成對應的物理操作任務(MR);

(6)啟動優化器對物理操作任務進行優化,生成最終的MR執行計劃;

(7)最後在驅動模組中的執行器中執行,輸出資料。

Hive生成小檔案過多有什麼影響?如何優化?

影響:

首先對底層儲存HDFS來說,HDFS本身就不適合儲存大量小檔案,小檔案過多會導致namenode元資料特別大, 佔用太多記憶體,嚴重影響HDFS的效能

對 hive 來說,在進行查詢時,每個小檔案都會當成一個塊,啟動一個Map任務來完成,而一個Map任務啟動和初始化的時間遠遠大於邏輯處理的時間,就會造成很大的資源浪費。而且,同時可執行的Map數量是受限的。

優化:

  1. 使用 hive 自帶的 concatenate 命令,自動合併小檔案

注意:
1、concatenate 命令只支援 RCFILE 和 ORC 檔案型別。
2、使用concatenate命令合併小檔案時不能指定合併後的檔案數量,但可以多次執行該命令。
3、當多次使用concatenate後文件數量不在變化,這個跟引數 mapreduce.input.fileinputformat.split.minsize=256mb 的設定有關,可設定每個檔案的最小size。

  1. 調整引數減少Map數量

設定map輸入合併小檔案的相關引數:

#執行Map前進行小檔案合併
#CombineHiveInputFormat底層是 Hadoop的 CombineFileInputFormat 方法
#此方法是在mapper中將多個檔案合成一個split作為輸入
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; -- 預設

#每個Map最大輸入大小(這個值決定了合併後文件的數量)
set mapred.max.split.size=256000000;   -- 256M

#一個節點上split的至少的大小(這個值決定了多個DataNode上的檔案是否需要合併)
set mapred.min.split.size.per.node=100000000;  -- 100M

#一個交換機下split的至少的大小(這個值決定了多個交換機上的檔案是否需要合併)
set mapred.min.split.size.per.rack=100000000;  -- 100M

設定map輸出和reduce輸出進行合併的相關引數:

#設定map端輸出進行合併,預設為true
set hive.merge.mapfiles = true;

#設定reduce端輸出進行合併,預設為false
set hive.merge.mapredfiles = true;

#設定合併檔案的大小
set hive.merge.size.per.task = 256*1000*1000;   -- 256M

#當輸出檔案的平均大小小於該值時,啟動一個獨立的MapReduce任務進行檔案merge
set hive.merge.smallfiles.avgsize=16000000;   -- 16M

啟用壓縮

hive的查詢結果輸出是否進行壓縮

set hive.exec.compress.output=true;

MapReduce Job的結果輸出是否使用壓縮

set mapreduce.output.fileoutputformat.compress=true
  1. 減少Reduce的數量

    #reduce 的個數決定了輸出的檔案的個數,所以可以調整reduce的個數控制hive表的檔案數量,
    #hive中的分割槽函式 distribute by 正好是控制MR中partition分割槽的,
    #然後通過設定reduce的數量,結合分割槽函式讓資料均衡的進入每個reduce即可。
    
    #設定reduce的數量有兩種方式,第一種是直接設定reduce個數
    set mapreduce.job.reduces=10;
    
    #第二種是設定每個reduce的大小,Hive會根據資料總大小猜測確定一個reduce個數
    set hive.exec.reducers.bytes.per.reducer=5120000000; -- 預設是1G,設定為5G
    
    #執行以下語句,將資料均衡的分配到reduce中
    set mapreduce.job.reduces=10;
    insert overwrite table A partition(dt)
    select * from B
    distribute by rand();
    
    解釋:如設定reduce數量為10,則使用 rand(), 隨機生成一個數 x % 10 ,
    這樣資料就會隨機進入 reduce 中,防止出現有的檔案過大或過小 
    
  2. 使用hadoop的archive將小檔案歸檔

Hadoop Archive簡稱HAR,是一個高效地將小檔案放入HDFS塊中的檔案存檔工具,它能夠將多個小檔案打包成一個HAR檔案,這樣在減少namenode記憶體使用的同時,仍然允許對檔案進行透明的訪問.

#用來控制歸檔是否可用
set hive.archive.enabled=true;
#通知Hive在建立歸檔時是否可以設定父目錄
set hive.archive.har.parentdir.settable=true;
#控制需要歸檔檔案的大小
set har.partfile.size=1099511627776;

#使用以下命令進行歸檔
ALTER TABLE A ARCHIVE PARTITION(dt='2020-12-24', hr='12');

#對已歸檔的分割槽恢復為原檔案
ALTER TABLE A UNARCHIVE PARTITION(dt='2020-12-24', hr='12');
注意:  
歸檔的分割槽可以檢視不能 insert overwrite,必須先 unarchive