Apache ORC列式存儲(chǔ)格式
Apache ORC 文件格式是一種Hadoop生態(tài)圈中的列式存儲(chǔ)格式,它的產(chǎn)生早在2013年初,最初產(chǎn)生自Apache Hive,用于降低Hadoop數(shù)據(jù)存儲(chǔ)空間和加速Hive查詢速度。
ORC(OptimizedRC File)存儲(chǔ)源自于RC(RecordColumnar File)這種存儲(chǔ)格式,RC是一種列式存儲(chǔ)引擎,對(duì)schema演化(修改schema需要重新生成數(shù)據(jù))支持較差,而ORC是對(duì)RC改進(jìn),但它仍對(duì)schema演化支持較差,主要是在壓縮編碼,查詢性能方面做了優(yōu)化。RC/ORC最初是在Hive中得到使用,最后發(fā)展勢(shì)頭不錯(cuò),獨(dú)立成一個(gè)單獨(dú)的項(xiàng)目。Hive 1.x版本對(duì)事務(wù)和update操作的支持,便是基于ORC實(shí)現(xiàn)的(其他存儲(chǔ)格式暫不支持)。ORC發(fā)展到今天,已經(jīng)具備一些非常高級(jí)的feature,比如支持update操作,支持ACID,支持struct,array復(fù)雜類型。你可以使用復(fù)雜類型構(gòu)建一個(gè)類似于parquet的嵌套式數(shù)據(jù)架構(gòu),但當(dāng)層數(shù)非常多時(shí),寫起來非常麻煩和復(fù)雜,而parquet提供的schema表達(dá)方式更容易表示出多級(jí)嵌套的數(shù)據(jù)類型。
ORC原生是不支持嵌套數(shù)據(jù)格式的,而是通過對(duì)復(fù)雜數(shù)據(jù)類型特殊處理的方式實(shí)現(xiàn)嵌套格式的支持,例如對(duì)于如下的hive表:
CREATE TABLE `orcStructTable`( `name` string, `course` struct<course:string,score:int>, `score` map<string,int>, `work_locations` array<string>)
ORC格式會(huì)將其轉(zhuǎn)換成如下的樹狀結(jié)構(gòu)(ORC的schema結(jié)構(gòu)):
在ORC的結(jié)構(gòu)中這個(gè)schema包含10個(gè)column,其中包含了復(fù)雜類型列和原始類型的列,前者包括LIST、STRUCT、MAP和UNION類型,后者包括BOOLEAN、整數(shù)、浮點(diǎn)數(shù)、字符串類型等,其中STRUCT的孩子節(jié)點(diǎn)包括它的成員變量,可能有多個(gè)孩子節(jié)點(diǎn),MAP有兩個(gè)孩子節(jié)點(diǎn),分別為key和value,LIST包含一個(gè)孩子節(jié)點(diǎn),類型為該LIST的成員類型,UNION一般不怎么用得到。每一個(gè)Schema樹的根節(jié)點(diǎn)為一個(gè)Struct類型,所有的column按照樹的中序遍歷順序編號(hào)。
ORC只需要存儲(chǔ)schema樹中葉子節(jié)點(diǎn)的值,而中間的非葉子節(jié)點(diǎn)只是做一層代理,它們只需要負(fù)責(zé)孩子節(jié)點(diǎn)值得讀取,只有真正的葉子節(jié)點(diǎn)才會(huì)讀取數(shù)據(jù),然后交由父節(jié)點(diǎn)封裝成對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu)返回。
文件結(jié)構(gòu)
ORC 文件是以二進(jìn)制方式存儲(chǔ)的,所以是不可以直接讀取,ORC文件也是自解析的,它包含許多的元數(shù)據(jù),這些元數(shù)據(jù)都是同構(gòu)ProtoBuffer進(jìn)行序列化的。ORC的文件結(jié)構(gòu)入圖6,其中涉及到如下的概念:
ORC文件:保存在文件系統(tǒng)上的普通二進(jìn)制文件,一個(gè)ORC文件中可以包含多個(gè)stripe,每一個(gè)stripe包含多條記錄,這些記錄按照列進(jìn)行獨(dú)立存儲(chǔ),對(duì)應(yīng)到Parquet中的row group的概念。
文件級(jí)元數(shù)據(jù):包括文件的描述信息PostScript、文件meta信息(包括整個(gè)文件的統(tǒng)計(jì)信息)、所有stripe的信息和文件schema信息。
stripe:一組行形成一個(gè)stripe,每次讀取文件是以行組為單位的,一般為HDFS的塊大小,保存了每一列的索引和數(shù)據(jù)。
stripe元數(shù)據(jù):保存stripe的位置、每一個(gè)列的在該stripe的統(tǒng)計(jì)信息以及所有的stream類型和位置。
row group:索引的最小單位,一個(gè)stripe中包含多個(gè)row group,默認(rèn)為10000個(gè)值組成。
stream:一個(gè)stream表示文件中一段有效的數(shù)據(jù),包括索引和數(shù)據(jù)兩類。索引stream保存每一個(gè)row group的位置和統(tǒng)計(jì)信息,數(shù)據(jù)stream包括多種類型的數(shù)據(jù),具體需要哪幾種是由該列類型和編碼方式?jīng)Q定。
在ORC文件中保存了三個(gè)層級(jí)的統(tǒng)計(jì)信息,分別為文件級(jí)別、stripe級(jí)別和row group級(jí)別的,他們都可以用來根據(jù)Search ARGuments(謂詞下推條件)判斷是否可以跳過某些數(shù)據(jù),在統(tǒng)計(jì)信息中都包含成員數(shù)和是否有null值,并且對(duì)于不同類型的數(shù)據(jù)設(shè)置一些特定的統(tǒng)計(jì)信息。
更詳細(xì)的介紹請(qǐng)看 http://blog.csdn.net/yu616568/article/details/51868447
