zoukankan      html  css  js  c++  java
  • orcFile split和读数据原理总结(hive0.13)

    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比较

  • 相关阅读:
    一个很简单的脑筋急转弯问题
    DataGrid PCV排序学习
    VS2010 出现打开关联文档错误的解决方案
    JS 简繁体互转代码
    js 常用正则表达式表单验证代码
    【转】自然语言处理(NLP)网上资源整理
    声卡编程讲解
    视频会议1
    转 语音处理资源
    编译WebRTC
  • 原文地址:https://www.cnblogs.com/felixzh/p/8575103.html
Copyright © 2011-2022 走看看