• 更高的压缩比,更好的性能–使用ORC文件格式优化Hive


    http://lxw1234.com/archives/2016/04/630.htm

    关键字:orc、index、hive

    Hive从0.11版本开始提供了ORC的文件格式,ORC文件不仅仅是一种列式文件存储格式,最重要的是有着很高的压缩比,并且对于MapReduce来说是可切分(Split)的。因此,在Hive中使用ORC作为表的文件存储格式,不仅可以很大程度的节省HDFS存储资源,而且对数据的查询和处理性能有着非常大的提升,因为ORC较其他文件格式压缩比高,查询任务的输入数据量减少,使用的Task也就减少了。关于Orc文件格式的官网介绍,见:

    https://cwiki.apache.org/confluence/display/Hive/LanguageManual+ORC

    需要注意的是,ORC能很大程序的节省存储和计算资源,但它在读写时候需要消耗额外的CPU资源来压缩和解压缩,当然这部分的CPU消耗是非常少的。
    对性能提升的另一个方面是通过在ORC文件中为每一个字段建立一个轻量级的索引,来判定一个文件中是否满足WHERE子句中的过滤条件。比如:当执行HQL语句”SELECT COUNT(1) FROM lxw1234_orc WHERE id = 0”时候,先从ORC文件的metadata中读取索引信息,快速定位到id=0所在的offsets,如果从索引信息中没有发现id=0的信息,则直接跳过该文件。详见后面介绍。
    说明一下:本文使用Hive2.0.0 + hadoop-2.3.0-cdh5.0.0作为测试环境。

    ORC的压缩比

    hive orc

    上图中原始的TEXT文本文件为585GB,使用Hive早期的RCFILE压缩后为505GB,使用Impala中的PARQUET压缩后为221GB,而Hive中的ORC压缩后仅为131GB,压缩比最高。

    查看ORC的文件元数据

    先准备一张ORC的示例表:

    1. CREATE TABLE lxw1234_orc1 (
    2. id INT,
    3. name STRING
    4. ) stored AS ORC;
    5.  
    6. INSERT overwrite TABLE lxw1234_orc1
    7. SELECT CAST(siteid AS INT) AS id,
    8. pcid
    9. FROM lxw1234_text
    10. limit 10;
    11.  
    12. SELECT * FROM lxw1234_orc1 ORDER BY id;
    13. 139 89578071000037563815CC
    14. 139 E811C27809708556F87C79
    15. 633 82E0D8720C8D1556C75ABA
    16. 819 726B86DB00026B56F3F151
    17. 1134 8153CD6F059210539E4552
    18. 1154 5E26977B0EEE5456F7E7FB
    19. 1160 583C0271044D3D56F95436
    20. 1351 FA05CFDD05622756F953EE
    21. 1351 16A5707006C43356F95392
    22. 1361 3C17A17C076A7E56F87CCC

    ORC表lxw1234_orc1对应的HDFS文件为:

    /hivedata/warehouse2/lxw1234_orc1/000000_0

    新版本的Hive中提供了更详细的查看ORC文件信息的工具 orcfiledump。

    执行命令:./hive –orcfiledump -j -p /hivedata/warehouse2/lxw1234_orc1/000000_0

    返回一段JSON,将其格式化后:

    hive orc

    schema

    hive orc

    为每一个字段做了编号,从1开始,编号为0的columnId中描述了整个表的字段定义。

    stripeStatistics

    hive orc

    这里是ORC文件中所有stripes的统计信息,其中有每个stripe中每个字段的min/max值,是否有空值等等。

    fileStatistics

    hive orc

    这里是整个文件中每个字段的统计信息,该表只有一个文件,也只有一个stripe。

    stripes

    这里列出了所有stripes的元数据信息,包括index data, row data和stripe footer。

    ORC查询优化

    经过上面ORC文件的元数据了解了一个ORC文件会被分成多个stripe,而且文件的元数据中有每个字段的统计信息(min/max,hasNull等等),这就为ORC的查询优化做好了基础准备。假如我的查询过滤条件为WHERE id = 0;在Map Task读到一个ORC文件时,首先从文件的统计信息中看看id字段的min/max值,如果0不包含在内,那么这个文件就可以直接跳过了。
    基于这点,还有一个更有效的优化手段是在数据入库的时候,根据id字段排序后入库,这样尽量能使id=0的数据位于同一个文件甚至是同一个stripe中,那么在查询时候,只有负责读取该文件的Map Task需要扫描文件,其他的Map Task都会跳过扫描,大大节省Map Task的执行时间。海量数据下,使用ORDER BY可能不太现实,另一个有效手段是使用DISTRIBUTE BY id SORT BY id;

    使用下面的HQL构造一个较大的ORC表:

    1. CREATE TABLE lxw1234_orc2 stored AS ORC
    2. AS
    3. SELECT CAST(siteid AS INT) AS id,
    4. pcid
    5. FROM lxw1234_text
    6. DISTRIBUTE BY id sort BY id;

    该语句保证相同的id位于同一个ORC文件中,并且是排序的。

    SELECT DISTINCT INPUT__FILE__NAME FROM lxw1234_orc2 WHERE id = 0;

    hdfs://cdh5/hivedata/warehouse2/lxw1234_orc2/000000_0

    id=0的数据只存在于这一个文件中,而这个表有33个文件。

    hive orc

    也可以通过命令

    ./hive –orcfiledump -j -p hdfs://cdh5/hivedata/warehouse2/lxw1234_orc2/000000_0

    查看文件的统计信息:

    hive orc

    该文件中id的最小值为0,最大值为1155.

    因此,对于HQL查询”SELECT COUNT(1) FROM lxw1234_orc2 WHERE id = 0”,优化器在执行时候,只会扫描这一个文件,其他文件都应该跳过。

    在验证之前,先介绍一个参数:

    hive.optimize.index.filter,是否自动使用索引,默认为false(不使用);如果不设置该参数为true,那么ORC的索引当然也不会使用。

    在Hive中执行set hive.optimize.index.filter=true;

    SELECT COUNT(1) FROM lxw1234_orc2 WHERE id = 0;

    查看日志,该查询一共有13个MapTask,

    找到包含/hivedata/warehouse2/lxw1234_orc2/000000_0的MapTask,查看日志:

    hive orc

    查看其它MapTask,均没有扫描记录的日志。

    不使用索引,再执行一次:

    set hive.optimize.index.filter=false;

    SELECT COUNT(1) FROM lxw1234_orc2 WHERE id = 0;

    再查看日志时,每个MapTask中都有扫描记录的日志,说明每个MapTask都对自己的分片进行了扫描。

    两次执行,MapTask的执行时间也能说明问题。

    使用索引的耗时:

    hive orc

    不使用索引的耗时(明显多于上面):

    hive orc

    由此可见,Hive中的ORC不仅仅有着高压缩比,很大程序的节省存储空间和计算资源,而且在其上还做了许多优化(这里仅仅介绍了row_index)。如果使用Hive作为大数据仓库,强烈建议主要使用ORC文件格式作为表的存储格式。

  • 相关阅读:
    制作自适应布局的模块及框架(转载)
    从今天起开始写博了
    工作中碰到的css问题解决方法
    标题写个什么好呢
    快速编写HTML(Zen conding)
    2013年1月21日记事
    opc 方面研究
    关于 部署方面研究 Visual Studio 2013
    intel AVX指令集
    关于 返回数据类型 后 加& 的作用
  • 原文地址:https://www.cnblogs.com/felixzh/p/8529546.html
Copyright © 2020-2023  润新知