Hive知識點整理

Hive知識點整理

簡介

  1. Hive解決的問題是海量結構化日誌的數據處理
  2. 基於Hadoop的一個數據倉庫工具,將結構化數據映射爲一張表,提供HQL的類SQL查詢功能
  3. Hive的數據存儲在HDFS上
  4. Hive計算邏輯的底層默認實現是MapReduce
  5. Hive由Yarn調度
  6. Hive相當於Hadoop的客戶端,因此是非分佈式的

優缺點

  1. 類SQL語法,學習成本低
  2. 延遲較高,常用於實時性要求不高的場合,例如離線計算
  3. 吞吐量大(高延遲、高吞吐特性繼承自Hadoop)
  4. 支持用戶自定義函數(UDF, UDAF, UDTF)
  5. 不法表達迭代式計算(繼承自Hadoop)
  6. Hive調優粒度較粗

架構

hive_arch

訪問方式

  1. hive shell: 通過CLI訪問
  2. java連接hive: 通過JDBC訪問

Driver

  1. 解析器:將HQL解析成AST,對AST進行語法分析,檢查錯誤
  2. 編譯器:將AST編譯成邏輯執行計劃
  3. 優化器:對邏輯執行計劃進行優化
  4. 執行器:將邏輯執行計劃轉換爲物理運行計劃,例如MapReduce或Spark

元數據存儲 (Meta Store)

  • 元數據包括:表名、表所屬數據庫、表的擁有者、列、分區字段、表的類型(是否爲外部表)、表數據所在目錄
  • 元數據默認存儲在自帶的derby數據庫中,生產環境下一般用MySQL替代默認的derby存儲元數據

與數據庫區別

  1. 數據庫的數據一般存儲在本地文件系統,Hive的數據存儲在HDFS
  2. 數據庫支持增刪改查,Hive不建議對數據進行改的操作
  3. Hive不能建索引,只能遍歷
  4. Hive的執行引擎是MapReduce,適合海量數據的非實時性查詢
  5. Hive的可擴展性基於Hadoop,可擴展性強

Hive排序

order by

全局排序:只有一個reducer

sort by

區內排序:多個reducer,每個reducer內部分別排序

distribute by

分區:指定按字段進行分區

cluster by

分區排序:相當於distribution bysort by的結合,先分區,每個分區內排序,適用於分區字段和排序字段相同的情況,但是不支持降序,只能升序

分區與分桶

分區

  • 將數據按分區鍵的值存儲到不同目錄下
  • 分區字段會存儲在元數據中,在where中指定分區的話,只會掃描指定的分區,可以避免全表掃描
  • 支持多級分區,partition by (x, y, z, ...),底層就多級目錄嵌套
  • 主要應用場景:按時間(天,小時)給日誌分區

分桶

  • 將數據按分桶鍵的值存儲在多個文件中
  • 主要應用場景:分桶抽樣, tablesample(bucket x out of y)

壓縮與存儲

Hive支持的文件存儲有Textfile, Sequencefile, ORC, Parquet

行存儲與列存儲

  • 行存儲:一行的數據存儲在一起,列存儲:一列的數據存儲在一起
  • Textfile, Sequencefile是行存儲,ORC, Parquet是列存儲

ORC

  1. Index Data: 一個輕量級的index, 每隔1w行做一個索引,記錄某行的各個字段在Row Data中的offset
  2. Row Data: 存儲具體數據,先取一個index內的行,對這些行按列存儲,對每列進行編碼,分成多個Stream存儲
  3. Stripe Footer: 各個Stream的類型,長度信息
  4. 每個文件有一個File Footer, 存每個Stripe的行數,每個Column的數據類型;每個文件尾是一個PostScript,存儲文件的壓縮類型以及File Footer長度。讀文件時,會seek到文件尾部讀PostScript,從裏面解析到File Footer的長度,再讀File Footer,解析到各個Stripe的信息,再從前往後讀內容

Hive調優

Fetch抓取

Hive中某些查詢可以不走MapReduce,例如SELECT * FROM xxx,Hive可以直接讀取表目錄下所有文件,直接輸出結果. Fetch抓取觸發條件由hive-default.xml.template文件的hive.fetch.task.conversion字段決定,默認爲more,當該字段爲more時,全局查找、字段查找 (SELECT col FROM table)、FILTER查找、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
    1. minimal  : SELECT STAR, FILTER on partition columns, LIMIT only
    2. more     : SELECT, FILTER, LIMIT only (support TABLESAMPLE and virtual columns)
    </description>
</property>

本地模式

當數據量小時,Hive可以在單機上處理所有任務,縮短執行時間。set hive.exec.mode.local.auto=true,Hive會根據輸入數據量的大小(hive.exec.mode.local.auto.inputbytes.max, 默認128M)和文件個數(hive.exec.mode.local.auto.input.files.max, 默認4個),自動決定是否開啓本地模式。

小表join大表:mapjoin功能

控制mapjoin開啓的參數hive.auto.convert.join默認值爲true, 大表小表閾值的參數hive.mapjoin.smalltable.filesize默認爲25M,表示默認情況下會對小表進行mapjoin優化,將小表讀入內存,25M以下是小表

大表join大表

大表join大表時,如果某一張表或者兩張表的連接鍵含有很多null,造成數據傾斜,給處理空key的reduce任務帶來很大的壓力,拖慢任務的執行速度。

  1. 空key過濾:join之前通過子查詢is not null過濾連接鍵
  2. 空key轉換:有時連接鍵爲null的字段不能過濾,則將空key轉換爲隨機key(注意隨機key不能和原來的key有重合的可能),使得這些記錄能夠均勻分配到不同的reducer處理

group by優化

Map端聚合

Map端聚合類似MapReduce的combiner操作,在MapTask中預聚合一部分數據,hive.map.aggr默認爲true,表示默認開啓Map端聚合

負載均衡

hive.groupby.skewindata參數控制是否啓用負載均衡,默認爲false. 當發現任務出現嚴重的數據傾斜時,set hive.groupby.skewindata=true,會開啓2個MR job. 第一個執行負載均衡,job將相同的key隨機發送到不同的reducer,然後reducer根據key對數據進行聚合,每個reduce中的數據的key不一定相同. 第二個job執行計算邏輯,將第一個job的結果進行一次聚合,計算最終結果。

count(distinct)優化

COUNT(DISTINCT key)對key去重後計數的操作只用一個ReduceTask,當數據量過大時,reduce節點的計算壓力過大。因此,大數據量時,要將COUNT(DISTINCT key)操作用GROUP BY替換

SELECT COUNT(DISTINCT id) FROM xxx;     -- 原查詢
SELECT COUNT(id) FROM (SELECT id FROM xxx GROUP BY id) a;       -- 優化後的查詢

分區分桶

explain查看執行計劃(類似MySQL)

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