目錄
- 概述
- 檔案存盤結構
- Stripe
- Index Data
- Row Data
- Stripe Footer
- 兩個補充名詞
- Row Group
- Stream
- File Footer
- 條紋資訊
- 列統計
- 元資料
- 型別資訊
- 復雜資料型別
- Postscript
- Stripe
- 資料讀取
- 位置指標
- 三層過濾
- 檔案級
- Stripe級
- Row 級
- 資料讀取
- 索引
- 行組索引
- 布隆過濾器
- 事務支持
- 壓縮
- 記憶體管理
- Hive中使用ORC
- Hive使用
- Hive引數設定
概述
本文基于上一篇文章 Hive存盤格式之RCFile詳解,RCFile的過去現在未來 撰寫,讀過上一篇文章,則更好理解以下內容,
2013年,HortonWorks在RCFile的基礎上開發出了ORC File(Optimied Row Columnar),在2015年成為Apache的頂級專案,以下簡稱ORC,
RCFile在被Facebook開源后,作為Hive之中典型的列存盤模型被廣泛使用,相比于之前的存盤格式有很大的優勢,但是同樣RCFile仍然有值得改進的地方,
ORC 做了相關優化,在Hive的使用中有更好的表現,它支持復雜資料型別、ACID支持及內置索引支持,非常適合海量資料的存盤,
ORC并不是一個單純的列式存盤格式,它也遵循了先水平磁區,再垂直磁區的理念,采用混合存盤結構,
除了Hive,目前也被Spark SQL,Flink,Presto,Impala等查詢引擎支持,
我上一篇中提及RCFile的兩個優化方向:
- 不同資料型別的列使用不同的壓縮方案(Facebook論文指出的優化方向-未做)
- 全域檢索性能查,提供更合理快速的檢索功能
ORC相對于RCFile提供了更優的解決方案:
- 列資料的型別感知:與RCFile之前未對列資料都統一為BLOB(binary large object-二進制大物件)資料不同,ORC可以感知列的資料型別,做出更為合理的資料壓縮選擇,
- 嵌套資料型別支持:ORC可以在列資料之中插入Struct,Union,List,Map等資料,讓資料操作更加靈活,也更加適合非結構化資料的存盤與處理,
- 謂詞下推:這個算是RCFile原先功能的補強,在元資料層面增加了很多內容,來利用謂詞下推加速處理的程序,ORC自己稱之為輕量級索引,其實就是一些相較于RCFile更為詳細的統計資料,
- 檔案可切分:檔案可切分,在Hive中使用ORC作為表的檔案存盤格式,不僅可以節省HDFS的存盤資源,查詢任務的輸入資料量減少,使用的MapTask也就減少了,
- 記憶體管理:提供了一個memory manager來管理記憶體使用情況,
接下來我們通過以下幾部分來完整的理解一下什么是ORC,
檔案存盤結構
ORC檔案是以二進制的方式存盤的,不可以直接讀取,但由于ORC的自描述特性,其讀寫不依賴于 Hive Metastore 或任何其他外部元資料,本身存盤了檔案資料、資料型別及編碼資訊,因為檔案是自包含的,所以讀取ORC檔案資料無需考慮用戶使用環境,
由于ORC的元資料使用Protocol Buffers序列化,添加新欄位不會破壞原有的資料結構,
如下圖所示,ORC引入了三個新的組件,
-
Stripe
-
File Footer
-
PostScript

