orcFile split和讀數據原理總結(hive0.13)
阿新 • • 發佈:2018-03-15
etime cit .net ack 處理 gem gravity AC col
http://blog.csdn.net/zhaorongsheng/article/details/72903431
官網關於orcfile的介紹
背景
Hive的rcfile格式已經使用多年,但是,它會將所有的列都當做二進制來處理,沒有與類型掛鉤。因此,Hive0.11版本引入orcFile。OrcFile有以下幾點好處:
- 每個task只生成一個文件,減輕hdfs壓力
- 保存列類型,支持datetime, decimal和負責類型(struct, list, map, and union)
- 文件中保存輕量級索引
- 跳過不需的row group
- seek到指定的row
- 根據列類型進行壓縮
- 整數類型:run-length encoding
- string類型:dictionary encoding
- 不同的recordReader並發讀同一文件
- split時,無需掃描標記
- 可以限制讀寫占用的內存
- 使用pb存放元數據,支持添加和移除列
結構
(圖片來源:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+ORC)
orc dump工具
// Hive version 0.11 through 0.14:
hive --orcfiledump <location-of-orc-file>
// Hive version 0.15 and later:
hive --orcfiledump [-d] [--rowindex <col_ids>] <location-of-orc-file>
// Hive version 1.2.0 and later:
hive --orcfiledump [-d] [-t] [--rowindex <col_ids>] <location-of-orc-file>
// Hive version 1.3.0 and later:
hive --orcfiledump [-j] [-p] [-d] [-t] [--rowindex <col_ids>] [--recover] [--skip-dump]
[--backup-path <new-path>] <location-of-orc-file-or-directory>
配置
KEY | Default | Notes |
---|---|---|
orc.compress | ZLIB | 壓縮算法,NONE/ZLIB/SNAPPY |
orc.compress.size | 262,144 | 每個壓縮塊大小,也是壓縮保存stripe數據緩存大小 |
orc.stripe.size | 67,108,864 | stripe大小 |
orc.row.index.stride | 10,000 | 索引數據間隔行(必須>=1000),即每10,000行數據,建一次索引,也是劃分rowGroup的依據 |
orc.create.index | true | 是否建行級索引 |
split讀取原理
-
涉及配置
- hive.optimize.index.filter
- 默認值:false
- 意義:
- 是否使用索引優化物理執行計劃
- 是否將條件下推到TableScanOperator中(讀取數據、做split時會使用此條件信息)
- orcFile需要設置為true,才能獲取到過濾條件,進行stripe過濾
- hive.exec.orc.zerocopy
- 默認:false
- 讀取orc文件時,是否使用0拷貝
- hive.input.format
- 默認:CombineHiveInputFormat
- 當使用combine方式時,會將小文件進行合並,但是不會用到OrcInputFormat的過濾stripe機制
- 當使用
org.apache.hadoop.hive.ql.io.HiveInputFormat
,會調用OrcInputFormat的getSplits方法
,過濾不符合要求的stripe
- hive.optimize.index.filter
-
開啟條件及優缺點
這裏只討論非combine方式的split個讀取方式。- 觸發條件:
- set hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;(必選)
- set hive.optimize.index.filter=true;(可選)
- 是否條件下推到TS,進行條件過濾,
建議開啟
- 是否條件下推到TS,進行條件過濾,
- set hive.exec.orc.zerocopy=true;(可選)
- 讀取orc文件,是否使用0拷貝,
建議開啟
- 讀取orc文件,是否使用0拷貝,
- 上述3個配置都開啟情況
- 優點:
- 做split時:
- 可以將不符合條件的stripe提前過濾,減少map個數
- 讀取時:
- 可以直接跳過不符合條件的rowGroup,無需讀取多余的數據
- 做split時:
- 缺點:
- 不會combine,有可能會因為小文件過多,導致map數過多
- 依賴用戶where條件,如果where條件過濾的數據不是很多,可能不會過濾stripe,導致map數過多(同時增加額外的計算,導致性能有所下降)
- 優點:
- 觸發條件:
-
原理介紹
- split
- 步驟1:stripe1,設置offset1和end1
- 步驟2:stripe2被過濾條件過濾,
stripe1則會產生一個split
- 步驟3:stripe3,設置offset2和end2
- 步驟4:stripe4和stripe3處於不同的block,
stripe3則會產生一個split
,offset和end分別指向stripe4的開始和結束位置 - 步驟5:stripe5,offset不變,end指向stripe5的結束位置
- 步驟6:stripe6,此時(end4-offset4)>maxSplitSize,
stripe4/5/6則會產生一個split
- 步驟7:stripe7,到達文件結束,
stripe7產生一個split
- 讀取
- 讀取footer:獲取列信息、索引位置信息、數據位置信息等
- 讀取indexData
- 根據
orc.row.index.stride
的值,劃分rowGroup,每個rowGroup的索引數據條數為orc.row.index.stride
的值 - 根據索引數據的信息(max/min),判斷每個rowGroup是否滿足下推的where條件,實際讀取數據時進行skip
- 根據
- 讀取實際數據
- 讀取每列的數據,當遇到被過濾的rowGroup時,會skip掉,減少讀取的數據量
- split
-
優缺點
- 優點
- 可以提前過濾無需的stripe,減少split個數
- 讀取時,可以過濾不滿足條件的rowGroup,減少讀取數
- 缺點
- 做split時,stripe不會合並,有可能導致split數比combine方式更多
- 也有可能數據量少的split數比數據量多的split數多
- 優點
測試結果
-
stripeSize為128M
- sql1
select log_date,log_time,hh24,area_country,area_prov,area_city from tbl_orc_128M where dt=‘20161109‘ and hh24=‘19‘ and
channel_id=179569143limit 100;
- combine方式
- map數:1310
- 會進行列skip
Reading ORC rows from hdfs://bipcluster/bip/external_table/xx/tbl_orc_128M/dt=20161109/000856_0 with {include: [true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false], offset: 0, length: 225585161}
- combine方式+條件下推
- map數:1310
- 會進行列skip
- 會進行rowGroup的skip
- 非combine方式
- map數:1747
- 會進行列skip
- 非combine方式+條件下推
- map數:43
- 會進行列skip
- 會進行rowGroup的skip:
- sql2
select log_date,log_time,hh24,area_country,area_prov,area_city from tbl_orc_128M where dt=‘20161109‘ and hh24=‘19‘ limit 100;
- combine方式
- map數:1310
- 會進行列skip
- combine方式+條件下推
- map數:1310
- 會進行列skip
- 會進行rowGroup的skip
- 非combine方式
- map數:1747
- 會進行列skip
- 非combine方式+條件下推
- map數:1747
- 會進行列skip
- 會進行rowGroup的skip:
- sql1
-
stripeSize為64M
- sql1
select log_date,log_time,hh24,area_country,area_prov,area_city from tbl_orc_64M where dt=‘20161109‘ and hh24=‘19‘ and
channel_id=179569143limit 100;
- combine方式
- map數:1448
- 會進行列skip
- combine方式+條件下推
- map數:1448
- 會進行列skip
- 會進行rowGroup的skip
- 非combine方式
- map數:3494
- 會進行列skip
- 非combine方式+條件下推
- map數:0
- sql2
select log_date,log_time,hh24,area_country,area_prov,area_city from tbl_orc_64M where dt=‘20161109‘ and hh24=‘19‘ limit 100;
- combine方式
- map數:1448
- 會進行列skip
- combine方式+條件下推
- map數:1448
- 會進行列skip
- 會進行rowGroup的skip
- 非combine方式
- map數:3494
- 會進行列skip
- 非combine方式+條件下推
- map數:3494
- 會進行列skip
- 會進行rowGroup的skip:
- sql1
參考文檔
orc和parquet比較
orcFile split和讀數據原理總結(hive0.13)