大數據雲計算——Hive組件

Hive:由 Facebook 開源用於解決海量結構化日誌的數據統計。Hive 是基於 Hadoop 的一個數據倉庫工具,可以將結構化的數據文件映射爲一張表,並提供類 SQL 查詢功能。本質是:將 HQL 轉化成 MapReduce 程序.

Hive的優缺點

優點:

1,可擴展性,橫向擴展,Hive可以自由的擴展集羣規模,一般情況下不需要重啓服務

2,延展性。Hive支持自定義函數,用戶可以根據自己的需求來實現自己的函數

3,良好的容錯性。可以保障即使節點出現問題,sql仍可完整執行。

缺點:

1,Hive不支持記錄級別的增刪改操作。但可以通過查詢生成新表或者將查詢結果導入文件中。

2,Hive查詢延遲很嚴重,因爲MapReduce Job的啓動過程消耗很長時間,所以不能用在交互查詢中。

3,Hive不支持事物。主要用作OLAP(聯機分析處理)

1) Hive 處理的數據存儲在 HDFS

2) Hive 分析數據底層的默認實現是 MapReduce

3) 執行程序運行在 Yarn 上

總結:相當於是hadoop的一個客戶端的作用。

6.1Hive 架構原理

1. 用戶接口: Client

CLI(hive shell)、 JDBC/ODBC(java 訪問 hive)、 WEBUI(瀏覽器訪問 hive)

2. 元數據: Metastore

元數據包括:表名、表所屬的數據庫(默認是 default)、表的擁有者、列/分區字段、表

的類型(是否是外部表)、表的數據所在目錄等;

元數據: Metastore

元數據包括:表名、表所屬的數據庫(默認是 default)、表的擁有者、列/分區字段、表

的類型(是否是外部表)、表的數據所在目錄等;

默認存儲在自帶的 derby 數據庫中,推薦使用 MySQL 存儲 Metastore。

3. Hadoop

使用 HDFS 進行存儲,使用 MapReduce 進行計算。

4. 驅動器: Driver

(1)解析器(SQL Parser):將 SQL 字符串轉換成抽象語法樹 AST,這一步一般都用

第三方工具庫完成,比如 antlr;對 AST 進行語法分析,比如表是否存在、字段是否存

在、 SQL 語義是否有誤。

(2)編譯器(Physical Plan):將 AST 編譯生成邏輯執行計劃。

(3)優化器(Query Optimizer):對邏輯執行計劃進行優化。

(4)執行器(Execution):把邏輯執行計劃轉換成可以運行的物理計劃。對於 Hive 來

說,就是 MR/Spark。

Hive 是建立在 Hadoop 之上的,所有 Hive 的數據都是存儲在 HDFS 中的。而數據庫則

可以將數據保存在塊設備或者本地文件系統中。

由於 Hive 是針對數據倉庫應用設計的,而數據倉庫的內容是讀多寫少的。 因此, Hive

中不建議對數據的改寫,所有的數據都是在加載的時候確定好的。而數據庫中的數據通常是

需要經常進行修改的,因此可以使用INSERT INTO … VALUES 添加數據,使用UPDATE … SET 修改數據。

爲什麼Hive的訪問延遲很高?

Hive在加載數據的過程中不會對數據進行任何處理,甚至不會對數據進行掃描,因此也沒有對數據中的某些 Key 建立索引。Hive 要訪問數據中滿足條件的特定值時,需要暴力掃描整個數據,因此訪問延遲較高。由於MapReduce 的引入,Hive可以並行訪問數據,因此即使沒有索引,對於大數據量的訪問, Hive 仍然可以體現出優勢。數據庫中,通常會針對一個或者幾個列建立索引,因此對於少量的特定條件的數據的訪問,數據庫可以有很高的效率,較低的延遲。由於數據的訪問延遲較高,決定了 Hive 不適合在線數據查詢。Hive 中大多數查詢的執行是通過 Hadoop 提供的 MapReduce 來實現的。而數據庫通常有自己的執行引擎。

Hive執行的延遲的原因是:

Hive 在查詢數據的時候,由於沒有索引,需要掃描整個表,因此延遲較高。另外一個導致 Hive 執行延遲高的因素是 MapReduce 框架。由於 MapReduce本身具有較高的延遲,因此在利用 MapReduce 執行 Hive 查詢時,也會有較高的延遲。相對的,數據庫的執行延遲較低。當然,這個低是有條件的,即數據規模較小,當數據規模大到超過數據庫的處理能力的時,Hive 的並行計算顯然能體現出優勢。