Stripe
ORC的主體由多個Stripe(也成為條帶)組成,類似于RCFile中的行組,但是其遠遠大于行組的4MB,最大可達到250M大小,更大的Stripe使ORC的資料讀取更加高效,
每個Stripe彼此獨立,這個很好理解,因為每行資料彼此獨立,而每行資料不會在多個Stripe中,
在Hive中每個Stripe通常由不同的任務處理,列存盤格式的定義特征是每一列的資料是分開存盤的,從檔案中讀取資料的速度應該與讀取的列數成正比,
Stripe又包含三個部分:Index Data、Row Data和Stripe Footer,索引和資料部分都按列劃分,因此只需要讀取所需列的資料,
Index Data
索引資料部分,存盤每列的統計資料,Index Data在Stripe的最前面,因為它們只在使用謂詞下推或尋找指定行時加載,(這里主要利用索引功能實作的,具體見下文條帶級別索引)
Row Data
實際存盤資料的單元,利用列存盤原理,對不同列可以實作不同的壓縮方案,所有的列資料可以組成行資料,
Stripe Footer
存盤了每個列的編碼,資料流目錄與位置,
message StripeFooter {
// the location of each stream
repeated Stream streams = 1;
// the encoding of each column
repeated ColumnEncoding columns = 2;
optional string writerTimezone = 3;
// one for each column encryption variant
repeated StripeEncryptionVariant encryption = 4;
}
兩個補充名詞
在資料存盤和決議的程序中還使用到了兩個比較抽象的名詞描述,分別為Row Group和Stream,這里單獨說明一下,
Row Group
這里的Row Group和RCFile里的行組不是同一個概念,RCFile的行組對標的是ORC中的Stripe,
Row Group是虛擬的(下文有詳細介紹),Row Group Index是索引(index)的最小單位,一個Index Data中包含多個行組,默認值為 10000 個值,每一個Row Group Index中有多少條記錄在檔案的Footer中存盤,
Stream
本節以上部分是Stripe的邏輯結構,具體資料存盤還有更細粒度的單位存在,那就是Stream,在ORC檔案中,每一列都存盤在多個Stream中,這些Stream在檔案中彼此相鄰存盤,Stream保存了用戶真正關心的業務資料內容,
這也是ORC列式存盤的根本所在:正如開頭的架構圖一樣,一個大檔案由各Stripe分割,每個Stripe負責多個行組,在一個Stripe負責的這多行范圍內,各列的資料內容以Stream的形式按列存盤,為了描述每個Stream,ORC以位元組為單位存盤Stream的型別、列ID和Stream的大小,每個Stream中存盤內容的詳細資訊取決于列的型別和編碼,也就是說,在一個Stripe中的每一列都可能有多個表示不同資訊的Stream,存盤內容如下所示:
message Stream {
enum Kind {
// boolean stream of whether the next value is non-null
PRESENT = 0;
// the primary data stream
DATA = https://www.cnblogs.com/lubians/archive/2022/08/25/1;
// the length of each value for variable length data
LENGTH = 2;
// the dictionary blob
DICTIONARY_DATA = 3;
// deprecated prior to Hive 0.11
// It was used to store the number of instances of each value in the
// dictionary
DICTIONARY_COUNT = 4;
// a secondary data stream
SECONDARY = 5;
// the index for seeking to particular row groups
ROW_INDEX = 6;
// original bloom filters used before ORC-101
BLOOM_FILTER = 7;
// bloom filters that consistently use utf8
BLOOM_FILTER_UTF8 = 8;
// Virtual stream kinds to allocate space for encrypted index and data.
ENCRYPTED_INDEX = 9;
ENCRYPTED_DATA = 10;
// stripe statistics streams
STRIPE_STATISTICS = 100;
// A virtual stream kind that is used for setting the encryption IV.
FILE_STATISTICS = 101;
}
required Kind kind = 1;
// the column id
optional uint32 column = 2;
// the number of bytes in the file
optional uint64 length = 3;
}
這些不同型別的Stream會分布在ORC檔案里的不同部分,每個Stream的資料會根據該列的型別使用特定的壓縮演算法保存,主要有以下幾種(Kind),首先是下面這5種Stream,出現在各Stripe的Row Data位置,即文章開頭架構圖的藍色部分:
- PRESENT:幾乎每一列都會使用該Stream,按位標記該值是否為NULL
- DATA:記錄資料內容本身,
- LENGTH:記錄每個成員的長度,這個是針對string型別的列或者子列才有的,
- DICTIONARY_DATA:對string型別資料采用字典編碼以后的內容(該列所有去重值),
- SECONDARY:和DATA搭配,存盤Decimal、timestamp型別的小數部分或者納秒數部分等,
下面兩種Stream出現在Index Data中,
- ROW_INDEX:保存Stripe中每個row group的統計資訊和每個row group起始位置資訊,
- BLOOM_FILTER:用于記錄當前列在該Stripe中每一個row group的布隆過濾器資訊,用于謂詞下推跳過不用讀取的行組,
File Footer
檔案頁腳包含檔案主體的布局,型別架構資訊,行數和每個列的統計資訊,通過它們可以篩選出需要讀取列的資料,
條紋資訊
檔案的主體被分成stripe,每個stripe都是自包含的,可以僅使用其自己的位元組以及檔案的頁腳和后記來讀取,每個stripe包含整行,因此行永遠不會跨越stripe邊界,
它包含了每一個stripe的長度和偏移量,該檔案的schema資訊(將schema樹按照schema中的編號保存在陣列中,如下圖)、整個檔案的統計資訊以及每一個stripe的行數,
列統計
列統計的目標是,對于每一列,記錄總數并根據型別記錄其他有用欄位,對于大多數原始型別,它記錄了最小值和最大值;對于數字型別,多了一個總和記錄,列統計資訊還通過設定 hasNull 標志記錄行組內是否有任何空值,ORC 的謂詞下推使用 hasNull 標志來更好地支持“IS NULL”查詢,
對于整數型別(tinyint、smallint、int、bigint),列統計資訊包括最小值、最大值和總和,如果計算的總和存盤大于資料本身,則不會記錄總和,
message IntegerStatistics {
optional sint64 minimum = 1;
optional sint64 maximum = 2;
optional sint64 sum = 3;
}
對于浮點型別(float、double),列統計資訊包括最小值、最大值和總和,如果總和溢位雙倍,則不記錄總和,
對于字串,記錄最小值、最大值和所有值的長度之和,
對于布林值,統計資訊包括假值和真值的計數,
對于小數,存盤最小值、最大值和總和,
日期列將最小值和最大值記錄為自 UNIX 紀元(UTC 時間為 1970 年 1 月 1 日)以來的天數,
時間戳列將最小值和最大值記錄為自 UNIX 紀元 (1/1/1970 00:00:00) 以來的毫秒數,在 ORC-135 之前,包括本地時區偏移量,它們存盤為minimum和 maximum. 在 ORC-135 之后,時間戳調整為 UTC,然后再轉換為毫秒并存盤在minimumUtc和maximumUtc中,
message TimestampStatistics {
// min,max values saved as milliseconds since epoch
optional sint64 minimum = 1;
optional sint64 maximum = 2;
// min,max values saved as milliseconds since UNIX epoch
optional sint64 minimumUtc = 3;
optional sint64 maximumUtc = 4;
}
二進制列存盤所有值的總位元組數,
元資料
元資料(Metadata)包括用戶元資料和檔案元資料,用戶元資料通常作為秘鑰使用,這里不做闡述了,
檔案元資料部分包含條帶級別粒度的列統計資訊,這些統計資訊可以根據每個條帶的謂詞下推過濾資料,
型別資訊
ORC檔案中的所有行具有相同的架構,定義的型別是如同下圖的嵌套模式,其中復合型別在其下具有子列,

