Hive 系列(一)—— Hive 簡介及核心概念

1、簡介

Hive 是一個構建在 Hadoop 之上的數據倉庫,它能夠將結構化的數據文件映射成表,並提供類 SQL 查詢功能,用於查詢的 SQL 語句會被轉化爲 MapReduce 做業,而後提交到 Hadoop 上運行。html

特色git

  1. 簡單、容易上手 (提供了相似 sql 的查詢語言 hql),使得精通 sql 可是不瞭解 Java 編程的人也能很好地進行大數據分析;
  2. 靈活性高,能夠自定義用戶函數 (UDF) 和存儲格式;
  3. 爲超大的數據集設計的計算和存儲能力,集羣擴展容易;
  4. 統一的元數據管理,可與 presto/impala/sparksql 等共享數據;
  5. 執行延遲高,不適合作數據的實時處理,但適合作海量數據的離線處理。

2、Hive的體系架構

2.1 command-line shell & thrift/jdbc

能夠用 command-line shell 和 thrift/jdbc 兩種方式來操做數據:github

  • command-line shell:經過 hive 命令行的的方式來操做數據;
  • thrift/jdbc:經過 thrift 協議按照標準的 JDBC 的方式操做數據。

2.2 Metastore

在 Hive 中,表名、表結構、字段名、字段類型、表的分隔符等統一被稱爲元數據。全部的元數據默認存儲在 Hive 內置的 derby 數據庫中,但因爲 derby 只能有一個實例,也就是說不能有多個命令行客戶端同時訪問,因此在實際生產環境中,一般使用 MySQL 代替 derby。算法

Hive 進行的是統一的元數據管理,就是說你在 Hive 上建立了一張表,而後在 presto/impala/sparksql 中都是能夠直接使用的,它們會從 Metastore 中獲取統一的元數據信息,一樣的你在 presto/impala/sparksql 中建立一張表,在 Hive 中也能夠直接使用。sql

2.3 HQL的執行流程

Hive 在執行一條 HQL 的時候,會通過如下步驟:shell

  1. 語法解析:Antlr 定義 SQL 的語法規則,完成 SQL 詞法,語法解析,將 SQL 轉化爲抽象 語法樹 AST Tree;
  2. 語義解析:遍歷 AST Tree,抽象出查詢的基本組成單元 QueryBlock;
  3. 生成邏輯執行計劃:遍歷 QueryBlock,翻譯爲執行操做樹 OperatorTree;
  4. 優化邏輯執行計劃:邏輯層優化器進行 OperatorTree 變換,合併沒必要要的 ReduceSinkOperator,減小 shuffle 數據量;
  5. 生成物理執行計劃:遍歷 OperatorTree,翻譯爲 MapReduce 任務;
  6. 優化物理執行計劃:物理層優化器進行 MapReduce 任務的變換,生成最終的執行計劃。

關於 Hive SQL 的詳細執行流程能夠參考美團技術團隊的文章:Hive SQL 的編譯過程數據庫

3、數據類型

3.1 基本數據類型

Hive 表中的列支持如下基本數據類型:apache

大類 類型
Integers(整型) TINYINT—1 字節的有符號整數
SMALLINT—2 字節的有符號整數
INT—4 字節的有符號整數
BIGINT—8 字節的有符號整數
Boolean(布爾型) BOOLEAN—TRUE/FALSE
Floating point numbers(浮點型) FLOAT— 單精度浮點型
DOUBLE—雙精度浮點型
Fixed point numbers(定點數) DECIMAL—用戶自定義精度定點數,好比 DECIMAL(7,2)
String types(字符串) STRING—指定字符集的字符序列
VARCHAR—具備最大長度限制的字符序列
CHAR—固定長度的字符序列
Date and time types(日期時間類型) TIMESTAMP — 時間戳
TIMESTAMP WITH LOCAL TIME ZONE — 時間戳,納秒精度
DATE—日期類型
Binary types(二進制類型) BINARY—字節序列

TIMESTAMP 和 TIMESTAMP WITH LOCAL TIME ZONE 的區別以下:編程

  • TIMESTAMP WITH LOCAL TIME ZONE:用戶提交時間給數據庫時,會被轉換成數據庫所在的時區來保存。查詢時則按照查詢客戶端的不一樣,轉換爲查詢客戶端所在時區的時間。
  • TIMESTAMP :提交什麼時間就保存什麼時間,查詢時也不作任何轉換。

3.2 隱式轉換

Hive 中基本數據類型遵循如下的層次結構,按照這個層次結構,子類型到祖先類型容許隱式轉換。例如 INT 類型的數據容許隱式轉換爲 BIGINT 類型。額外注意的是:按照類型層次結構容許將 STRING 類型隱式轉換爲 DOUBLE 類型。數組

3.3 複雜類型

類型 描述 示例
STRUCT 相似於對象,是字段的集合,字段的類型能夠不一樣,可使用 名稱.字段名 方式進行訪問 STRUCT ('xiaoming', 12 , '2018-12-12')
MAP 鍵值對的集合,可使用 名稱[key] 的方式訪問對應的值 map('a', 1, 'b', 2)
ARRAY 數組是一組具備相同類型和名稱的變量的集合,可使用 名稱[index] 訪問對應的值 ARRAY('a', 'b', 'c', 'd')

3.4 示例

以下給出一個基本數據類型和複雜數據類型的使用示例:

