Hive优化_1. 数据文件优化篇
2015-12-02 13:40
363 查看
之前转载了一篇<Hive - 数据仓库的性能优化>。博主总结的很不错。这里本人将自己平时积累的资料汇总了一下,来补充一下这篇文章:
针对方法上篇的优化方法1,2,3 主要建立在 Hive 触发了一个 MapReduce Job。但是我们都知道,启用 MapReduce Job 会消耗系统开销的(从我这篇博文 Hive_4.DDL
-- 数据库&内部表&外部表 可以发现当使用 Like 关键词的时候效率比 CTAS 要快很多倍)。对于这个问题, Hive 从0.10.0 版本开始,对于简单的不需要聚合操作的语句将不会触发 MapReduce Job,直接通过 Fetch task 来获取数据。
详细信息可以参考:/article/2315994.html
1.1 文件格式 -- 具体应用实例请参考: Hive_1.
Hive 最新发布的 0.14.0 版本中支持
在这里,
我们可以通过
Hive 支持如下数据格式,它们的优化如下所示:
TEXTFILE :这是 Hive 默认的文件格式。文本文件中的数据没有被压缩,所以我们可以通过压缩工具(
GZip, Bzip2, Snappy) 对它进行压缩。但是 Gzip 和 Snappy 压缩的文件是不可分割的,这就导致了处理一个大文件时需要一个单独的,耗资源的 map job 。增加了系统的负担和时间。这里需要注意的是,Bzip2
从 Hadoop 2.1 开始才支持本地可分割。所以你会发现网上很多文章都把 Bzip2 认为是不可分割的。我将会在之后的 Hadoop Compression 专题中详细介绍。详细参考 Jira ticket : https://issues.apache.org/jira/browse/HADOOP-8462
SEQUENCEFILE:这是一个基于键值对的二进制存储格式。它是优势是
SequenceFile 比文本文件更加紧凑,同时能够很好的兼容 MapReduce 的输出格式。SequenceFile 有3中压缩方式:Record & Block & Null。 你可以通过以下方式来启动 Blcok 级别的压缩:
不幸的是,文本文件和 SequenceFile 都是基于行级别的存储文件格式,对Hive 来说并不是最优的选择。由于 Hive 每次都需要读取整行数据,尽管只需要一列数据。因此 RCFile , ORC, Parquet 便应运而生了。它们用来解决文本文件和 SequenceFile所存在的限制。(这里需要了解一下
Avro 也是基于行的存储,由于在Avro系列中已经做了详细介绍,这里就不对Avro过多阐述了)
RCFile :它是柱状记录文件(Record
Columnar File)的简称。它是一个由二进制键值对组成的平面文件,与SequenceFile 有点相似。RCFile 是基于行组(row group)的水平数据分割。这里一个或者多个行组是 HDFS 中存储的文件。RCFile 通过首先将每一行的第一列来将行组数据保存为柱状格式,之后再对每一行的第二列,。。。这种格式是可分割的并且允许
Hive 跳过无关数据来更快更轻松得到数据结果。
ORC :它是 Optimized
Row Columnar的简写。从 Hive 0.11.0 版本才开始支持 ORC 格式。ORC 用来解决 RCFile部分性能问题。它提供了默认的 256MB 大小的 blcok ( RCFile 是 4MB, SequenceFile 是1MB)来对NameNode
节点上的高吞吐量和通过更少的 reducer端需要处理的文件来优化HDFS 中序列化文件的读取。与 RCFile 不同的是,ORC 需要依赖元数据来确认数据类型。它通过特定的编码器来识别数据类型,这样它就能根据不同类型进行压缩优化。ORC 同样支持基本列的统计方法:
和
Parquet :它是一个类似于 ORC 格式的行柱状文件格式。不同的是,相比较只支持 Hive 和 Pig 的ORC
格式,Parquet 在 Hadoop 生态系统中已经广泛支持许多项目。Parquet 利用 Google的最佳实践案例:Dremel 来支持嵌套的结构化数据。Parquet 支持从 Hive 0.10.0 版本开始就可以作为一个插件进行使用,知道
Hive 0.13.0 才开始得到本地支持。(Avro 是从 Hive 0.14 版本才得到本地支持)。
Google Dremel high level intruduce:http://research.google.com/pubs/pub36632.html
Google Dremel 原理(中文):http://www.yankay.com/google-dremel-rationale/
考虑到 Hive 的成熟度,还是建议在你的 Hadoop 环境中使用 ORC 格式作为主要的工具。如果你的 Hadoop 生态系统中使用多种 tools, Parquet 在适应性方面不失为一个更好的选择。
注意:Hadoop Archive
接下来,我们就需要考虑应该配置哪一种压缩编码,Hadoop 和 Hive 中支持的通用压缩编码器如下所示:
Hadoop 有一个默认压缩编码器(
CPU 成本都比 GZip 要高。Bzip2 是可分割的,但是直到 Hadoop 1.1 才支持分割(参考 Jira ticket :https://issues.apache.org/jira/browse/HADOOP-4012)。Bzip2
也由于高额的 CUP 开销使得压缩很缓慢。
LZO 文件并不是本地可分割,但是我们可以通过 com.hadoop.compression.lzo.LzoIndexer 创建一个索引来决定文件的分割,它很好的中和了CUP开销和压缩率(在后面会有专题介绍该内容)。LZ4
和 Snappy能够很好的处理一个 Job。
由于很多编码方法不支持压缩后可分割,所以不建议在 HDFS 中压缩大文件。
你可以通过
Hive CLI 来指定压缩编码器,如下所示:
对指定的 Job 中间数据的压缩只会节省磁盘空间,但是需要多个 map 和 reduce job。为了进一步节省磁盘空间,Hive 的输出文件是可以被压缩的。可以通过设置
Hive 可以通过配置 mapred.map.output.compression.codec 属性来对中间数据进行压缩。你可以从
Hive CLI 设置。
另一方面,太多的文件或者冗余会耗尽NameNode 的内存,特别的对于大量的小于 Hadoop blcok 大小的文件。Hadoop 对于处理大量小文件问题的这种情况已经提出了解决方案。如下所示:
Hadoop Archive and HAR:用来打包小文件的工具集.
SequenceFile format : 将小文件压缩成大文件的一种格式.
CombineFileInputFormat : 一种在map
和 reduce 进程前整合小文件的输入格式。是 Hive 的默认
HDFS federation :它允许 NameNode 有更好的扩展性并且能够管理多个文件。
我们同样可以使用 Hadoop 生态系统中的其他工具来处理(在已经安装该工具的前提下),如下所示:
HBase 有更小的 block 大小和文件格式来处理小文件处理问题。
Flume NG 可以用来作为将小文件整合成大文件的管道( 关于 Flume-NG 请参考:/article/10611211.html)
通过离线的文件整合程序来将 HDFS 中小文件整合到一起。
对 Hive 来说,我们可以通过配置属性来将查询结果进行整合,避免创建小文件:
map 的job 中整合小文件,默认为
在 MapReduce Job 最后进行整合小文件,可以设置为
该属性定义了对于每个任务运行整合的文件最大值。默认是 256,000,000.
这是用来触发文件整合操作的阈值,默认是16,000,000.
当输出文件的平均大学都小于指定的
会启动一个额外的 MapReduce Job 来整合输出文件为一个大文件。
针对方法上篇的优化方法1,2,3 主要建立在 Hive 触发了一个 MapReduce Job。但是我们都知道,启用 MapReduce Job 会消耗系统开销的(从我这篇博文 Hive_4.DDL
-- 数据库&内部表&外部表 可以发现当使用 Like 关键词的时候效率比 CTAS 要快很多倍)。对于这个问题, Hive 从0.10.0 版本开始,对于简单的不需要聚合操作的语句将不会触发 MapReduce Job,直接通过 Fetch task 来获取数据。
详细信息可以参考:/article/2315994.html
1. 数据文件优化:
数据文件的优化包含了通过数据文件格式, 压缩,存储方式的选择来进行性能提升。1.1 文件格式 -- 具体应用实例请参考: Hive_1.
数据存储 & 压缩
Hive 最新发布的 0.14.0 版本中支持TEXTFILE,
SEQUENCEFILE,
RCFILE,
ORC,
PARQUET和 Avro文件格式。我们可以通过以下方法来指定文件的格式:
CREATE TABLE ... STORE AS <File_Format>
ALTER TABLE ... [PARTITION partition_spec] SET FILEFORMAT <File_Format>
SET hive.default.fileformat = <File_Format> --设置表的默认文件格式
在这里,
<File_Type>可以是
TEXTFILE,
SEQUENCEFILE,
RCFILE,
ORC,
PARQUET
或者
Avro
类型.
我们可以通过
TEXTFILE格式将 text 文件直接加载到一张表中。如果要往表中加载其他格式的数据,我们需要将数据先加载成
TEXTFILE格式的表,之后再使用
INSERT OVERWRITE TABLE <target_file_format_table> SELECT * FROM <text_format_source_table>语句进行转换,将期望的数据格式加载到表中。
Hive 支持如下数据格式,它们的优化如下所示:
TEXTFILE :这是 Hive 默认的文件格式。文本文件中的数据没有被压缩,所以我们可以通过压缩工具(
GZip, Bzip2, Snappy) 对它进行压缩。但是 Gzip 和 Snappy 压缩的文件是不可分割的,这就导致了处理一个大文件时需要一个单独的,耗资源的 map job 。增加了系统的负担和时间。这里需要注意的是,Bzip2
从 Hadoop 2.1 开始才支持本地可分割。所以你会发现网上很多文章都把 Bzip2 认为是不可分割的。我将会在之后的 Hadoop Compression 专题中详细介绍。详细参考 Jira ticket : https://issues.apache.org/jira/browse/HADOOP-8462
SEQUENCEFILE:这是一个基于键值对的二进制存储格式。它是优势是
SequenceFile 比文本文件更加紧凑,同时能够很好的兼容 MapReduce 的输出格式。SequenceFile 有3中压缩方式:Record & Block & Null。 你可以通过以下方式来启动 Blcok 级别的压缩:
jdbc:hive2://> SET hive.exec.compress.output=true; jdbc:hive2://> SET io.seqfile.compression.type=BLOCK;
不幸的是,文本文件和 SequenceFile 都是基于行级别的存储文件格式,对Hive 来说并不是最优的选择。由于 Hive 每次都需要读取整行数据,尽管只需要一列数据。因此 RCFile , ORC, Parquet 便应运而生了。它们用来解决文本文件和 SequenceFile所存在的限制。(这里需要了解一下
Avro 也是基于行的存储,由于在Avro系列中已经做了详细介绍,这里就不对Avro过多阐述了)
RCFile :它是柱状记录文件(Record
Columnar File)的简称。它是一个由二进制键值对组成的平面文件,与SequenceFile 有点相似。RCFile 是基于行组(row group)的水平数据分割。这里一个或者多个行组是 HDFS 中存储的文件。RCFile 通过首先将每一行的第一列来将行组数据保存为柱状格式,之后再对每一行的第二列,。。。这种格式是可分割的并且允许
Hive 跳过无关数据来更快更轻松得到数据结果。
ORC :它是 Optimized
Row Columnar的简写。从 Hive 0.11.0 版本才开始支持 ORC 格式。ORC 用来解决 RCFile部分性能问题。它提供了默认的 256MB 大小的 blcok ( RCFile 是 4MB, SequenceFile 是1MB)来对NameNode
节点上的高吞吐量和通过更少的 reducer端需要处理的文件来优化HDFS 中序列化文件的读取。与 RCFile 不同的是,ORC 需要依赖元数据来确认数据类型。它通过特定的编码器来识别数据类型,这样它就能根据不同类型进行压缩优化。ORC 同样支持基本列的统计方法:
MIN,
MAX,
SUM,
和
COUNT.以及使用一个轻量级的索引来跳过无关的行块。
Parquet :它是一个类似于 ORC 格式的行柱状文件格式。不同的是,相比较只支持 Hive 和 Pig 的ORC
格式,Parquet 在 Hadoop 生态系统中已经广泛支持许多项目。Parquet 利用 Google的最佳实践案例:Dremel 来支持嵌套的结构化数据。Parquet 支持从 Hive 0.10.0 版本开始就可以作为一个插件进行使用,知道
Hive 0.13.0 才开始得到本地支持。(Avro 是从 Hive 0.14 版本才得到本地支持)。
Google Dremel high level intruduce:http://research.google.com/pubs/pub36632.html
Google Dremel 原理(中文):http://www.yankay.com/google-dremel-rationale/
考虑到 Hive 的成熟度,还是建议在你的 Hadoop 环境中使用 ORC 格式作为主要的工具。如果你的 Hadoop 生态系统中使用多种 tools, Parquet 在适应性方面不失为一个更好的选择。
注意:Hadoop Archive
File (HAR)
是HDFS 中另一种打包文件的格式。它对HDFS中大量的小文件存储是可选的(并不是很好的选择)。由于将大量的小文件直接存储是非常低效的。HAR 目前仍然有以下的一些限制使得它无法出众:不可分割,兼容性比较差。更多关于 HAR 信息请参考维基百科:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Archiving.
1.2 压缩
为 Mapper 和 Reducer 中间数据和HDFS结果数据选择合适的压缩格式,在Hive 中能够明显的减小磁盘的 I/O,以至于Hive 查询也会有更好的性能。为了对 Hive 通过 MapReduce job 处理的文件进行压缩,我们需要通过 Hive CLI 或者hive-site.xml文件来设置以下属性(默认情况是
false):
jdbc:hive2://> SET hive.exec.compress.intermediate=true
接下来,我们就需要考虑应该配置哪一种压缩编码,Hadoop 和 Hive 中支持的通用压缩编码器如下所示:
压缩方式 | 编码方式 | 拓展名 | 可分割 |
---|---|---|---|
Deflate | org.apache.hadoop.io.compress.DefaultCodec | .deflate | N |
GZip | org.apache.hadoop.io.compress.GzipCodec | .gz | N |
Bzip2 | org.apache.hadoop.io.compress.BZip2Codec | .gz | Y |
LZO | com.hadoop.compression.lzo.LzopCodec | .lzo | N |
LZ4 | org.apache.hadoop.io.compress.Lz4Codec | .lz4 | N |
Snappy | org.apache.hadoop.io.compress.SnappyCodec | .snappy | N |
.deflate),压缩率和
CPU 成本都比 GZip 要高。Bzip2 是可分割的,但是直到 Hadoop 1.1 才支持分割(参考 Jira ticket :https://issues.apache.org/jira/browse/HADOOP-4012)。Bzip2
也由于高额的 CUP 开销使得压缩很缓慢。
LZO 文件并不是本地可分割,但是我们可以通过 com.hadoop.compression.lzo.LzoIndexer 创建一个索引来决定文件的分割,它很好的中和了CUP开销和压缩率(在后面会有专题介绍该内容)。LZ4
和 Snappy能够很好的处理一个 Job。
由于很多编码方法不支持压缩后可分割,所以不建议在 HDFS 中压缩大文件。
你可以通过
mapred-site.xml,
hive-site.xml或者
Hive CLI 来指定压缩编码器,如下所示:
jdbc:hive2://> SET hive.intermediate.compression.codec= . . . . . . .> org.apache.hadoop.io.compress.SnappyCodec
对指定的 Job 中间数据的压缩只会节省磁盘空间,但是需要多个 map 和 reduce job。为了进一步节省磁盘空间,Hive 的输出文件是可以被压缩的。可以通过设置
hive.exec.compress.output属性为 true.
Hive 可以通过配置 mapred.map.output.compression.codec 属性来对中间数据进行压缩。你可以从
hive-site.xml文件进行设置,或者在
Hive CLI 设置。
jdbc:hive2://> SET hive.exec.compress.output=true jdbc:hive2://> SET mapred.output.compression.codec= . . . . . . .> org.apache.hadoop.io.compress.SnappyCodec
1.3 存储优化
对于频繁用于扫描的数据,我们会称之为 Hot data。通常,对于hot data 的查询对整体性能来说是至关重要的。增加 hot data 在 HDFS 中的副本因子可以增加Hive job 本地查找命中率并且能够提高性能。这同样是衡量存储的一个方面:$ hdfs dfs -setrep -R -w 4 /user/hive/warehouse/employeeReplication 4 set: /user/hive/warehouse/employee/000000_0
另一方面,太多的文件或者冗余会耗尽NameNode 的内存,特别的对于大量的小于 Hadoop blcok 大小的文件。Hadoop 对于处理大量小文件问题的这种情况已经提出了解决方案。如下所示:
Hadoop Archive and HAR:用来打包小文件的工具集.
SequenceFile format : 将小文件压缩成大文件的一种格式.
CombineFileInputFormat : 一种在map
和 reduce 进程前整合小文件的输入格式。是 Hive 的默认
InputFormat( 参考:https://issues.apache.org/jira/browse/HIVE-2245)。
HDFS federation :它允许 NameNode 有更好的扩展性并且能够管理多个文件。
我们同样可以使用 Hadoop 生态系统中的其他工具来处理(在已经安装该工具的前提下),如下所示:
HBase 有更小的 block 大小和文件格式来处理小文件处理问题。
Flume NG 可以用来作为将小文件整合成大文件的管道( 关于 Flume-NG 请参考:/article/10611211.html)
通过离线的文件整合程序来将 HDFS 中小文件整合到一起。
对 Hive 来说,我们可以通过配置属性来将查询结果进行整合,避免创建小文件:
hive.merge.mapfiles: 将在只有
map 的job 中整合小文件,默认为
true.
hive.merge.mapredfiles:
在 MapReduce Job 最后进行整合小文件,可以设置为
true, 默认是
false.
hive.merge.size.per.task:
该属性定义了对于每个任务运行整合的文件最大值。默认是 256,000,000.
hive.merge.smallfiles.avgsize:
这是用来触发文件整合操作的阈值,默认是16,000,000.
当输出文件的平均大学都小于指定的
hive.merge.smallfiles.avgsize值,并且hive.merge.mapfiles 和 hive.merge.mapredfiles 都设置为true,Hive
会启动一个额外的 MapReduce Job 来整合输出文件为一个大文件。
相关文章推荐
- 点滴 UL
- idcheck 标识符合法性检查
- 如何让旧浏览器支持HTML5新标签
- SQLLDR
- Windows2008R2+iis7.5环境下的dz论坛X3版伪静态设置教程
- HDOJ 5499 SDOI(结构体排序)
- 欢迎使用CSDN-markdown编辑器
- Apache POI
- C语言优化实例:为了消除嵌套switch-case聪明的做法
- sql loader
- 数据结构(Java)——Set和Map的应用
- [JS复习] JS 基础知识
- 关于mvc5+EF里面的db.Entry(model).State = EntityState.Modified报错问题
- gcc and fPIC
- Binary Tree Paths
- WebView显示h5图片并点击放大过多后的内存泄漏问题
- LoadRunner 调用webservice Internal error, please call customer support. Details: class java.lang.Objec
- 南大软院大神养成计划--day17
- 忍一时得寸进尺, 退一步变本加厉。
- 2.Linux文件和目录