这一篇博文是【大数据技术●降龙十八掌】系列文章的其中一篇,点击查看目录:大数据技术●降龙十八掌
-
小系列列表
-
【十八掌●武功篇】第十掌:Hive之基本语法
【十八掌●武功篇】第十掌:Hive之原理与优化
【十八掌●武功篇】第十掌:Hive之高级知识
【十八掌●武功篇】第十掌:Hive之安装过程实践
一、 Hive文件格式
1、 常见文件格式
Hive中的文件格式常见的有:textfile文件格式、sequencefile二进制序列化文件格式、rcfile、orc、parquet。hive表的文件格式一般是在创建表时用stored as语句声明,如:
create table demo_textfile
(
id int,
name string
)
stored as textfile;
其中textfile和sequencefile是以行存储数据的,rcfile、orc、parquet是列式存储的。
- TextFile是Hive的默认文件格式,数据不做压缩,磁盘开销比较大,数据解析时开销也比较大。从本地文件向Hive load数据只能用textfile文件格式。 (2) SequenceFile格式
- SequenceFile是Hadoop API提供的一种二进制文件支持,其具有使用方便、可分割、可压缩的特点。SequenceFile文件是含有键-值对的二进制文件。 (3) Rcfile格式
- Rcfile是一种行列存储结合的存储方式,首先将数据按行分块,保证同一个记录在一个块上,避免读取一行记录需要读取多个块的情况,然后块数据列式存储,这样有利于数据压缩和列存取。 (4) Orc格式
-
Orc格式是Rcfile格式的升级版,性能有很大的提升,并且数据可以压缩存储,比textfile文件压缩比可以达到70%,同时读取性能也非常高,推荐使用orc文件格式创建表。
● 单个Hive Task输出单个文件,减小文件系统负载。
● 支持datetime、decimal和其他复杂类型(struct、list、map和union)。
● 文件内含轻量级索引。减少不必要的扫描,高效定位记录。
● 基于数据类型的块模式压缩。例如String和Integer可以采用不同的压缩方式。
● 同一文件可以利用多个RecordReader并发读取。
● 支持免扫描进行文件分块。
● 读写文件时,绑定I/O所需的最大内存空间。
● 文件的metadata采取Protocol Buffers格式,允许灵活的属性增删。
(5) Parquet格式
-
Parquet是一种适合多种计算框架的文件格式,Parquet是语言无关的,并且不与任何一种数据处理框架绑定在一起,适配多种语言和组件,能够与parquet配合的组件有:
查询引擎:Hive、Impala、Pig、Presto、Drill、Tajo、HAWQ、IBM Big SQL。
计算框架:MapReduce、Spark、Cascading、Crunch、Scalding、Kite
所以如果一套数据要多种引擎使用,Parquet是最好的选择。
存储方式 | 文件格式 | 输入输出格式 | |
---|---|---|---|
行式存储 | textfile | InputFormat | org.apache.hadoop.mapred.TextInputFormat |
OutputFormat | org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat | ||
sequencefile | InputFormat | org.apache.hadoop.mapred.SequenceFileInputFormat | |
OutputFormat | org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat | ||
列式存储 | rcfile | InputFormat | org.apache.hadoop.hive.ql.io.RCFileInputFormat |
OutputFormat | org.apache.hadoop.hive.ql.io.RCFileOutputFormat | ||
orc | InputFormat | org.apache.hadoop.hive.ql.io.orc.OrcInputFormat | |
OutputFormat | org.apache.hadoop.hive.ql.io.orc.OrcInputFormat | ||
parquet | InputFormat | org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat | |
OutputFormat | org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat |
2、 列式存储
-
(1) 数据存储方式
-
目前大数据存储有两种方案可以供选择:行存储、列存储。
物理存储上,行存储是一行中各列顺序存储,列存储是一列中各行的值顺序存储。
行存储和列存储各有优缺点:
● 行存储的写入是一次性完成的,消耗的时间比列存储少,并且能够保证数据的完整性,缺点是数据读取过程中会产生冗余数据,如果数据量大会影响到数据的处理效率。
● 列存储在写入效率、保证数据完整性方面不如行存储,但是他的优势在于读取过程,不会产生冗余数据
(2) 列式存储在大数据存储中的优势
-
● 可以跳过不符合条件的数据,只读取需要的数据,降低IO数据量。
● 由于同一列的数据类型是一样的,所以可以使用更高效的压缩编码方式,最大限度地节约存储空间。
● 只读取需要列,能够获取更好的扫描性能。
3、 自定义表的文件格式
创建表的时候也可以自定义其他的文件格式,用自定义文件格式时需要制定InputFormat、OutputFormat和SerDe
二、 Hive压缩方法
1、 压缩的原因
Hive最终是转为MapReduce程序来执行的,而MapReduce的性能瓶颈在于网络IO和磁盘IO,要解决性能瓶颈,最主要的是减少数据量,对数据进行压缩是个好的方式。
压缩虽然是减少了数据量,但是压缩过程要消耗CPU的,但是在Hadoop中,往往性能瓶颈不在于CPU,CPU压力并不大,所以压缩充分利用了比较空闲的CPU。
2、 Hadoop常用压缩方法
压缩格式 | 是否可拆分 | 是否自带 | 压缩率 | 速度 | 是否hadoop自带 |
---|---|---|---|---|---|
gzip | 否 | 是 | 很高 | 比较快 | 是 |
lzo | 是 | 是 | 比较高 | 很快 | 否,要安装 |
snappy | 否 | 是 | 比较高 | 很快 | 否,要安装 |
bzip2 | 是 | 否 | 最高 | 慢 | 是 |
各个压缩格式对应的类:
-
● 压缩比率
● 压缩解压速度
● 是否支持split
所有的压缩算法都是空间和时间上做出的一种平衡,即牺牲时间换空间还是牺牲空间换时间。例如:在对实时性比较高的应用场景中,一般要求压缩和解压的速度高;而对一般的大文件存储时,则更注重节省压缩存储空间。
(2) map的输入压缩
- 最好选择一种支持split的压缩方式,如果选择不支持split的压缩方式,大文件将会由一个map进程进行处理。如果要选择不支持的split压缩方式,那么就先将大文件进行分割成大小接近128M的小文件,然后对这些小文件进行单独压缩。 (3) map的输出压缩
- map的输出压缩,要注重考虑压缩解压速度,常用的用snappy压缩, (4) reduce端的输出
-
很少对reduce端的输出进行压缩,但是一下两个场景会对使用压缩
● reduce输出结果后面甚少使用,一般要用压缩以提高性能。一般使用压缩比率比较高的压缩格式。
● 迭代计算时,reduce输出结果要给下一个job做为输入使用,着重使用压缩解压速度比较快的方式。
压缩格式 | 类 |
---|---|
Zlib | org.apache.hadoop.io.compress.DefaultCodec |
Gzip | org.apache.hadoop.io.compress.GzipCodec |
Bzip2 | org.apache.hadoop.io.compress.BZip2Codec |
Lzo | org.apache.hadoop.io.compress.lzo.LzoCodec |
Lz4 | org.apache.hadoop.io.compress.Lz4Codec |
Snappy | org.apache.hadoop.io.compress.SnappyCodec |
3、 配置Hadoop压缩解压
在Hadoop的mapred-site.xml配置文件中的配置。
参数 | 备注 |
---|---|
mapreduce.map.output.compress | map输出是否启用压缩 |
mapreduce.map.output.compress.codec | map输出采用压缩方式 |
mapreduce.output.fileoutputformat.compress | 是否启用reduce输出压缩 |
mapreduce.output.fileoutputformat.compress.codec | reduce压缩方式 |
mapreduce.output.fileoutputformat.compress.type | 压缩级别:NONE, RECORD(行级别), BLOCK(块级别) |
4、 Hive中的压缩
在Hive中,只有当属性hive.exec.compress.intermediate设置为true,以上hadoop设置的压缩才生效。如果Hive SQL被翻译成多个MapReduce时,这个属性不单单控制MapReduce中map的输出结果压缩,也控制着job之间的输出输入的压缩。
<property>
<name>hive.exec.compress.intermediate</name>
<value>true</value>
<description>
This controls whether intermediate files produced by Hive between multiple map-reduce jobs are compressed.
The compression codec and other options are determined from Hadoop config variables mapred.output.compress*
</description>
</property>
三、 Hive SQL转换为MapReduce过程
Hive是将SQL转化为MapReduce任务要经过解释、编译。
-
整译过程分为六个阶段:
-
(1) Antlr定义SQL的语法规则,完成SQL词法,语法解析,将SQL转化为抽象语法树AST Tree
(2) 遍历AST Tree,抽象出查询的基本组成单元QueryBlock
(3) 遍历QueryBlock,翻译为执行操作树OperatorTree(逻辑执行计划)
(4) 逻辑层优化器进行OperatorTree变换,合并不必要的ReduceSinkOperator,减少shuffle数据量
(5) 遍历OperatorTree,翻译为MapReduce任务
(6) 物理层优化器进行MapReduce任务的变换,生成最终的执行计划
四、 Hive解释器
Hive解释器是将Hive SQL语句转换为抽象语法树AST,过程 分为解析和生成语法树两个步骤。
1、 词法语法解析
Antlr是一种语言识别工具,可以用来构造领域语言,使用Antlr构造特定的语言需要编写一个语法文件,定义词法和语法替换规则。
Hive使用Antlr实现SQL的词法和语法解析,完成词法分析、语法分析、语义定义、中间代码生成的过程。Hive中有五个文件记录着词法规则和语法规则:
词法规则文件:HiveLexer.g。
语法规则文件:SelectClauseParser.g、FormClauseParser.g、IdentifiersParser.g、HiveParser.g。
2、 生成抽象语法树
在词法和语法解析的同时,Antlr生成一个抽象语法树。
五、 Hive编译器
Hive编译器是将抽象语法树编译为逻辑执行计划。
抽象语法树是比较复杂的,不够结构化,不方便直接翻译为MapReduce程序,所以Hive编译器会将抽象语法树再进一步抽象和结构化为逻辑执行计划。
六、 Hive优化器
Hive优化器是对逻辑执行计划进行优化。
大部分逻辑层优化器通过变换OperatorTree,合并操作符,达到减少MapReduce Job,减少Shuffle数据量的目的。
名称 | 作用 |
---|---|
② SimpleFetchOptimizer | 优化没有GroupBy表达式的聚合查询 |
② MapJoinProcessor | MapJoin,需要SQL中提供hint,0.11版本已不用 |
② BucketMapJoinOptimizer | BucketMapJoin |
② GroupByOptimizer | Map端聚合 |
① ReduceSinkDeDuplication | 合并线性的OperatorTree中partition/sort key相同的reduce |
① PredicatePushDown | 谓词前置 |
① CorrelationOptimizer | 利用查询中的相关性,合并有相关性的Job,HIVE-2206 |
ColumnPruner | 字段剪枝 |
上表中带①符号的,优化目的都是尽量将任务合并到一个Job中,以减少Job数量,带②的优化目的是尽量减少shuffle数据量。
七、 Hive执行器
Hive执行器是调用底层的框架,执行优化好的逻辑执行计划。
编译器将操作树切分为一个Task链(DAG),执行器会顺序执行其中的所有Task,如果Task链不存在依赖关系时,可以采用并发执行的方式进行Job执行。
这一篇博文是【大数据技术●降龙十八掌】系列文章的其中一篇,点击查看目录:大数据技术●降龙十八掌