1. 程式人生 > >orcFile split和讀數據原理總結(hive0.13)

orcFile split和讀數據原理總結(hive0.13)

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>

配置

KEYDefaultNotes
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
  • 開啟條件及優缺點
    這裏只討論非combine方式的split個讀取方式。

    • 觸發條件:
      • set hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;(必選)
      • set hive.optimize.index.filter=true;(可選)
        • 是否條件下推到TS,進行條件過濾,建議開啟
      • set hive.exec.orc.zerocopy=true;(可選)
        • 讀取orc文件,是否使用0拷貝,建議開啟
    • 上述3個配置都開啟情況
      • 優點:
        • 做split時:
          • 可以將不符合條件的stripe提前過濾,減少map個數
        • 讀取時:
          • 可以直接跳過不符合條件的rowGroup,無需讀取多余的數據
      • 缺點:
        • 不會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掉,減少讀取的數據量
  • 優缺點

    • 優點
      • 可以提前過濾無需的stripe,減少split個數
      • 讀取時,可以過濾不滿足條件的rowGroup,減少讀取數
    • 缺點
      • 做split時,stripe不會合並,有可能導致split數比combine方式更多
      • 也有可能數據量少的split數比數據量多的split數多

測試結果

  1. 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‘ andchannel_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:
  2. 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‘ andchannel_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:

參考文檔

orc和parquet比較

orcFile split和讀數據原理總結(hive0.13)