6.2Hive DDL數據定義

創建一個數據庫, 數據庫在 HDFS 上的默認存儲路徑是/user/hive/warehouse/*.db。

1 create database db_hive

避免要創建的數據庫已經存在錯誤, 增加 if not exists 判斷。(標準寫法)

2 create database if not exists db_hive

創建一個數據庫,指定數據庫在 HDFS 上存放的位置

3 create database db_hive2 location '/db_hive2.db'

顯示數據庫

4 show databases

過濾顯示查詢的數據庫

5 show databases like 'db_hive*'

修改數據庫

6 用戶可以使用ALTER DATABASE 命令爲某個數據庫的DBPROPERTIES設置鍵-值對屬性值,來描述這個數據庫的屬性信息。數據庫的其他元數據信息都是不可更改的,包括數據庫名和數據庫所在的目錄位置。

alter database hive set dbproperties('createtime'='20170830');

7 刪除空數據庫

drop database db_hive2;

drop database if exists db_hive2;

8 如果數據庫不爲空,可以採用 cascade 命令,強制刪除

ALTER TABLE table_name RENAME TO new_table_name

9重命名錶

drop table dept_partition;

10刪除表

(1)CREATE TABLE 創建一個指定名字的表。 如果相同名字的表已經存在,則拋出

異常;用戶可以用 IF NOT EXISTS 選項來忽略這個異常。

(2)EXTERNAL 關鍵字可以讓用戶創建一個外部表,在建表的同時指定一個指向實際

數據的路徑(LOCATION), Hive 創建內部表時,會將數據移動到數據倉庫指向的路

徑;若創建外部表,僅記錄數據所在的路徑,不對數據的位置做任何改變。在刪除表的

時候,內部表的元數據和數據會被一起刪除,而外部表只刪除元數據,不刪除數據。

(3)COMMENT:爲表和列添加註釋。

(4)PARTITIONED BY 創建分區表

(5)CLUSTERED BY 創建分桶表

(6)SORTED BY 不常用

(7)ROW FORMAT DELIMITED [FIELDS TERMINATED BY char] [COLLECTION ITEMS

TERMINATED BY char] [MAP KEYS TERMINATED BY char] [LINES TERMINATED BY char] | SERDE serde_name [WITH SERDEPROPERTIES (property_name=property_value,

property_name=property_value, ...)]

用戶在建表的時候可以自定義 SerDe 或者使用自帶的 SerDe。如果沒有指定 ROW

FORMAT 或者 ROW FORMAT DELIMITED,將會使用自帶的 SerDe。在建表的時候,用戶

還需要爲表指定列,用戶在指定表的列的同時也會指定自定義的 SerDe, Hive 通過 SerDe

確定表的具體的列的數據。

SerDe 是 Serialize/Deserilize 的簡稱,目的是用於序列化和反序列化。

(8) STORED AS 指定存儲文件類型

常用的存儲文件類型: SEQUENCEFILE(二進制序列文件)、 TEXTFILE(文本)、

RCFILE(列式存儲格式文件)

如果文件數據是純文本,可以使用 STORED AS TEXTFILE。如果數據需要壓縮,

使用 STORED AS SEQUENCEFILE。

(9) LOCATION :指定表在 HDFS 上的存儲位置。

(10)LIKE 允許用戶複製現有的表結構,但是不復制數據

管理表:

默認創建的表都是所謂的管理表,有時也被稱爲內部表。因爲這種表,Hive 會(或多或少地) 控制着數據的生命週期。Hive 默認情況下會將這些表的數據存儲在由配置項hive.metastore.warehouse.dir(例如, /user/hive/warehouse)所定義的目錄的子目錄下。 當我們刪除一個管理表時,Hive 也會刪除這個表中數據。 管理表不適合和其他工具共享數據

外部表:

因爲表是外部表,所以 Hive 並非認爲其完全擁有這份數據。 刪除該表並不會刪除掉這份數據,不過描述表的元數據信息會被刪除掉。

管理表和外部表的使用場景

每天將收集到的網站日誌定期流入HDFS文本文件。在外部表(原始日誌表)的基礎上做大量的統計分析,用到的中間表、 結果表使用內部表存儲,數據通過 SELECT+INSERT進入內部表。分別創建部門和員工外部表,並向表中導入數據。

實際的例子:

分區表

分區表實際上就是對應一個 HDFS 文件系統上的獨立的文件夾,該文件夾下是該分區所有的數據文件。Hive中的分區就是分目錄,把一個大的數據集根據業務需要分割成小的數據集。在查詢時通過WHERE子句的表達式選擇查詢所需要的指定的分區,這樣的查詢效率會提高很多。

6.3Hive DML數據操作

向表中裝載數據(Load)

load data [local] inpath '/opt/module/datas/student.txt' [overwrite] | into table student [partition (partcol1=val1,…)];

通過查詢語句向表中插入數據(Insert)

Import 數據到指定 Hive 表中

import table student2 partition(month='201709') from

'/user/hive/warehouse/export/student';

Insert 導出

分區針對的是數據的存儲路徑;分桶針對的是數據文件。分區提供一個隔離數據和優化查詢的便利方式。不過,並非所有的數據集都可形成合理的分區,特別是之前所提到過的要確定合適的劃分大小這個疑慮。分桶是將數據集分解成更容易管理的若干部分的另一個技術

6.4Hive 的自定義函數

1) Hive 自帶了一些函數,比如: max/min 等,但是數量有限,自己可以通過自定義 UDF

來方便的擴展。

2) 當 Hive 提供的內置函數無法滿足你的業務處理需要時,此時就可以考慮使用用戶自定義

函數(UDF: user-defined function)。

3)根據用戶自定義函數類別分爲以下三種:

(1)UDF(User-Defined-Function)一進一出

(2)UDAF(User-Defined Aggregation Function)聚集函數,多進一出

類似於: count/max/min

(3)UDTF(User-Defined Table-Generating Functions)一進多出 如 lateral view explore()

6.5Hive 壓縮與存儲

hive對文件的壓縮是對內容的壓縮,也就是說對文件的壓縮不是先生成文件,再對文件壓縮,而是在生成文件時,對其中的內容字段進行壓縮,最終壓縮後,對外仍體現爲某種具體的壓縮文件。開啓 map 輸出階段壓縮可以減少 job 中 map 和 Reduce task 間數據傳輸量。

6.6Hive 文件存儲格式

Hive 支持的存儲數的格式主要有: TEXTFILE 、 SEQUENCEFILE、 ORC、 PARQUET

1.行存儲的特點

查詢滿足條件的一整行數據的時候,列存儲則需要去每個聚集的字段找到對應的每個列

的值,行存儲只需要找到其中一個值,其餘的值都在相鄰地方, 所以此時行存儲查詢的速度

更快。

2.列存儲的特點

因爲每個字段的數據聚集存儲,在查詢只需要少數幾個字段的時候,能大大減少讀取的

數據量;每個字段的數據類型一定是相同的,列式存儲可以針對性的設計更好的設計壓縮算

法。TEXTFILE 和 SEQUENCEFILE 的存儲格式都是基於行存儲的;ORC 和 PARQUET 是基於列式存儲的。

6.7Hive 企業的調優

Fetch 抓取是指,Hive中對某些情況的查詢可以不必使用 MapReduce 計算。例如:SELECT * FROM employees;在這種情況下, Hive 可以簡單地讀取 employee 對應的存儲目錄下的文件,然後輸出查詢結果到控制檯。

在 hive-default.xml.template 文件中 hive.fetch.task.conversion 默認是 more,老版本 hive默認是 minimal,該屬性修改爲 more 以後,在全局查找、字段查找、 limit 查找等都不走mapreduce。

6.8Hive 表的優化處理

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

如果不指定 MapJoin 或者不符合 MapJoin 的條件,那麼 Hive 解析器會將 Join 操作轉換

成 Common Join,即:在 Reduce 階段完成 join。容易發生數據傾斜。可以用 MapJoin 把小

表全部加載到內存在 map 端進行 join,避免 reducer 處理。

MR 優化

合理設置 Map 數

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

主要的決定因素有: input 的文件總個數, input 的文件大小,集羣設置的文件塊大小。

2)是不是 map 數越多越好?

答案是否定的。如果一個任務有很多小文件(遠遠小於塊大小 128m),則每個小文件

也會被當做一個塊,用一個 map 任務來完成,而一個 map 任務啓動和初始化的時間遠遠大

於邏輯處理的時間,就會造成很大的資源浪費。而且,同時可執行的 map 數是受限的。

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

答案也是不一定。比如有一個 127m 的文件,正常會用一個 map 去完成,但這個文件只

有一個或者兩個小字段,卻有幾千萬的記錄,如果 map 處理的邏輯比較複雜,用一個 map

任務去做,肯定也比較耗時。

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

小文件進行合併:在 map 執行前合併小文件,減少 map 數: CombineHiveInputFormat 具有對小文件進行合併的功能(系統默認的格式)。 HiveInputFormat 沒有對小文件合併功能

複雜文件增加 Map 數:當 input 的文件都很大,任務邏輯複雜, map 執行非常慢的時候,可以考慮增加 Map數,來使得每個 map 處理的數據量減少,從而提高任務的執行效率。

增加 map 的方法爲:根據

computeSliteSize(Math.max(minSize,Math.min(maxSize,blocksize)))=blocksize=128M 公式,調整 maxSize 最大值。讓 maxSize 最大值低於 blocksize 就可以增加 map 的個數。

並行執行

Hive 會將一個查詢轉化成一個或者多個階段。這樣的階段可以是MapReduce階段、抽樣階段、合併階段、limit 階段。或者 Hive 執行過程中可能需要的其他階段。默認情況下,Hive 一次只會執行一個階段。不過,某個特定的 job 可能包含衆多的階段,而這些階段可能並非完全互相依賴的,也就是說有些階段是可以並行執行的,這樣可能使得整個 job 的執行時間縮短。不過,如果有更多的階段可以並行執行,那麼 job 可能就越快完成。

6.9Hive 嚴格模式

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

1)區表, 除非 where 語句中含有分區字段過濾條件來限制範圍,否則不允許執行。換句話說,就是用戶不允許掃描所有分區。進行這個限制的原因是,通常分區表都擁有非常大的數據集,而且數據增加迅速。沒有進行分區限制的查詢可能會消耗令人不可接受的巨大資源來處理這個表。

2) 對於使用了 order by 語句的查詢,要求必須使用 limit 語句。 因爲 order by 爲了執行排序過程會將所有的結果數據分發到同一個 Reducer 中進行處理,強制要求用戶增加這個

LIMIT 語句可以防止 Reducer 額外執行很長一段時間。

3) 限制笛卡爾積的查詢。 對關係型數據庫非常瞭解的用戶可能期望在執行 JOIN 查詢的時

候不使用 ON 語句而是使用 where 語句,這樣關係數據庫的執行優化器就可以高效地將WHERE 語句轉化成那個 ON 語句。不幸的是, Hive 並不會執行這種優化,因此,如果表足夠大,那麼這個查詢就會出現不可控的情況。

JVM 重用是 Hadoop 調優參數的內容,其對 Hive 的性能具有非常大的影響,特別是對於很難避免小文件的場景或 task 特別多的場景,這類場景大多數執行時間都很短。Hadoop 的默認配置通常是使用派生 JVM 來執行 map 和 Reduce 任務的。這時 JVM 的啓動過程可能會造成相當大的開銷,尤其是執行的 job 包含有成百上千 task任務的情況。JVM重用可以使得 JVM 實例在同一個 job 中重新使用 N 次。 N 的值可以在 Hadoop 的這個功能的缺點是,開啓 JVM 重用將一直佔用使用到的 task 插槽,以便進行重用,直到任務完成後才能釋放。如果某個“不平衡的”job 中有某幾個 reduce task 執行的時間要比其他 Reduce task 消耗的時間多的多的話,那麼保留的插槽就會一直空閒着卻無法被其他的 job使用,直到所有的 task 都結束了纔會釋放.

7.0hadoop的推測執行

在分佈式集羣環境下, 因爲程序 Bug(包括 Hadoop 本身的 bug), 負載不均衡或者資源分佈不均等原因,會造成同一個作業的多個任務之間運行速度不一致,有些任務的運行速度可能明顯慢於其他任務(比如一個作業的某個任務進度只有 50%,而其他所有任務已經運行完畢),則這些任務會拖慢作業的整體執行進度。爲了避免這種情況發生, Hadoop 採用了推測執行(Speculative Execution)機制,它根據一定的法則推測出“拖後腿”的任務,併爲這樣的任務啓動一個備份任務,讓該任務與原始任務同時處理同一份數據,並最終選用最先成功運行完成任務的計算結果作爲最終結果。於調優這些推測執行變量,還很難給一個具體的建議。 如果用戶對於運行時的偏差非

常敏感的話,那麼可以將這些功能關閉掉。 如果用戶因爲輸入數據量很大而需要執行長時間的 map 或者 Reduce task 的話,那麼啓動推測執行造成的浪費是非常巨大大。

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