Hive ORC檔案儲存格式

2021-09-08 13:56:49 字數 3953 閱讀 1315

orc檔案格式是從hive-0.11版本開始的。關於orc檔案格式的官方文件,以及基於官方文件的翻譯內容這裡就不贅述了,有興趣的可以仔細研究了解一下。本文接下來根據**《major technical advancements in apache hive》中的內容進行深入的研究。

orc的全稱是(optimized record columnar),使用orc檔案格式可以提高hive讀、寫和處理資料的能力。orc在rcfile的基礎上進行了一定的改進,所以與rcfile相比,具有以下一些優勢: 

- 1、orc中的特定的序列化與反序列化操作可以使orc file writer根據資料型別進行寫出。 

- 2、提供了多種rcfile中沒有的indexes,這些indexes可以使orc的reader很快的讀到需要的資料,並且跳過無用資料,這使得orc檔案中的資料可以很快的得到訪問。 

- 3、由於orc file writer可以根據資料型別進行寫出,所以orc可以支援複雜的資料結構(比如map等)。 

- 4、除了上面三個理論上就具有的優勢之外,orc的具體實現上還有一些其他的優勢,比如orc的stripe預設大小更大,為orc writer提供了乙個memory manager來管理記憶體使用情況。 

圖1-orc檔案結構圖

在orc格式的hive表中,記錄首先會被橫向的切分為多個stripes,然後在每乙個stripe內資料以列為單位進行儲存,所有列的內容都儲存在同乙個檔案中。每個stripe的預設大小為256mb,相對於rcfile每個4mb的stripe而言,更大的stripe使orc的資料讀取更加高效。 

對於複雜資料型別,比如map,orc檔案會將乙個複雜資料型別字段解析成多個子欄位。下表中列舉了orc檔案中對於複雜資料型別的解析

data type

chile columns

array

乙個包含所有陣列元素的子字段

map兩個子欄位,乙個key欄位,乙個value欄位

struct

每乙個屬性對應乙個子欄位

union

每乙個屬性對應乙個子欄位

當欄位型別都被解析後,會由這些字段型別組成乙個欄位樹,只有樹的葉子節點才會儲存表資料,這些葉子節點中的資料形成乙個資料流,如上圖中的data stream。 

為了使orc檔案的reader更加高效的讀取資料,欄位的metadata會儲存在meta stream中。在字段樹中,每乙個非葉子節點記錄的就是欄位的metadata,比如對乙個array來說,會記錄它的長度。下圖根據表的字段型別生成了乙個對應的字段樹。 

圖二-欄位樹結構圖 

在hive-0.13中,orc檔案格式只支援讀取指定字段,還不支援只讀取特殊字段型別中的指定部分。 

使用orc檔案格式時,使用者可以使用hdfs的每乙個block儲存orc檔案的乙個stripe。對於乙個orc檔案來說,stripe的大小一般需要設定得比hdfs的block小,如果不這樣的話,乙個stripe就會分別在hdfs的多個block上,當讀取這種資料時就會發生遠端讀資料的行為。如果設定stripe的只儲存在乙個block上的話,如果當前block上的剩餘空間不足以儲存下乙個strpie,orc的writer接下來會將資料打散儲存在block剩餘的空間上,直到這個block存滿為止。這樣,下乙個stripe又會從下乙個block開始儲存。 

在orc檔案中新增索引是為了更加高效的從hdfs讀取資料。在orc檔案中使用的是稀疏索引(sparse indexes)。在orc檔案中主要有兩種用途的索引,乙個是資料統計(data statistics)索引,乙個是位置指標(position pointers)索引。

orc reader用這個索引來跳過讀取不必要的資料,在orc writer生成orc檔案時會建立這個索引檔案。這個索引中統計的資訊主要有記錄的條數,記錄的max, min, sum值,以及對text型別和binary型別欄位還會記錄其長度。對於複雜資料型別,比如array, map, struct, union,它們的子字段中也會記錄這些統計資訊。 

在orc檔案中,data statistics有三個level。 

(1)file level statistics 

