ORC原理及查詢優化

Hive從0.11版本開始提供了ORC的文件格式,ORC文件不僅僅是一種列式文件存儲格式,最重要的是有著很高的壓縮比,并且對于MapReduce來說是可切分(Split)的。因此,在Hive中使用ORC作為表的文件存儲格式,不僅可以很大程度的節省HDFS存儲資源,而且對數據的查詢和處理性能有著非常大的提升,因為ORC較其他文件格式壓縮比高,查詢任務的輸入數據量減少,使用的Task也就減少了。

ORC文件是自描述的,它的元數據使用Protocol Buffers序列化,并且文件中的數據盡可能的壓縮以降低存儲空間的消耗,目前也被Spark SQL、Presto等查詢引擎支持,但是Impala對于ORC目前沒有支持,仍然使用Parquet作為主要的列式存儲格式。2015年ORC項目被Apache項目基金會提升為Apache頂級項目。

例如,與RCFile格式相比,ORC文件格式具有許多優點,例如:

  • 一個文件作為每個任務的輸出,這減少了NameNode的負載
  • 支持復雜的數據結構,Hive類型支持包括datetime,decimal和復雜類型(struct,list,map和union)
  • 三級索引,存儲在文件中的輕量級索引,能過濾掉沒在查找范圍內的數據塊,快速查詢到滿足條件的數據
  • 基于數據類型的塊模式壓縮,整數列的行程編碼,字符串列的字典編碼,減少了讀或寫所需的數據量
  • 分割的數據塊,使用單獨的RecordReaders并發讀取同一文件

由于ORC普遍應用于Apache大數據生態,了解其原理,有助于hive和presto查詢優化。

列式存儲

列式存儲可以提升OLAP查詢查詢性能,但是它是如何做到的呢?這就要從列式存儲的原理說起,從圖1中可以看到,相對于關系數據庫中通常使用的行式存儲,在使用列式存儲時每一列的所有元素都是順序存儲的。由此特點可以給查詢帶來如下的優化:

1)查詢的時候不需要掃描全部的數據,而只需要讀取每次查詢涉及的列,這樣可以將I/O消耗降低N倍,另外可以保存每一列的統計信息(min、max、sum,字符類型數據長度等),實現部分的謂詞下推。

2)由于每一列的成員都是同構的,可以針對不同的數據類型使用更高效的數據壓縮算法,進一步減小I/O。

3)由于每一列的成員的同構性,可以使用更加適合CPU pipeline的編碼方式,減小CPU的緩存失效。

image

文件結構

從下圖可以看到ORC文件結構

ORC文件的元數據一個ORC文件會被分成多個stripe,而且文件的元數據中有每個字段的統計信息(min/max,sum,hasNull等等),這就為ORC的查詢優化做好了基礎準備。

image

整個文件從下往上分成幾個部分:

1)Postscript: 提供了解釋文件其余部分的必要信息,包括文件的頁腳和元數據部分的長度,文件的版本以及使用的常規壓縮類型(例如,none,zlib,LZO,LZ4,ZSTD或snappy)

2)File Footer: 包含文件正文的布局,類型架構信息,行數以及每個列的統計信息。

3)Stripe條帶數據塊:文件正文分為條帶。每個條帶都是自包含的,只能使用自己的字節與文件的Footer和Postscript結合使用。每個條帶僅包含整行,因此行不會跨越條帶邊界。Stripes有三個部分:條帶中行的一組索引,數據本身和條帶頁腳。索引和數據部分都按列分割,因此只需要讀取所需列的數據。

4)列統計:列統計信息的目標是,對于每個列,編寫器記錄計數并根據其他有用字段的類型進行記錄。對于大多數原始類型,它記錄最小值和最大值; 對于數字類型,它還存儲總和。從Hive 1.1.0開始,列統計信息還將通過設置hasNull標志來記錄行組中是否存在任何空值。ORC的謂詞下推使用hasNull標志來更好地回答'IS NULL'查詢。真實列數據塊,其中又分為Index data( 記錄每列的索引信息),Raw Data(記錄原始數據),Stripe Footer(記錄每列的統計信息,min/max/sum等)。

Stripe在默認情況下64MB。文件中的條帶彼此獨立,形成分布式工作的自然單元。在每個條帶中,列彼此分開,因此Reader只能讀取所需的列。

三級索引

