# 5-3 Hive – A Petabyte Scale Data Warehouse Using Hadoop
## Introduction
:::danger
資料量成長數度大,而Hadoop又沒有很好的表達方式使終端使用者不好使用
:::
* Hadoop沒有像是SQL這種表示方式,使用者撰寫程式要很花時間
* Hive將table, colouns, rows, partitions和SQL子集帶到分結構化的Hadoop中
## Data Model, Type System and Query Language
:::danger
介紹Hive的model和其支援的type及QL
:::
* 具有易懂的database觀念像是tables, columns, rows, partitions
* 支援主要的一些primitive types: integers, floats, doubles, strings,也有更複雜的如maps, lists, structs
* 可以嵌套來構成更複雜的型態
* 使用者也可以自己定義type和function
### Data Model and Type System
* Primitive types:
* Integers:
* biging(8 bytes)
* int(4 bytes)
* smallint(2 bytes)
* tinyint(1 byte)
* 全部integer types皆為有號
* Floating pointer numbers:
* float(single precision)
* double(double precision)
* String
* Complex types:
* Associative arrays:
* map<key-type, value-type>
* Lists:
* list\<element-tpye>
* Structs:
* struct<file-name: field-type, ...>
* 可以為arbitrary
* Example: list<map<string, struct<p1:int, p2:int>>
* 建立table的schema example
```
CREATE TABLE t1(st string, f1 float, li list<map<string, struct<p1:int, p2:int>>);
```
* SerDes
* 默認使用序列化器和反序列化器(SerDes)來讀寫表中的數據
* 序列化將數據轉換成便於儲存或傳輸的格式
* 反序列化則是將數據重新轉換回可讀格式
* Hive中使用的數據可能來自外部來源或是舊數據格式
* Hive將這些屬聚集成進來,無需將其轉換Hive兼容格式,省時間
* 需要透過創建自定義jar文件來集成到Hive中來兼容數據類型和型態,其中jar必須實作ObjectInspector interface
* 此jar使Hive能夠處理任意數據格式,如處理原生類型資料
* 建立客制化Serde的table
```
add jar/jars/myformat.jar;
CREATE TABLE t2
ROW FORMAT SERDE 'com.myformat.MySerDe';
```
### Query Language
* Hive提供了一種Query Language叫HiveQL,為SQL的子集合以及一些額外的延伸
* 其中包括多種join,products, group by, aggregation, union, create等好用的query都與SQL相同
* 其中有一些限制:
1. only equality predicates are supported in a join predicate abd the joins have to be specified using the ANSI join syntax. 如:
```
SELECT t1.a1 as c1, t2.b1 as c2
FROM t1 JOIN t2 ON (t1.a2 = t2.b2);
```
而不是傳統SQL的
```
SELECT t1.a1 as c1, t2.b1 as c2
FROM t1, t2
WHERE t1.a2 = t2.b2;
```
2. Hive不支援插入到現有table或data partition,所有insert都會覆蓋掉現有資料,如:
```
INSERT OVERWRITE TABLE t1
SELECT * FROM t2;
```
* 這些限制都不是問題
* 另外也有一些額外的語法:
* 以map-reduce程式表示的分析,使進階使用者可以用map來表達複雜的邏輯,如:
```
FROM t1
INSERT OVERWRITE TABLE t2
SELECT t3.c2, count(1)
FROM t3
WHERE t3.c1 <= 20
GROUP BY t3.c2
INSERT OVERWRITE DIRECTORY '/output_dir'
SELECT t3.c2, avg(t3.c1)
FROM t3
WHERE t3.c1 > 20 AND t3.c1 <= 30
GROUP BY t3.c2
INSERT OVERWRITE LOCAL DIRECTORY '/home/dir'
SELECT t3.c2, sum(t3.c1)
FROM t3
WHERE t3.c1 > 30
GROUP BY t3.c2;
```
## Data Storage, Serde and File Format
### Data Storage
* Table
* table: 以目錄的結構存在HDFS上,table可以更近一步劃分為partition,每個partition存在表目錄的子目錄中。
* 可以將table根據一些關鍵字來進行分區,每個分區作為一個子目錄存在
* Example:
* 指定partitionby來創近partition table
```
CREATE TABLE test_part(c1 string, c2 int)
PARTITIONED BY (ds string, hr int);
```
* 將partition加入table
```
INSERT OVERWRITE TABLE
test_part PARTITION(ds='2009-01-01', hr=12)
SELECT * FROM t;
ALTER TABLE test_part
ADD PARTITION(ds='2009-02-02', hr=11);
```
* Bucket:
* 存在partition或是表目錄中的文件,用於更近一步細分數據
* 創建表時可以指定bucket的數量以及分配的列
* Example: 查詢32個bucket中第二個bucket
```
SELECT * FROM t TABLESAMPLE(2 OUT OF 32);
```
* 存儲配置
* 用戶在創建瞟時可以選擇數據的存儲路徑,也可以指定如何根據table中的某些自斷來進行分區
### Serde
* 自定義SerDe:用戶可以客製化Serializer/Deserializer來控制如何將結構化數據映射到存儲系統,以及如何存儲這些數據
* 處理各種來源的數據:支援通過定義行和字段的分隔符號來解析不同的文本數據格式
* Example:
```
# 指定table test_delimited的資料並使用'\002'(ctrl-B, ascii代碼2)列作為分隔符,並使用'\012'(ctrl-L, ascii代碼12)行作為分隔符
CREATE TABLE test_delimited(c1 string, c2 int)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\002'
LINES TERMINATED BY '\012';
```
也可以指定不同分隔符號來分隔list(collection)的各種元素:
```
CREATE TABLE test_delimited2(c1 string, c2 list<map<string, int>>)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\002'
COLLECTION ITEMS TERMINATED BY '\003'
MAP KEYS TERMINATED BY '\004';
```
* 正則表達式SerDe:也可以透過正則表達式來解析數據,常用於處理log
* Example: 用正規表達式解釋apache log
```
# output.format.string指示從正規表示式中的群組匹配建構列欄位
# 使用WITH SERDEPROPERTIES子句將任意key-value pair傳遞到serde
add jar 'hive_contrib.jar';
CREATE TABLE apachelog(
host string,
identity string,
user string,
time string,
request string,
status string,
size string,
referer string,
agent string)
ROW FORMAT SERDE
'org.apache.hadoop.hive.contrib.serde2.RegexSerDe'
WITH SERDEPROPERTIES(
'input.regex' = '([^ ]*) ([^ ]*) ([^ ]*) (-|\\[[^\\]]*\\]) ([^
\"]*|\"[^\"]*\") (-|[0-9]*) (-|[0-9]*)(?: ([^ \"]*|\"[^\"]*\") ([^
\"]*|\"[^\"]*\"))?',
'output.format.string' = '%1$s %2$s %3$s %4$s %5$s %6$s
%7$s %8$s %9$s');
```
### File Format
* 支持多種文件格式儲存,也可以自己客製化格式
* RCFile格式:Row columner File格式,可以只查詢被涉及的row,提升查詢性能
* Example: 新增文件格式並關聯到table:
```
CREATE TABLE dest1(key INT, value STRING)
STORED AS
INPUTFORMAT
'org.apache.hadoop.mapred.SequenceFileInputFormat'
OUTPUTFORMAT
'org.apache.hadoop.mapred.SequenceFileOutputFormat'
```
## System Architecture and Components
### Hive System Architecture