等效的Hive DDL是:
create table orc_temp(
myInt int,
myMap map<string,struct<myStirng:string,myDouble:double>>,
myTime timestamp
)
型別樹通過前序遍歷被展平到一個串列中,其中每個型別都被分配了下一個id,
復雜資料型別
對于復雜資料型別,比如Map,ORC檔案會將一個復雜資料型別欄位決議成多個子欄位,下表中列舉了ORC檔案中對于復雜資料型別的決議:
| 資料型別 | 子列 |
|---|---|
| Array | 一個包含所有陣列元素的單個子列 |
| Map | 兩個子列,一個key子列,一個value子列 |
| Struct | 每一個屬性對應一個子列 |
| Union | 每一個屬性對應一個子列 |

等效的DDL
CREATE TABLE tbl (
col1 Int,
col2 Array<Int>,
col4 Map<String,
Struct<col7:String,col8:Int>
>,
col9 String
)
Postscript
檔案的最后一個位元組保存著PostScript的長度,它的長度不會超過256位元組,PostScript提供了解釋檔案其余部分的必要資訊,包括檔案的 Footer 和 Metadata 部分的長度、檔案的版本以及使用的一般壓縮型別(例如 none、zlib 或 snappy)、檔案內部每個壓縮塊的最大長度(每次分配記憶體的大小)以及一些版本資訊,
資料讀取
orc檔案結構對資料的查找和索引本質上是三層過濾結合位置指標來實作的:檔案級、Stripe級、Row級,這樣可以把最終實際要掃描讀取的資料減少到部分Stripe的部分Row,不用全掃整個檔案,也就是先從檔案末尾往前讀檔案元資料,再跳著讀Stripe元資料,最終讀需要的Stripe中的部分資料,

