更高的压缩比,更好的性能–使用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的压缩比

上图中原始的TEXT文本文件为585GB,使用Hive早期的RCFILE压缩后为505GB,使用Impala中的PARQUET压缩后为221GB,而Hive中的ORC压缩后仅为131GB,压缩比最高。
查看ORC的文件元数据
先准备一张ORC的示例表:
- CREATE TABLE lxw1234_orc1 (
- id INT,
- name STRING
- ) stored AS ORC;
- INSERT overwrite TABLE lxw1234_orc1
- SELECT CAST(siteid AS INT) AS id,
- pcid
- FROM lxw1234_text
- limit 10;
- SELECT * FROM lxw1234_orc1 ORDER BY id;
- 139 89578071000037563815CC
- 139 E811C27809708556F87C79
- 633 82E0D8720C8D1556C75ABA
- 819 726B86DB00026B56F3F151
- 1134 8153CD6F059210539E4552
- 1154 5E26977B0EEE5456F7E7FB
- 1160 583C0271044D3D56F95436
- 1351 FA05CFDD05622756F953EE
- 1351 16A5707006C43356F95392
- 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表:
- CREATE TABLE lxw1234_orc2 stored AS ORC
- AS
- SELECT CAST(siteid AS INT) AS id,
- pcid
- FROM lxw1234_text
- 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的更多相关文章
- 转: 更高的压缩比,更好的性能–使用ORC文件格式优化Hive
Hive从0.11版本开始提供了ORC的文件格式,ORC文件不仅仅是一种列式文件存储格式,最重要的是有着很高的压缩比,并且对于MapReduce来说是可切分(Split)的.因此,在Hive中使用OR ...
- SqlHelper发布——比你期望的还要多的多(例如比MyBatis-Pagehelper性能更高)
SqlHelper发布——比Mybatis-PageHelper性能更高 起源 前段时间开启了一个新的项目,在选择分页插件时,发现github上很流行的一个是pagehelper,在百度上搜索了一下, ...
- 译:ORCFILE IN HDP 2:更好的压缩,更高的性能
原文地址: https://hortonworks.com/blog/orcfile-in-hdp-2-better-compression-better-performance/ ORCFILE I ...
- Clear Linux 为脚本语言提供更高的性能
导读 Clear Linux的领先性能不仅限于C/C++应用程序,而且PHP,R和Python等脚本语言也有很大的提升速度.在一篇新的博客文章中,英特尔的一位开发人员概述了他们对Python的一些性能 ...
- graphicview和widgets没本质区别。它只是更轻量级,更灵活,性能更高的widgets
graphicview和widgets没本质区别.它只是更轻量级,更灵活,性能更高的widgets.核心就是把widgets变成了更轻量级的graphicitem,把QWidget的各种事件转换成了g ...
- 移动Web—CSS为Retina屏幕替换更高质量的图片
来源:互联网 作者:佚名 时间:12-24 10:37:45 [大 中 小] 点评:Retian似乎是屏幕显示的一种趋势,这也是Web设计师面对的一个新挑战;移动应用程序的设计师们已经学会了如何为Re ...
- 声明式编程——抽象程度更高,关注是什么(what),而非如何做(how)
CSDN:AngularJS的设计理念是什么?灵感来自于什么? Misko:AngularJS遵循的设计理念是--构建UI应该是声明式的.这也是AngularJS中标识符(directives)想法的 ...
- Struts 2.x仍然明显落后于时代。 Struts 2.x这一类老牌Web MVC开发框架仅能用于开发瘦客户端应用,无法用来开发对于交互体验要求更高的应用。
后来我在工作中陆续使用过Struts 1.x和Struts 2.x.我曾经把一个开源的基于Struts 1.x的自助式广告联盟应用移植到Spring MVC,还基于Struts 2.x做过网站开发.S ...
- Spring AOP中的JDK和CGLib动态代理哪个效率更高?
一.背景 今天有小伙伴面试的时候被问到:Spring AOP中JDK 和 CGLib动态代理哪个效率更高? 二.基本概念 首先,我们知道Spring AOP的底层实现有两种方式:一种是JDK动态代理, ...
随机推荐
- 腾讯云图片鉴黄集成到C#
官方文档:https://cloud.tencent.com/document/product/641/12422 请求官方API及签名的生成代码如下: var urlList = new List& ...
- .NET MVC项目设置包含Areas中的页面为默认启动页
利用vs创建一个MVC项目后,一般的默认启动页是根目录下-->Controllers-->HomeController-->Index这个方法对应的页面. 我先说下创建Areas的流 ...
- [日常] HTTP连接管理
HTTP连接管理: 1.误解的Connection首部 当http报文经过中间客户端到服务端中间的各种代理设备时,对标签中列出的头信息进行删除,close是事务结束后关掉此条连接 2.消除串行化的时延 ...
- 12. ReadWriteLock 读写锁
package com.gf.demo11; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent. ...
- (5)Microsoft office Word 2013版本操作入门_标尺
1.标尺 :左缩进,右缩进,悬挂缩进,首行缩进,阴影部分 可以左右拖拽调整边缘. 1.1 左缩进:默认缩进所在的段落,要缩进多段则需要多段落选中, 后拖动左缩进. 1.2 首行缩进缩进或者突出所选的 ...
- 【Mysql】常用命令
登录mysql -uroot -p 查看有哪些数据库show databases; 创建一个普通用户 sa ,密码是 some_passCREATE USER 'sa'@'%' IDENTIFIED ...
- 并发之AQS
一.概述 谈到并发,不得不谈ReentrantLock:而谈到ReentrantLock,不得不谈AbstractQueuedSynchronizer(AQS)! 类如其名,抽象的队列式的同步器,AQ ...
- element vue validate验证名称重复 输入框与后台重复验证 特殊字符 字符长度 及注意事项
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- CSS效果:CSS改变下拉列表select框的默认样式
原理 原理是将浏览器默认的下拉框样式清除,然后应用上自己的,再附一张向右对齐小箭头的图片即可.当然右侧的小箭头可以用伪元素before或者after来实现. select { /*Chrome和Fir ...
- PHP对接淘宝客api完成APP引流优惠券
淘宝客现在对多数人来说已经耳熟能详了,属于CPS(Cost Per Sale),一种网络广告收费标准,以实际销售产品数量来换算广告刊登金额.其他收费标准还有常见的CPC(Cost Per Click ...