### 主要components
* Metastore:
* 一個關鍵的組件,負責儲存系統有關table、row、partition的metadata,使Hive能夠快速訪問和管理HDFS上的數據結構
* Driver:
* 用戶與Hive交互的首要接口,負責處理用戶提交的HiveQL查詢,解析查詢,並在執行前進行必要的優化。
* 在查詢執行時Driver會維護相關的會話訊息和統計數據,以管理查詢的生命週期
* Query Compiler:
* 將HiveQL編譯成一個有向無環圖(DAG),表示MapReduce作業的順序以及依賴關係。
* 使用一系列優化來不斷改善此DAG,使其更高效進行查詢
* 優化的Flowchart:

* Execution Engine:
* 按依賴順序執行編譯器產生的MapReduce任務,與底層的Hadoop實例交互,使用Hadoop的資源管理器來調度和執行任務。
* HiveServer:
* 提供一個server端接口供使用者或應用程式連接到Hive
* Client Components:
* 包括命令行界面(CLI)、Web用戶界面和JDBC/ODBC驅動程序,讓用戶能使用不同前端與Hive交互。
* Extensibility Interfaces:
* 允許用戶擴展和客制Hive的功能,處理更複雜的數據結構
* 包括先前描述的SerDe和ObjectInspector接口,以及允許用戶定義自己的自定義函數(UDF)和用戶定義聚合函數(UDAF)的接口 。
## Hive Usage in Facebook
* 規模:
* 目前數據倉庫有700TB的數據,考慮到三倍數據冗余,實際在Hadoop上原始空間到達2.1PB
* 每天新增5TB的壓縮數據,經過冗余後約15TB
* 日常作業:
* 每天提交超過7500個作業到集群
* 每天處理超過75TB的壓縮數據
* 使用情況:
* 超過一半的工作負載來自臨時查詢,其餘為報告dashboard
* 運營挑戰:
* 臨時用戶和報告用戶共享相同資源,導致運營上的顯著挑戰,特別是由於臨時工作的不可預測性
* 許多臨時工作沒有適當調整,因而消耗寶貴的集群資源,可能導致報告查詢信下降,而這些查詢往往是時間敏感的
* 資源調度在Hadoop中一直是一個薄弱點,目前看來唯一可行的解決方案似乎是為臨時查詢和報告查詢要維護不同的集群
* 作業多樣性:
* 每天運行的Hive作業範圍從簡單的匯總作業生成不同類型的滾動和立方體,到更高級的ML算法。
* 系統被新手用戶以及高級用戶使用
## Related Work
* 最近也有許多有關PB級別的資料處理系統:
* Scope:類似SQL的語言,位於 Microsoft 專有的 Cosmos 映射/歸約和分散式檔案系統之上
* Pig:允許使用者編寫聲明性腳本來處理資料
* Hive與這些不同,它提供了一個系統目錄,用於保存有關系統內表的metadata,使其能充當傳統倉庫,可以與MicroStrategy等標準報告工具互動ㄉ
* HadoopDB:重複使用Hive的大部分系統,不過它在每個節點中使用傳統的資料庫實例來儲存數據,而不是使用分散式檔案系統。
## Conclusoins and Future Work
* 持續擴充HiveQL來支援更全面的語法
* 基於成本和適應性來改進優化器
* 通過探索列式存儲和智能數據放置來改善性能
* 進行性能測試來提高Hadoop 20%的性能
* 發展多查詢優化技術