位置指標
在讀取ORC檔案時,讀取器需要知道兩種位置,才能執行有效的資料讀取操作,
首先,由于條帶中的一列具有多個邏輯索引組(Row Group Index),因此ORC檔案的讀取器需要知道元資料流和資料流中每個索引組的起點,在上圖中,指向元資料流和資料流的圓虛線表示這種位置指標,
其次,一個ORC檔案可以包含多個Stripe,而這個ORC檔案的一個HDFS塊可以包含多個Stripe,為了有效地定位Stripe的起點,需要定位Stripe的位置指標,這些指標存盤在ORC檔案的檔案頁腳中(圓角虛線指向上圖中條紋的起點),
三層過濾
檔案級
在ORC檔案的末尾(檔案頁腳)會記錄檔案級別的統計資訊,會記錄整個檔案中每列的統計資訊,這些資訊主要用于查詢的優化,也可以為一些簡單的聚合查詢比如max, min, sum輸出結果,
Stripe級
ORC檔案會保存每個欄位Stripe級別的統計資訊,每個條帶中的每列的值的統計資訊,ORC reader使用這些統計資訊來確定對于一個查詢陳述句來說,需要讀入哪些Stripe中的記錄,例如,如果查詢要查找年齡超過 100 歲的人,則 SARG 將為“年齡 > 100”,并且只會讀取年齡超過 100 歲的條帶,
Row 級
為了進一步的避免讀入不必要的資料,在邏輯上將一個column的index(Index Data部分)以一個給定的值(默認為10000,可由引數配置)分割為多個index組(Row Group Index),存盤統計資訊和行組索引開始的位置,
Hive查詢引擎會將where條件中的約束傳遞給ORC reader,這些reader根據組級別的統計資訊,過濾掉不必要的資料,如果該值設定的太小,就會保存更多的統計資訊,用戶需要根據自己資料的特點權衡一個合理的值,
關于虛擬的Row Group,這10000個值的Row group Index映射到資料里,就是一個個的Row Group,反向看起來好像是Row Group的存在產生了Row group Index,但實際上Row Group是不存在的,為了便于理解,有些文章里也會說在Stripe之下還會有一個Row Group的存在,
資料讀取
看了以上三級檔案結構,就能很好的理解整個ORC的資料讀取流程了,
讀取檔案元資料:讀取 ORC 檔案是從尾部開始的,第一次讀取16KB的大小,盡量的將Postscript和Footer資料都讀入記憶體,
讀取Stripe元資料:處理Stripe時首先從Footer中獲取每一個Stripe的起始位置和長度、每一個Stripe的Footer資料(元資料,記錄了index和data的的長度),在初始化階段獲取所有的元資料以后,會得到一個指定讀取哪些列的編號構成的Boolean陣列,如果不指定則讀取所有的列,
讀取Row Group級元資料:接下來通過傳遞SearchArgument引數指定過濾條件,根據元資料首先讀取每個stripe中的index資訊,而后根據index中的統計資訊以及SearchArgument引數讀取的row group編號,獲取到所要讀取資料范圍包含了哪些row group,在對應的row group中讀取需要的資料,
讀取資料處理:經過這兩層的過濾,需要讀取的資料只是整個Stripe多個小段的區間,而后ORC會盡量合并多個離散的區間盡量減少I/O次數,下一步再根據Index中保存的下一個row group的位置資訊開始該Stripe中的下一個需要讀取的row group中進行資料讀取,

使用ORC檔案格式時,用戶可使用HDFS的每個block存盤ORC檔案的一個stripe,對于一個ORC檔案來講,stripe的大小通常須要設定得比HDFS的block小,若是不這樣的話,一個stripe就會分別在HDFS的多個block上,當讀取這種資料時就會發生遠程讀資料的行為,若是設定stripe的只保存在一個block上的話,若是當前block上的剩余空間不足以存盤下一個strpie,ORC的writer接下來會將資料打散保存在block剩余的空間上,直到這個block存滿為止,這樣,下一個stripe又會從下一個block開始存盤,
因為ORC中使用了更加精確的索引資訊,使得在讀取資料時能夠指定從任意一行開始讀取,更細粒度的統計資訊使得讀取ORC檔案跳過整個row group,ORC默認會對任何一塊資料和索引資訊使用ZLIB壓縮(可更改),所以ORC檔案占用的存盤空間也更小,
索引
ORC檔案在Row級過濾中使用的索引具體分為兩種,行組索引和布隆過濾器,后者為支持更好的使用謂詞下推過濾資料,布隆過濾器流與行組索引交錯,這種布局便于在單次讀取操作中同時讀取布隆過濾器流和行索引流,