ORC在每個文件中提供三級索引:

  • 文件級別 - 有關整個文件中每列中的值的統計信息

  • stripe條帶級別 - 有關每個條帶的每列中的值的統計信息

  • 行級別 (行組)- 條帶中每組10,000行(默認值)的每列值的統計信息

文件和條帶級別列統計信息位于文件頁腳中,因此可以輕松訪問它們以確定是否需要讀取文件的其余部分。行級索引包括每個行組的列統計信息和搜索行組開頭的位置。

列統計信息始終包含值的計數以及是否存在空值。大多數其他原始類型包括最小值和最大值,對于數字類型,則包括總和。從Hive 1.2開始,索引可以包括bloom過濾器,它提供了更具選擇性的過濾器。

索引工作原理
1)假如我的查詢過濾條件為WHERE id = 0;在Map Task讀到一個ORC文件時,首先從文件的統計信息(一級索引)中看看id字段的min/max值,如果0不包含在內,那么跳過該文件
2)如果在這個文件中,那么繼續查看每個stripe中id字段的min/max值(二級索引),如果0不包含在內,那么跳過在stripe
3)如果在該stripe中,則繼續匹配行組中的min/max值(三級索引),如果0不包含在內,那么跳過該行組。如果0包含在內min和max范圍內,則利用布隆過濾器再次判斷是否一定不在內,不在內則繼續跳過該行組。

這種索引通常用于數值型字段的查詢過濾優化上。

布隆過濾器

本質上布隆過濾器是一種數據結構,比較巧妙的概率型數據結構(probabilistic data structure),布隆過濾器是一個 bit 向量或者說 bit 數組和一組hash函數組成。特點是高效地插入和查詢,可以用來告訴你 “某樣東西一定不存在或者可能存在”。

布隆過濾器可以應用在各種類型字段上,包括字符串和二進制。

謂詞下推

謂詞下推(predicate pushdown)屬于邏輯優化。優化器可以將謂詞過濾下推到數據源,從而使物理執行跳過無關數據。在邏輯層面可以理解為利用where 條件中的過濾條件將無用的數據進行篩選掉最終得到需要的行列。
在ORC中表現為:
1)列式存儲可以容易過濾掉不需要的列數據
2)利用三級索引中的統計信息可以跳過不需要的文件,條帶塊或行組

Hive建表優化

Hive中建表使用ORC存儲格式時,ORC默認會開啟索引。這樣可以充分利用ORC索引減少數據掃描時間。

  • 建議ETL過程中將where語句后經常過濾的字段預先排序后插入數據表
  • 建議在建ORC表時對于where語句后經常過濾的字段添加在布隆過濾器中
CREATE TABLE bdc_dm.res_category_orc(
channel_id1 int comment '1級渠道id',
province string COMMENT '省',
city string comment '市', 
uv int comment 'uv'
)
comment 'example'
partitioned by (landing_date int COMMENT '日期:yyyymmdd')
row format delimited fields terminated by '\t'
stored as orc 
TBLPROPERTIES (
"orc.compress"="SNAPPY",
'orc.create.index'='true',
"orc.bloom.filter.columns"="channel_id1,uv",
'orc.bloom.filter.fpp'='0.05',
'orc.stripe.size'='10485760',
'orc.row.index.stride'='10000'
);

上面用到的參數見下表,有些含有默認值,可以不用設置。由于ZLIB壓縮性能不如Snappy,ORC文件壓縮器一般設置為snappy。

參數名 默認值 含義
orc.compress ZLIB 高級壓縮器 = {NONE, ZLIB, SNAPPY}
orc.compress.size 262,144 壓縮塊大小
orc.stripe.size 67,108,864 每個stripe塊中的字節數
orc.row.index.stride 10,000 行組大小
orc.create.index true 是否創建索引
orc.bloom.filter.columns "" 逗號分隔的列名列表,用于創建bloom過濾器
orc.bloom.filter.fpp 0.05 布隆過濾器的假陽性概率 (must >0.0 and <1.0)

參考文檔

https://orc.apache.org/docs/index.html

https://orc.apache.org/specification/ORCv1/

http://www.lxweimin.com/p/2104d11ee0a2

https://cwiki.apache.org/confluence/display/Hive/LanguageManual+ORC

http://lxw1234.com/archives/2016/04/632.htm

http://lxw1234.com/archives/2016/04/630.htm

https://www.cnblogs.com/ITtangtang/p/7677912.html

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。