CREATE TABLE students(
  name      STRING,   -- 姓名
  age       INT,      -- 年齡
  subject   ARRAY<STRING>,   --學科
  score     MAP<STRING,FLOAT>,  --各個學科考試成績
  address   STRUCT<houseNumber:int, street:STRING, city:STRING, province:STRING>  --家庭居住地址
) ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t";

4、內容格式

當數據存儲在文本文件中,必須按照必定格式區別行和列,如使用逗號做爲分隔符的 CSV 文件 (Comma-Separated Values) 或者使用製表符做爲分隔值的 TSV 文件 (Tab-Separated Values)。但此時也存在一個缺點,就是正常的文件內容中也可能出現逗號或者製表符。

因此 Hive 默認使用了幾個平時不多出現的字符,這些字符通常不會做爲內容出如今文件中。Hive 默認的行和列分隔符以下表所示。

分隔符 描述
\n 對於文本文件來講,每行是一條記錄,因此可使用換行符來分割記錄
^A (Ctrl+A) 分割字段 (列),在 CREATE TABLE 語句中也可使用八進制編碼 \001 來表示
^B 用於分割 ARRAY 或者 STRUCT 中的元素,或者用於 MAP 中鍵值對之間的分割,
在 CREATE TABLE 語句中也可使用八進制編碼 \002 表示
^C 用於 MAP 中鍵和值之間的分割,在 CREATE TABLE 語句中也可使用八進制編碼 \003 表示

使用示例以下:

CREATE TABLE page_view(viewTime INT, userid BIGINT)
 ROW FORMAT DELIMITED
   FIELDS TERMINATED BY '\001'
   COLLECTION ITEMS TERMINATED BY '\002'
   MAP KEYS TERMINATED BY '\003'
 STORED AS SEQUENCEFILE;

5、存儲格式

5.1 支持的存儲格式

Hive 會在 HDFS 爲每一個數據庫上建立一個目錄,數據庫中的表是該目錄的子目錄,表中的數據會以文件的形式存儲在對應的表目錄下。Hive 支持如下幾種文件存儲格式:

格式 說明
TextFile 存儲爲純文本文件。 這是 Hive 默認的文件存儲格式。這種存儲方式數據不作壓縮,磁盤開銷大,數據解析開銷大。
SequenceFile SequenceFile 是 Hadoop API 提供的一種二進制文件,它將數據以<key,value>的形式序列化到文件中。
這種二進制文件內部使用 Hadoop 的標準的 Writable 接口實現序列化和反序列化。它與 Hadoop API 中的 MapFile 是互相兼容的。
Hive 中的 SequenceFile 繼承自 Hadoop API 的 SequenceFile,不過它的 key 爲空,使用 value 存放實際的值,
這樣是爲了不 MR 在運行 map 階段進行額外的排序操做。
RCFile RCFile 文件格式是 FaceBook 開源的一種 Hive 的文件存儲格式,首先將表分爲幾個行組,
對每一個行組內的數據按列存儲,每一列的數據都是分開存儲。
ORC Files ORC 是在必定程度上擴展了 RCFile,是對 RCFile 的優化。
Avro Files Avro 是一個數據序列化系統,設計用於支持大批量數據交換的應用。
它的主要特色有:支持二進制序列化方式,能夠便捷,快速地處理大量數據;
動態語言友好,Avro 提供的機制使動態語言能夠方便地處理 Avro 數據。
Parquet Parquet 是基於 Dremel 的數據模型和算法實現的,面向分析型業務的列式存儲格式。
它經過按列進行高效壓縮和特殊的編碼技術,從而在下降存儲空間的同時提升了 IO 效率。

以上壓縮格式中 ORC 和 Parquet 的綜合性能突出,使用較爲普遍,推薦使用這兩種格式。

5.2 指定存儲格式

一般在建立表的時候使用 STORED AS 參數指定:

CREATE TABLE page_view(viewTime INT, userid BIGINT)
 ROW FORMAT DELIMITED
   FIELDS TERMINATED BY '\001'
   COLLECTION ITEMS TERMINATED BY '\002'
   MAP KEYS TERMINATED BY '\003'
 STORED AS SEQUENCEFILE;

各個存儲文件類型指定方式以下:

  • STORED AS TEXTFILE
  • STORED AS SEQUENCEFILE
  • STORED AS ORC
  • STORED AS PARQUET
  • STORED AS AVRO
  • STORED AS RCFILE

6、內部表和外部表

內部表又叫作管理表 (Managed/Internal Table),建立表時不作任何指定,默認建立的就是內部表。想要建立外部表 (External Table),則須要使用 External 進行修飾。 內部表和外部表主要區別以下:

內部表 外部表
數據存儲位置 內部表數據存儲的位置由 hive.metastore.warehouse.dir 參數指定,默認狀況下表的數據存儲在 HDFS 的 /user/hive/warehouse/數據庫名.db/表名/ 目錄下 外部表數據的存儲位置建立表時由 Location 參數指定;
導入數據 在導入數據到內部表,內部表將數據移動到本身的數據倉庫目錄下,數據的生命週期由 Hive 來進行管理 外部表不會將數據移動到本身的數據倉庫目錄下,只是在元數據中存儲了數據的位置
刪除表 刪除元數據(metadata)和文件 只刪除元數據(metadata)

參考資料

  1. Hive Getting Started
  2. Hive SQL 的編譯過程
  3. LanguageManual DDL
  4. LanguageManual Types
  5. Managed vs. External Tables

更多大數據系列文章能夠參見 GitHub 開源項目大數據入門指南

相關文章
相關標籤/搜索