行組索引
行組索引(Row Group Index)由每個原始列的 ROW_INDEX 流組成,每個原始列被行組索引覆寫,行組可調節,默認為 10,000 行,存盤列的每個流的位置以及該行組的統計資訊,
索引流被放置在條帶的前面,因為在默認的流式傳輸情況下,它們不需要被讀取,它們僅在使用謂詞下推或讀者尋找特定行時加載,
message RowIndexEntry {
repeated uint64 positions = 1 [packed=true];
optional ColumnStatistics statistics = 2;
}
message RowIndex {
repeated RowIndexEntry entry = 1;
}
對于具有多個流的列,每個流中的位置序列是連接的,
因為字典是隨機訪問的,即使只讀取部分條帶,也必須讀取整個字典,
布隆過濾器
從 Hive 1.2.0 開始,Bloom Filters 被添加到 ORC 索引中,謂詞下推可以利用布隆過濾器更好地修剪不滿足過濾條件的行組,布隆過濾器索引由通過“orc.bloom.filter.columns”表屬性指定的每一列的 BLOOM_FILTER 流組成,
布隆過濾器的具體使用參見上篇--什么是謂詞下推篇中的列式存盤中的謂詞下推(RF演算法),
事務支持
在 Hive 中以原子方式向表中添加資料的唯一方法是添加新磁區,更新或洗掉磁區中的資料需要洗掉舊磁區并將其與新資料一起添加回來,并且不可能以原子方式進行,
為了資料可靠性得到保證,需要實作保證原子性、一致性、隔離性和持久性的 ACID 事務,ORC支持 ACID 事務,支持流式攝取到 Hive 表中,查詢要么看到所有事務,要么看不到任何事務,
HDFS 是一次寫入檔案系統,而 ORC 是一次寫入檔案格式,不支持編輯檔案,
Hive在 ORC File基礎上,基于“base file+delta file”的模型實作了對ACID的支持,即資料首先被寫入一個 base file中,之后的修改資料被寫入一個 delta file,Hive將定期合并這兩個檔案,
但需要注意的是, Hive ORC ACID并不是為OLTP場景設計的,它能較好地支持一個事務中更新上百萬(甚至更多)條記錄,但難以應對一小時內上百萬個事務的場景,
壓縮
ORC檔案使用了一個兩級壓縮方案,流首先由特定于流型別的資料編碼方案進行編碼,然后,可以使用一個可選的通用資料壓縮方案(zlib 或 snappy)來進一步壓縮該流,
上文提到對于一個列,它被存盤在一個或多個流中,根據流的型別,我們可以將流分為四種基本型別,根據其型別,每個流有自己的資料編碼方案,下面介紹了這四種流的型別,
- 位元組流:一個位元組流基本上存盤一個位元組序列,它不編碼資料,
- 運行長度位元組流:一個運行長度位元組流存盤一個位元組序列,對于一個相同的位元組序列,它存盤重復的位元組和出現的情況,
- 整數流:一個整數流存盤一個整數序列,它可以用運行長度編碼和增量編碼來編碼這些整數,整數子序列的特定編碼方案是根據其模式確定的,
- 位元流:一個位欄位流用于存盤一個布林值的序列,在這個流中,一個位表示一個布林值,在底層,位欄位流由運行長度位元組流支持,
對于Int列,將使用一個位元流和一個整數流,位元流用于記錄一個值是否為空,整數流用于記錄此Int列的整數值,
對于二進制資料,ORC 使用三個流 ,位元流、位元組流 和 整數流,它們存盤每個值的長度,
對于字串列,ORC寫入器將首先檢查使用字典編碼是否可以有效地通過評估字典中不同條目的數量與編碼值的數量的比率是否大于可配置的閾值(默認閾值為0.8)來有效地存盤資料,
如果小于0.8,ORC寫入器將使用字典編碼方案,該列將存盤在一個位元流、一個位元組流和兩個整數流中,與Int列一樣,位元流也用于記錄一個值是否為空,位元組流用于存盤字典,一個整數流用于存盤字典中每個詞條的長度,第二個整數流用于存盤此列的值,
如果字典中不同條目目的數量與編碼值的數量大于閾值,ORC撰寫器將知道有許多不同的值,使用字典編碼不能有效地存盤資料,因此,它將自動存盤此列,而不需要進行字典編碼,ORC寫入器將使用位元組流來存盤此字串列的值,并使用整數流來存盤每個值的長度,而不是將字典和將值存盤為對字典的索引,
在ORC檔案中,可以進一步對ORC檔案使用通用的編解碼器壓縮流(ZLIB、Snappy),對于一個流,通用編解碼器將這個流壓縮為多個小壓縮單元,壓縮單元的默認大小為256KB,
ORC存盤格式支持三種通用壓縮格式,NONE,ZLIB和snappy壓縮,默認為ZLIB壓縮,即不設定壓縮格式則為ZLIB壓縮格式,可以通過"orc.compress"="NONE"來設定其余兩種壓縮格式,
關于以上四種型別的編碼詳解,感興趣的人可以去ORC官網具體查看,
記憶體管理
當ORC檔案的寫入器寫入資料時,它會緩沖記憶體中的整個Stripe,因此,ORC寫入器的記憶體占用是Stripe的大小,由于Stripe的默認大小很大,當有許多用戶同時寫入多個映射或減少任務中的ORC檔案時(例如,當用戶使用動態磁區,并且磁區列有許多不同的值時),此任務可能會耗盡記憶體,為了系結這些并發寫入器的記憶體消耗,ORC檔案中提供了一個記憶體管理器,在“映射”或“減少”任務中,記憶體管理器會設定一個閾值,以限制此任務中的寫入者可以使用的最大記憶體量,然后,每個新寫入器都以其Stripe大小(已設定的Stripe大小)注冊到此記憶體管理器,
當寫入器使用的記憶體總量(設定的Stripe大小總數)超過記憶體閾值時,記憶體管理器將以記憶體閾值與注冊的Stripe大小總數的比值縮小這些寫入器中使用的實際Stripe大小,當寫入器關閉時,記憶體管理器將從注冊的Stripe大小中減去此寫入器的注冊Stripe大小,如果注冊的總條帶大小低于閾值,則所有寫入器的實際條帶大小將被設定為其原始條帶大小,使用這種控制機制,來約束任務中ORC檔案的活動寫入器的記憶體,
Hive中使用ORC
Hive使用
在建Hive表的時候指定檔案的存盤格式,
CREATE TABLE ... STORED AS ORC
ALTER TABLE ... [PARTITION partition_spec] SET FILEFORMAT ORC
SET hive.default.fileformat=Orc
示例
-- 建表
create table lubian_orc(
id int,
name string,
extra string
) comment 'orc格式測驗表'
stored as orc;
-- 寫入資料
insert overwrite table lubian_orc
select id,name,extra from lubian_text
大多情況下,還是建議在Hive中將文本檔案轉成ORC格式(以上),使用程式生成ORC檔案,例如Java,屬于特殊需求場景,感興趣可以在orc官網找對應api做一些測驗,
Hive引數設定
所有關于ORCFile的引數都是在Hive QL陳述句的TBLPROPERTIES欄位里面出現
| 引數名 | 默認值 | 說明 |
|---|---|---|
| hive.exec.orc.memory.pool | 0.5 | 每個寫入任務使用記憶體最大比例 |
| hive.exec.orc.default.stripe.size | 256M | stripe的默認大小 |
| hive.exec.orc.default.block.size | 25610241024 | orc檔案在檔案系統中的默認block大小,從hive-0.14開始 |
| hive.exec.orc.dictionary.key.size.threshold | 0.8 | String型別欄位使用字典編碼的閾值,大于該閾值,不使用字典編碼 |
| 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則跳過該記錄 |
更多引數參考官網
以上,就是關于ORC檔案格式的詳細說明了,如果覺得不錯,點個贊再走吧,
按例,歡迎點擊此處關注我的個人公眾號,交流更多知識,
后臺回復關鍵字 hive,隨機贈送一本魯邊備注版珍藏大資料書籍,
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/502778.html
標籤:其他