在orc檔案的末尾會記錄檔案級別的統計資訊,會記錄整個檔案中columns的統計資訊。這些資訊主要用於查詢的優化,也可以為一些簡單的聚合查詢比如max, min, sum輸出結果。 

(2)stripe level statistics 

orc檔案會儲存每個欄位stripe級別的統計資訊,orc reader使用這些統計資訊來確定對於乙個查詢語句來說,需要讀入哪些stripe中的記錄。比如說某個stripe的字段max(a)=10,min(a)=3,那麼當where條件為a >10或者a <3時,那麼這個stripe中的所有記錄在查詢語句執行時不會被讀入。 

(3)index group level statistics 

為了進一步的避免讀入不必要的資料,在邏輯上將乙個column的index以乙個給定的值(預設為10000,可由引數配置)分割為多個index組。以10000條記錄為乙個組,對資料進行統計。hive查詢引擎會將where條件中的約束傳遞給orc reader,這些reader根據組級別的統計資訊,過濾掉不必要的資料。如果該值設定的太小,就會儲存更多的統計資訊,使用者需要根據自己資料的特點權衡乙個合理的值。 

當讀取乙個orc檔案時,orc reader需要有兩個位置資訊才能準確的進行資料讀取操作。 

(1)metadata streams和data streams中每個group的開始位置 

由於每個stripe中有多個group,orc reader需要知道每個group的metadata streams和data streams的開始位置。圖1中右邊的虛線代表的就是這種pointer。 

(2)stripes的開始位置 

由於乙個orc檔案可以包含多個stripes,並且乙個hdfs block也能包含多個stripes。為了快速定位指定stripe的位置,需要知道每個stripe的開始位置。這些資訊會儲存在orc file的file footer中。如圖1中間位置的虛線所示。

當orc writer寫資料時,會將整個stripe儲存在記憶體中。由於stripe的預設值一般比較大,當有多個orc writer同時寫資料時,可能會導致記憶體不足。為了現在這種併發寫時的記憶體消耗,orc檔案中引入了乙個記憶體管理器。在乙個map或者reduce任務中記憶體管理器會設定乙個閾值,這個閾值會限制writer使用的總記憶體大小。當有新的writer需要寫出資料時,會向記憶體管理器註冊其大小(一般也就是stripe的大小),當記憶體管理器接收到的總註冊大小超過閾值時,記憶體管理器會將stripe的實際大小按該writer註冊的記憶體大小與總註冊記憶體大小的比例進行縮小。當有writer關閉時,記憶體管理器會將其註冊的記憶體從總註冊記憶體中登出。

引數名預設值

說明hive.exec.orc.default.stripe.size

256*1024*1024

stripe的預設大小

hive.exec.orc.default.block.size

256*1024*1024

orc檔案在檔案系統中的預設block大小,從hive-0.14開始

hive.exec.orc.dictionary.key.size.threshold

0.8string型別字段使用字典編碼的閾值

hive.exec.orc.default.row.index.stride

10000

stripe中的分組大小

hive.exec.orc.default.compress

zlib

orc檔案的預設壓縮方式

hive.exec.orc.skip.corrupt.data

false

遇到錯誤資料的處理方式,false直接丟擲異常,true則跳過該記錄

更多引數可參看:

Hive ORC檔案儲存格式(續)

本文在hive orc檔案儲存格式的理論基礎上,進一步分析乙個實際的hive orc表中的資料儲存形式。庫名 表名 fileformat.test orc 字段型別 category id string product id intbrand id intprice double category ...

HIVE檔案儲存格式

hive檔案儲存格式包括以下幾類 textfile sequencefile rcfile orcfile 其中textfile為預設格式,建表時不指定預設為這個格式,匯入資料時會直接把資料檔案拷貝到hdfs上不進行處理。sequencefile,rcfile,orcfile格式的表不能直接從本地檔...

Hive RCFile檔案儲存格式

在新建hive表時,可以使用stored as rcfile來指定hive檔案的儲存方式為rcfile。下圖是乙個rcfile的檔案結構形式。從上圖可以看出 1 一張表可以包含多個hdfs block。2 在每個block中,rcfile以行組 row group,類似於orc中的stripe 為單...