我在整理Hive的存盤格式和壓縮格式,本來打算一篇發出來,結果其中一小節就有很多內容,于是打算寫成Hive存盤格式和壓縮格式系列,
本節主要講一下Hive存盤格式最早的典型的列式存盤格式RCFile,
綜述
RCFile(Record Columnar File)檔案格式是FaceBook開源的一種Hive的檔案存盤格式,遵循“首先水平磁區,然后垂直磁區”的設計理念,首先將資料水平分為幾個行組,這樣每一行資料就可以保證存盤在同一個集群節點,然后對每個行組內資料進行垂直劃分,按列存盤,
下面通過檔案存盤結構來引入RCFile的詳細介紹,檔案存盤結構主要有行存盤結構,列存盤結構和混合存盤結構,
1.行存盤存盤結構
行存盤(row-store)結構在傳統的一刀切的資料庫系統 中占主導地位,使用這種結構,關系記錄被組織在一個n元存盤模型中,一個記錄的所有欄位都按它們出現的順序依次填充,記錄被連續地放置在一個磁盤頁中,下圖給出了一個示例,展示了如何在HDFS塊中的行存盤結構中放置表,
下圖為HDFS block中基于行存盤示意圖

1.1 優點
行存盤保證了相同記錄的所有欄位都在同一個集群節點,具備快速資料加載和動態負載的高適應能力,
1.2 缺點
在當查詢僅僅針對所有列中少數幾列時,它就不能直接定位到所需列而跳過不需要的列,不太滿足快速的查詢回應時間的要求,由于混合著不同資料域的列,行存盤不易獲得一個極高的壓縮比,
盡管通過熵編碼和利用列相關性的行存盤可以有比列存盤更好的資料壓縮比,但這同樣也會因為復雜的資料存盤實作導致很高的資料解壓縮開銷,
2.列式存盤存盤結構
列式存盤(column-group)是基于讀取優化的資料倉庫系統的面向列的存盤模型,在列式存盤中,一個關系被垂直劃分為幾個子集,有兩種存盤方案,
第一種是每一列放在一個子集中,常見一些實驗系統中,我們稱之為列存盤(column-store),
第二種是將每個關系的所有列組織成不同的列組,并且通常允許多個列組之間的列重復,Hbase的列簇設計就是一種類似方案,我們稱之為列組(column-group),
也就是說我們通常所說的列式存盤其實是列組存盤,
如下圖,列A和列B存盤在同一個列組中,而列C和列D存盤在兩個獨立的列組中,
下圖為HDFS block中基于列存盤示意圖

2.1 優點
列式結構使得在查詢時能夠直接讀取需要的列而避免不必要的列的讀取,
通過壓縮同一資料域內的每個列,可以有一個更好的壓縮比,
2.2 缺點
由于元組重構的高開銷,不能提供基于Hadoop系統的快速查詢處理能力,
缺點詳細解釋版本:列存盤不能保證同一記錄中所有的欄位都位于同一個集群節點,如上圖,一個記錄的四個欄位存盤在三個HDFS塊中,它們可能位于不同的節點,因此,查詢一條完整的記錄將導致多個集群節點之間的網路進行大量的資料傳輸,必然會慢,集群中過多的網路傳輸是一個集群增長的瓶頸,如果可能的話應該避免,
列組和物化視圖類似(提前加載好查詢資料),因此它可以避免記錄重構的開銷(同一個塊中),但是,它不能滿足快速適應動態作業負載的要求,除非將所有的查詢可能都構建為列組,這會有極高的資料冗余,
關于物化視圖,開源資料庫postgresql 做了很好的支持,有機會單獨開篇講一講,
3.RCFile存盤思想-混合存盤(PAX)
混合存盤的核心,先水平磁區,再垂直磁區,
它采用了一種混合放置結構,旨在提高CPU快取性能,對于來自不同列多個值的記錄,PAX不是將這些欄位值放在不同的磁盤頁中,而是將它們放在單個磁盤頁中,以保存用于記錄重構的其他操作,
在每個磁盤頁面中,PAX使用頁面頭來存盤一個指向指標,該指標指向一個用來存盤屬于每個列的所有欄位的迷你頁面,
3.1 優點
與行存盤區一樣,PAX對各種動態查詢作業負載具有很強的自適應能力,
3.2 缺點
由于PAX主要是為了提高加載資料集的CPU快取利用率的性能,因此PAX不能直接滿足高存盤空間利用率和快速查詢處理速度的要求,原因有以下三個方面:
-
PAX與資料壓縮無關,僅僅提供了一個執行列級資料壓縮的可能,而資料壓縮對于快取優化不是必需的,但對于大型資料處理系統非常重要,
-
PAX不能提高I/O性能,因為它不會改變頁面的實際內容,這限制了我們實作在大規模增長的資料集上對大量磁盤掃描進行快速查詢處理的目標,
-
受傳統DBMS引擎中的頁面級資料操作的限制,PAX使用一個固定的頁面作為資料記錄組織的基本單元,通過如此固定的大小,PAX無法有效地存盤大型資料處理系統中不同的資料資源型別,
4.RCFile
RCFile應用了PAX中的“首先水平磁區,然后垂直磁區”的概念,結合了行存盤和列存盤的優點,從行存盤的角度來看,RCFile保證了同一行資料位于同一節點,從列存盤的角度來看,RCFile可以利用列級的資料壓縮,并跳過不必要的列讀取,
那么它是怎么做到的呢?我們且看下文,RCFile的五個特性,
4.1 資料組成
如下圖,在每個HDFS塊中,RCFile使用行組作為基本單位來組織資料,存盤在HDFS塊中的所有記錄都被劃分成了行組,對于一個表,所有的行組大小都相同,一個HDFS塊只能有一個或者多個行組,
一個行組由三部分組成,第一部分是行組開頭的同步標記,用于指向在一個HDFS塊兩個連續的行組,第二部分是行組的元資料頭,存盤此行組中有多少記錄,每列有多少位元組以及某列中每個欄位中有多少位元組等資訊,第三部分是表資料,實際上是一個列存盤區,同一列中所有欄位都連續的存盤在一起,如下圖中,首先存盤A列所有資料,然后存盤B列所有資料,
HDFS block上RCFile存盤示意圖

