HIVE MR知識鞏固

概念

Hive 將 HQL 轉換成MapReduce 執行 ,可以說Hive 是基於 hadoop的一個數據倉庫工具,實質就是一款基於 HDFS的 MapReduce 計算框架

我的大白話解釋

其實Hive就是基於hdfs以及mr的數據倉庫,通過hql進行數據的導入,以及對數據的離線分析。導入數據是將結構化的數據文件映射爲一張數據庫表,離線分析則是將hql翻譯爲mr進行執行。

相關組件

Metastore :存儲系統目錄以及關於表、列、分區等元數據的組件

Driver:該組件包括Complier、Optimizer和Executor,它的作用是將我們寫的HiveQL(類SQL)語句進行解析、編譯優化,生成執行計劃,然後調用底層的mapreduce計算框架。

Thrift服務:它用來進行可擴展且跨語言的服務的開發,hive集成了該服務,能讓不同的編程語言調用hive的接口。

客戶端組件:CLI:command line interface,命令行接口。
Thrift客戶端: hive架構的許多客戶端接口是建立在thrift客戶端之上,包括JDBC和ODBC接口。
WEBGUI:hive客戶端提供了一種通過網頁的方式訪問hive所提供的服務。這個接口對應hive的hwi組件(hive web interface),使用前要啓動hwi服務。

運行機理

  1. 命令行或Web UI之類的Hive接口將查詢語句發送給Driver
  2. Driver藉助查詢編譯器解析查詢語句,檢查語法和查詢計劃或查詢需求
  3. 編譯器將元數據請求發送到Metastore
  4. Metastore將元數據響應給編譯器
  5. 編譯器檢查需求並將計劃重新發送給Driver。
    到目前爲止,查詢的解析和編譯已經完成
  6. Driver將執行計劃發送到執行引擎
  7. 在內部,執行任務的過程是MapReduce Job。執行引擎將Job發送到ResourceManager, ResourceManager位於Name節點中,並將job分配給datanode中的NodeManager。在這裏,查詢執行MapReduce任務.
  8. 執行引擎將從datanode上獲取結果集
  9. 執行引擎將這些結果值發送給Driver
  10. Driver將結果發送到Hive接口

hive建表 數據導入
普通表創建 導入
創建表 導入數據字段按逗號分隔開
create table if not exists brand_dimension
(bid STRING,
category STRING,
brand STRING)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ',‘;

導入數據 local字段爲linux本地導入 不加則爲hdfs目錄
load data local inpath ‘/hivedata/user.data’ overwrite into table brand_dimension ;

分區表

month值一致的所有記錄存放在一個分區中,分區,這是將滿足某些條件的記錄打包,做個記號,在查詢時提高效率,相當於按文件夾對文件進行分類。
create external table if not exists stocks (
empno int,
ename string,
job string,
mgr int
)
partitioned by (month string)
row format delimited fields terminated by ‘,’

導入數據

load data local inpath ‘hivedata/stocks/NASDAQ/AAPL/stocks.csv’ overwrite into table stocks partition(month=“201812”);
insert into table stocks partition(month=‘201812’) select * from stocks 2;

外部表

指定表存放文件位置創建外部表,drop表 指揮刪除元數據,不刪除hdfs文件數據
reate external table if not exists stocks (
empno int,
ename string,
job string,
mgr int
)
row format delimited fields terminated by ‘,’
LOCATION ‘bigdata/stocks’;
處理json數據
{“id”:1701439105,“ids”:[2154137571,3889177061,1496915057,……,1663973284],“total_number”: 493}
select get_json_object(t.json,’.id),getjsonobject(t.json,.id'), get_json_object(t.json,'.total_number’) from tmp_json_test t ;

數據格式

1、TEXTFILE :默認格式,建表時不指定默認爲這個格式,導入數據時會直接把數據文件拷貝到hdfs上不進行處理。
2、SEQUENCEFILE 一種Hadoop API提供的二進制文件,使用方便、可分割、可壓縮等特點。
3:ORC:ORC是RCfile的升級版,性能有大幅度提升, 而且數據可以壓縮存儲,壓縮比和Lzo壓縮差不多,比text文件壓縮比可以達到70%的空間。而且讀性能非常高,可以實現高效查詢。
4、RCFILE : 一種行列存儲相結合的存儲方式。首先,其將數據按行分塊,保證同一個record在一個塊上,避免讀一個記錄需要讀取多個block。其次,塊數據列式存儲,有利於數據壓縮和快速的列存取。理論上具有高查詢效率(但hive官方說效果不明顯,只有存儲上能省10%的空間,所以不好用,可以不用)。

自定義函數函數
分三類
UDF 一進一出 處理原文件內容某些字段包含 [] “”
UDAF 多進一出 sum() avg() max() min()
UDTF 一進多出 ip -> 國家 省 市

UDF函數的開發
** 必須繼承UDF類
** 重寫evaluate函數 支持重載
** 必須要有返回類型,可以返回null,但是返回類型不能爲void
使用方式
1、編程
2、把程序到出爲jar包放到目標機器上去:
hive> add jar /home/beifeng/jars/lower.jar ;
3、創建臨時函數:
hive> CREATE TEMPORARY FUNCTION my_lower AS ‘包名.類名’;
4**、使用指定函數**:
hive> show fuctions ;
hive> select my_lower(ename) from emp ;

MapReduce工作流程

基本流程:

