Hive存儲格式之RCFile詳解,RCFile的過去現在和未來

我在整理Hive的存儲格式和壓縮格式,本來打算一篇發出來,結果其中一小節就有很多內容,於是打算寫成Hive存儲格式和壓縮格式系列。

本節主要講一下Hive存儲格式最早的典型的列式存儲格式RCFile。

綜述

RCFile(Record Columnar File)文件格式是FaceBook開源的一種Hive的文件存儲格式,遵循“首先水平分區,然後垂直分區”的設計理念。首先將數據水平分爲幾個行組,這樣每一行數據就可以保證存儲在同一個集羣節點,然後對每個行組內數據進行垂直劃分,按列存儲。

下面通過文件存儲結構來引入RCFile的詳細介紹。文件存儲結構主要有行存儲結構,列存儲結構和混合存儲結構。

1.行存儲存儲結構

行存儲(row-store)結構在傳統的一刀切的數據庫系統 中占主導地位。使用這種結構,關係記錄被組織在一個n元存儲模型中。一個記錄的所有字段都按它們出現的順序依次填充。記錄被連續地放置在一個磁盤頁中。下圖給出了一個示例,展示瞭如何在HDFS塊中的行存儲結構中放置表。

下圖爲HDFS block中基於行存儲示意圖
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,隨機贈送一本魯邊備註版珍藏大數據書籍。

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