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的压缩比

上图中原始的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. INSERT overwrite TABLE lxw1234_orc1
  6. SELECT CAST(siteid AS INT) AS id,
  7. pcid
  8. FROM lxw1234_text
  9. limit 10;
  10. SELECT * FROM lxw1234_orc1 ORDER BY id;
  11. 139 89578071000037563815CC
  12. 139 E811C27809708556F87C79
  13. 633 82E0D8720C8D1556C75ABA
  14. 819 726B86DB00026B56F3F151
  15. 1134 8153CD6F059210539E4552
  16. 1154 5E26977B0EEE5456F7E7FB
  17. 1160 583C0271044D3D56F95436
  18. 1351 FA05CFDD05622756F953EE
  19. 1351 16A5707006C43356F95392
  20. 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,将其格式化后:

schema

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

stripeStatistics

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

fileStatistics

这里是整个文件中每个字段的统计信息,该表只有一个文件,也只有一个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 –orcfiledump -j -p hdfs://cdh5/hivedata/warehouse2/lxw1234_orc2/000000_0

查看文件的统计信息:

该文件中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,查看日志:

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

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

set hive.optimize.index.filter=false;

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

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

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

使用索引的耗时:

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

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

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的压缩比

上图中原始的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. INSERT overwrite TABLE lxw1234_orc1
  6. SELECT CAST(siteid AS INT) AS id,
  7. pcid
  8. FROM lxw1234_text
  9. limit 10;
  10. SELECT * FROM lxw1234_orc1 ORDER BY id;
  11. 139 89578071000037563815CC
  12. 139 E811C27809708556F87C79
  13. 633 82E0D8720C8D1556C75ABA
  14. 819 726B86DB00026B56F3F151
  15. 1134 8153CD6F059210539E4552
  16. 1154 5E26977B0EEE5456F7E7FB
  17. 1160 583C0271044D3D56F95436
  18. 1351 FA05CFDD05622756F953EE
  19. 1351 16A5707006C43356F95392
  20. 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,将其格式化后:

schema

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

stripeStatistics

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

fileStatistics

这里是整个文件中每个字段的统计信息,该表只有一个文件,也只有一个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 –orcfiledump -j -p hdfs://cdh5/hivedata/warehouse2/lxw1234_orc2/000000_0

查看文件的统计信息:

该文件中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,查看日志:

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

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

set hive.optimize.index.filter=false;

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

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

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

使用索引的耗时:

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

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

转: 更高的压缩比,更好的性能–使用ORC文件格式优化Hive的更多相关文章

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

    http://lxw1234.com/archives/2016/04/630.htm 关键字:orc.index.hive Hive从0.11版本开始提供了ORC的文件格式,ORC文件不仅仅是一种列 ...

  2. SqlHelper发布——比你期望的还要多的多(例如比MyBatis-Pagehelper性能更高)

    SqlHelper发布——比Mybatis-PageHelper性能更高 起源 前段时间开启了一个新的项目,在选择分页插件时,发现github上很流行的一个是pagehelper,在百度上搜索了一下, ...

  3. 译:ORCFILE IN HDP 2:更好的压缩,更高的性能

    原文地址: https://hortonworks.com/blog/orcfile-in-hdp-2-better-compression-better-performance/ ORCFILE I ...

  4. System.Data.Oracleclient需要Oracle客户端软件Version8.1.7或更高版本问题

    C#连接ORACLE报System.Data.Oracleclient需要Oracle客户端软件Version8.1.7或更高版本问题: 开始Webservice在32位系统ORACLE10g库中we ...

  5. phpMyAdmin - 错误 您应升级到 MySQL 5.5.0 或更高版本,解决办法。。。

    折腾自己的个人网站,装了个数据库管理工具,遇到您应升级到 MySQL 5.5.0 或更高版本... 采用降级phpmyadmin版本的方法解决了: 查找phpmyadmin/libraries/com ...

  6. oracleclient连oracle库 报System.Data.OracleClient 需要 Oracle 客户端软件 8.1.7 或更高版本

    在iis下发布eworkflow+eform+ebiao的代码,访问oracle的数据库,用oracleClient或者oledb的方式连接,有时会报“System.Data.OracleClient ...

  7. 关于IIS部署时出现“System.Data.OracleClient 需要 Oracle 客户端软件 8.1.7 或更高版本”的问题解决摘要

    系统环境:windows2008 X64 IIS版本:iis7 oracle客户端版本:11g,另外装了32位的客户端. 网站.net framework版本: 4.0 目前状况,IIS可以正常运行, ...

  8. MVC 基架不支持 Entity Framework 6 或更高版本

    MVC 基架不支持 Entity Framework 6 或更高版本.有关详细信息,请访问 http://go.microsoft.com/fwlink/?LinkId=276833. PS:新做一个 ...

  9. 【2016-09-16】UbuntuServer14.04或更高版本安装问题记录

    出于项目需要,我们的Qt程序需要运行在 1. Windows/Linux-X86平台(CPU为常见的桌面级CPU如G3220.I3等): 2. Windows/Linux-X86低功耗平台(CPU为I ...

随机推荐

  1. PYTHON 最佳实践指南(转)

    add by zhj: 本文参考了The Hitchhiker's Guide to Python,当然也加入了作者的一些东西.The Hitchhiker's Guide to Python 的gi ...

  2. HTML(form标签)、CSS

    一.表单标签<form> 功能:表单用于向服务器传输数据,从而实现用户与Web服务器的交互. 表单能够包含input系列标签,比如文本字段.复选框.单选框.提交按钮等等. 表单还可以包含t ...

  3. centos7 重启网卡失败

    今天在centOS 7 network服务重启不了 现把各种解决方法归纳整理,希望能让后面的同学少走点歪路... 首先看问题:执行service network restart命令后出现下面的错误: ...

  4. sql server性能调优

    转自:https://www.cnblogs.com/woodytu/tag/%E6%80%A7%E8%83%BD%E8%B0%83%E4%BC%98%E5%9F%B9%E8%AE%AD/defaul ...

  5. 关于source insight、添加.s和.S文件,显示全部路径、加入项目后闪屏幕

    1.source insight使用也有一年多时间了,今天出现建工程后添加文件“no files found” 百思不得姐: 后面发现是原工程命名时出现非法字符.重新命名就ok了. 切记切记 2.实用 ...

  6. 微信小程序组件button

    表单组件button:官方文档 Demo Code: var types=['default', 'primary', 'warn']; var pageObject = { data: { defa ...

  7. LeetCode:路径总和II【113】

    LeetCode:路径总和II[113] 题目描述 给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径. 说明: 叶子节点是指没有子节点的节点. 示例:给定如下二叉树, ...

  8. Spark机器学习3·推荐引擎(spark-shell)

    Spark机器学习 准备环境 jblashttps://gcc.gnu.org/wiki/GFortranBinaries#MacOS org.jblas:jblas:1.2.4-SNAPSHOT g ...

  9. HTTP与服务器的四种交互方式

    Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE.URL全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上的资源,而HTTP ...

  10. Tomcat:解决Tomcat可以在eclipse启动,却无法显示默认页面的操作

    解决Tomcat可以在eclipse启动,却无法显示默认页面的操作 今天在eclipse中配置好tomcat后访问不到它的主页,但是能运行自己的项目,一直找不到原因,百度之后最后解决了这个问题,总结如 ...