1,數據經split劃分成大小相等的數據塊(數據塊的大小一般等於HDFS一個塊的大小)以及用戶作業程序。
2,系統中有一個負責調度的Master節點和許多的Map工作節點,Reduce工作節點
3,用戶作業程序提交給Master節點,Master節點尋找合適的Map節點,並將數據傳給Map節點,並且Master也尋找合適的Reduce節點並將數據傳給Reduce節點
4,Master節點啓動Map節點執行程序,Map節點儘可能的讀取本地或本機架上的數據塊進行計算。(數據本地化是Mapreduce的核心特徵)
5,每個Map節點處理讀取的數據塊,並做一些數據整理,並且將中間結果放在本地而非HDFS中,同時通知Master節點Map工作完成,並告知中間結果的存儲位置。
6,Master節點等所有Map工作完成後,開始啓動Reduce節點,Reduce節點通過Master節點掌握的中間結果的存儲位置來遠程讀取中間結果。
7,Reduce節點將中間結果處理後將結果輸出到一個文件中

MapReduce 的shuffle過程

在這裏插入圖片描述
MapReduce確保每個reducer的輸入都是按鍵排序的。系統執行排序、將map輸出作爲輸入傳給reducer的過程稱爲Shuffle。

1 map端
map函數開始產生輸出時,利用緩衝的方式寫到內存並排序具體分一下幾個步驟。

  1. map數據分片:把輸入數據源進行分片,根據分片來決定有多少個map,每個map任務都有一個環形內存緩衝區用於存儲任務輸出,默認情況下緩衝區大小爲100MB,可通mapreduce.task.io.sort.mb來調整。
  2. map排序:當map緩衝區大小達到閾值時(mapreduce.map.sort.spill.percent),就會將內存的數據溢寫到磁盤,根據reducer的個數劃分成相應的partition,在內存中按鍵值進行排序,如果有combiner函數,在排序後就會應用,排序後寫入分區磁盤文件中。溢寫的過程中,map會阻塞直到寫磁盤過程完成。每次內存緩衝區到達溢出閾值,就會新建一個溢出文件件,在map寫完最後一個輸出記錄之後,會有幾個溢出文件,在任務完成之前溢出文件會被合併成一個已分區且已經排序的輸出文件
    2reduce端
  3. reduce複製:每個map任務的完成時間不同,在所有任務完成時,reduce任務就開始複製其輸出,這就是reduce任務的複製階段。如果map輸出很小,會被複制到reduce任務JVM的內存,否則輸出被複制到磁盤。如果內存緩衝區達到閾值大小或達到map輸出閾值,則合併溢出寫到磁盤中,如果指定combiner,則在合併期間運行它。隨着磁盤上副本增多,後臺線程會將他們合併爲更大的,排序的文件。
  4. reduce合併排序:這個階段合併map輸出,維持其順序排序,這是循環進行的,如果有50個map輸出,合併因子是10,合併將進行5次,最後有5箇中間文件。
  5. reduce:直接把數據輸入reduce函數,從而省略了一次磁盤的往返行程。

數據傾斜

產生原因

  1. key 的分化嚴重不均,造成一部分數據很多,一部分數據很少的局面
    2.機器性能分配不均(機器配置和數據量存在一個合理的比例)
  2. join的key值發生傾斜,key值包含很多空值或是異常值
    4.SQL語句造成數據傾斜
    group by 維度過小,某值的數量過多,處理某值的reduce非常耗時
    去重 distinct count(distinct xx),某特殊值過多,處理此特殊值的reduce耗時
    連接 join,其中一個表較小,但是key集中,分發到某一個或幾個Reduce上的數據遠高於平均值

解決方案

調優參數

set hive.map.aggr=true 在map中會做部分聚集操作,效率更高但需要更多的內存。
set hive.groupby.skewindata=true; 數據傾斜時負載均衡。使計算變成了兩個mapreduce,先在第一個中在 shuffle 過程 partition 時隨機給 key 打標記,使每個key 隨機均勻分佈到各個 reduce 上計算,但是這樣只能完成部分計算,因爲相同key沒有分配到相同reduce上,所以需要第二次的mapreduce,這次就回歸正常 shuffle,但是數據分佈不均勻的問題在第一次mapreduce已經有了很大的改善,因此基本解決數據傾斜。

SQL語句優化

  1. 大小表進行連接時,使用map join讓小表先進內存,在map端完成reduce。
  2. 大表連接大表時,如果是空值造成數據傾斜,那麼把空值變成一個字符串加上隨機數,把這部分傾斜的數據分發到不同的reduce上。
  3. 如果count distinct有大量相同特殊值 (如空值) 空值可以不用處理,直接最後count結果加1即可。或者空值單獨拿出來處理,最後再union回去。
  4. 不同數據類型關聯 默認的hash操作會按其中一種類型的值進行分配,導致別一種類型全部分發到同一個reduce中。把兩個關聯的類型轉換成相同類型。

其他解決方案

1.增加reduce 的jvm內存(單個值有大量記錄, 這種值的所有紀錄已經超過了分配給reduce 的內存)
2. 增加reduce 個數(唯一值較多,單個唯一值的記錄數不會超過分配給reduce 的內存)
Map join
hive 中的join可分爲倆類,一種是common join(也叫Reduce join或shuffle join),另一種是 map join,後者是對hive join的一個優化,利用本地的task對較小的表hash生產一個hashtable文件,然後直接和map出來另一個表進行匹配,最終完成join
set hive.auto.convert.join = true在0.11.0到之後的版本是ture,代表使用優化

map join 沒有shuffle過程,他是對小表進行hash到hdfs 臨時緩存中生成hashtable file,然後直接匹配,正常的join是使用倆個map和一個reduce來完成join,因爲過程中有shuffle,所以會有網絡io,執行效率相對較小

https://blog.csdn.net/WYpersist/article/details/80102757?utm_source=blogxgwz3

hive行專列:https://www.cnblogs.com/kimbo/p/6208973.html

mysql行專列:
https://www.cnblogs.com/ken-jl/p/8570518.html

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