4.2 資料壓縮
RCFile在資料壓縮上是將每個行組的元資料頭部分和表資料部分分別壓縮,
元資料頭使用RLE演算法進行壓縮,方便快速查找資料元資料資訊,
RLE演算法詳解,有空寫(課本資料結構一書中有介紹),
表資料部分沒有作為一個整體進行壓縮,而是將每一列都單獨使用Gzip進行壓縮,以獲得更高的壓縮比,
RCFile允許擴展可選擇每一列根據不同資料型別和資料分布來使用不同的壓縮演算法,使其壓縮達到最佳,這是RCFile的優化和發展方向,但似乎有點過于笨重,
4.3 資料寫入
RCFile存盤方式導致了它不支持資料修改,由此Hive使用RCFile存盤是不支持資料更新,只支持資料覆寫或者資料追加模式,
4.4 資料讀取和懶解壓縮
上文提到表資料壓縮使用Gzip,Gzip具有高壓縮比,但是解壓縮也有比較高的開銷,那這個是如何避免的呢?
通過只讀取給定查詢的元資料頭和行組中所需要的列(跳過不需要的列)并且結合懶解壓縮方式(如果該行列資料沒有所需要的欄位值,則不解壓縮該資料)來獲得I/O優勢,降低解壓縮開銷,本質上并沒有提升I/O性能,只是少讀了,
4.5 行組大小
合適的行組大小能夠提升資料讀取性能,降低資料存盤,顯然它由兩個因素決定,壓縮比和資料讀取性能,
大的行組能夠提升壓縮比,降低表存盤,但是可能會損害資料讀取性能,小的行組能夠提升資料讀取性能,但是卻損失了存盤空間,
RCFile默認設定是4MB,用戶可以通過引數調節行組大小,
需要說明的是,RCFile在map階段從 遠端拷貝仍然是拷貝整個資料塊,并且拷貝到本地目錄后RCFile并不是真正直接跳過不需要的列,并跳到需要讀取的列, 而是通過掃描每一個row group的頭部定義來實作的,但是在整個HDFS Block 級別的頭部并沒有定義每個列從哪個row group起始到哪個row group結束,所以在讀取所有列的情況下,RCFile的性能反而沒有SequenceFile高,
4.6 Hive使用RCFile示例:
-- 創建RCFile格式表
create table if not exists rcfile_temp(
id int,
name string,
gender int,
remark string
)
row format delimited fields terminated by ','
stored as rcfile;
-- 插入資料(自帶壓縮格式,就不需要使用壓縮引數了)
insert overwrite table rcfile_temp
select * from rcfile_temp;
RCFile還提供了豐富的API,支持開發者進行二次參考,這里就不一一詳述了,
下期預告,講講和RCFile的優化版ORC File,具體是怎樣發揚了RCFile的優點,又是怎樣解決了所有列讀取的性能問題,
上一篇:什么是hive的靜態磁區和動態磁區,它們又有什么區別呢?hive動態磁區詳解
按例,我的個人公眾號:魯邊社,歡迎關注
魯邊社

后臺回復關鍵字 hive,隨機贈送一本魯邊備注版珍藏大資料書籍,
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/501848.html
標籤:其他
