hive四种存储格式介绍与分析比较
1、TestFile
TextFile文件不支持块压缩,默认格式,数据不做压缩,磁盘开销大,数据解析开销大。这边不做深入介绍。
2、RCFile
Record Columnar的缩写。是Hadoop中第一个列文件格式。能够很好的压缩和快速的查询性能,但是不支持模式演进。通常写操作比较慢,比非列形式的文件格式需要更多的内存空间和计算量。
RCFile是一种行列存储相结合的存储方式。首先,其将数据按行分块,保证同一个record在一个块上,避免读一个记录需要读取多个block。其次,块数据列式存储,有利于数据压缩和快速的列存取。
3、ORCFile
存储方式:数据按行分块每块按照列存储,压缩快,快速列存取,效率比rcfile高,是 rcfile 的改良版本,相比RC能够更好的压缩,能够更快的查询,但还是不支持模式演进。
4、Parquet
Parquet能够很好的压缩,有很好的查询性能,支持有限的模式演进。但是写速度通常比较慢。这中文件格式主要是用在Cloudera Impala上面的。
压缩算法比较
1、gzip压缩
优点:压缩率比较高,而且压缩/解压速度也比较快;hadoop本身支持,在应用中处理gzip格式的文件就和直接处理文本一样;有hadoop native库;大部分linux系统都自带gzip命令,使用方便。
缺点:不支持split。
应用场景:当每个文件压缩之后在130M以内的(1个块大小内),都可以考虑用gzip压缩格式。譬如说一天或者一个小时的日志压缩成一个gzip文件,运行mapreduce程序的时候通过多个gzip文件达到并发。hive程序,streaming程序,和java写的mapreduce程序完全和文本处理一样,压缩之后原来的程序不需要做任何修改。
2、lzo压缩
优点:压缩/解压速度也比较快,合理的压缩率;支持split,是hadoop中最流行的压缩格式;支持hadoop native库;可以在linux系统下安装lzop命令,使用方便。
缺点:压缩率比gzip要低一些;hadoop本身不支持,需要安装;在应用中对lzo格式的文件需要做一些特殊处理(为了支持split需要建索引,还需要指定inputformat为lzo格式)。
应用场景:一个很大的文本文件,压缩之后还大于200M以上的可以考虑,而且单个文件越大,lzo优点越越明显。
3、snappy压缩
优点:高速压缩速度和合理的压缩率;支持hadoop native库。
缺点:不支持split;压缩率比gzip要低;hadoop本身不支持,需要安装;linux系统下没有对应的命令。
应用场景:当mapreduce作业的map输出的数据比较大的时候,作为map到reduce的中间数据的压缩格式;或者作为一个mapreduce作业的输出和另外一个mapreduce作业的输入。
4、bzip2压缩
优点:支持split;具有很高的压缩率,比gzip压缩率都高;hadoop本身支持,但不支持native;在linux系统下自带bzip2命令,使用方便。
缺点:压缩/解压速度慢;不支持native。
应用场景:适合对速度要求不高,但需要较高的压缩率的时候,可以作为mapreduce作业的输出格式;或者输出之后的数据比较大,处理之后的数据需要压缩存档减少磁盘空间并且以后数据用得比较少的情况;或者对单个很大的文本文件想压缩减少存储空间,同时又需要支持split,而且兼容之前的应用程序(即应用程序不需要修改)的情况。
最后用一个表格比较上述4种压缩格式的特征(优缺点):
注意:以上几种压缩算法都是在压缩普通文本的前提下来说的是否支持split,如果是RCFile、Sequence Files等,本身就支持split,经过压缩之后一样是支持split的。
综上,我们hadoop2.4集群要求RCFile+gzip是有一定道理的,首先RCFile格式的文件支持按列存储,同时支持split,而gzip的压缩率比较高,而且压缩/解压速度也比较快,所以RCFile格式的文件经过gzip压缩后既能保证文件能split,还能保证很高压缩/解压速度和压缩比。
Hive和RDBMS的区别
1.查询语言:HSQL为类SQL,可以进行一般的查询。没有SQL灵活好用
2.Hive数据在HDFS,而RDBMS数据在块设备或者本地文件系统
3.Hive通常不能进行update和delete(高版本可以开启ACID,需要ORC等等条件),RDBMS可以
4.Hive是MR计算,RDBMS有自己的计算引擎
5.Hive执行延迟高,适合大批量离线处理;RDBMS延迟低,大批量数据处理性能下降明显
6.Hive底层是HDFS,几千上万台;RDBMS受限,几百台
order by,sort by,clustered by,distribute by
order by:全局排序,一个reduce
sort by :每个reduce端排序,局部有序;优点:做完sort by 再做全局排序能提高效率;
distribute by:经常和sort by 搭配。先distribute by,相同的数据到相同的reduce(partition)再做sort by;
cluster by:等价于distribute by和sort by一起使用,但是cluster by只能降序
Hive Join分类
reduce join:inner join,left join,right join,full join,cross join(笛卡尔积)
map join:小表对大表,hive.mapjoin.smalltable.filesize=25000000
sort-merge-bucket join:大表 join 大表,后台会创建两张参与join的表,并分区分桶排序。 clustered by sort by
hive小文件问题
影响:NameNode 性能,MapReduce任务缓慢(小文件会增加MapTask);无数据倾斜,小表关联任务太慢
解决:合理的文件格式(sequence file 比text file好);
控制Reduce数量;
少用动态分区,用时记得distribute by分区;
hive.merg.mapfiles=true:合并map输出
hive.merge.mapredfiles=false:合并reduce输出
hive.merge.size.per.task=25610001000:合并文件的大小
hive.mergejob.maponly=true:如果支持CombineHiveInputFormat则生成只有Map的任务执行merge
hive.merge.smallfiles.avgsize=16000000:文件的平均大小小于该值时,会启动一个MR任务执行merge。
已有的小文件:HAR归档;重建表,设置合理的reduce数;
数据倾斜
表现:任务长时间卡在99%,某些任务时间远大于其他任务平均时间
原因:1.key分布不均匀,导致join时部分key集中在几个reduce上
2.count(distinct ) 特殊值过多
3.数据业务本身特点
4.Hive SQL存在数据倾斜
解决:1.空值产生的数据倾斜 – > 1️⃣ 空值数据单独管理,之后union 2️⃣ 空值赋值 特定值+随机数
2.设置hive.map.aggr = true map端部分聚合,相当于Combiner
3.count(distinct ) 特殊值类型不多,可以单独计算,再union;或者先group by,再做sum
4.不同的数据类型关联,需要先转换为相同的数据类型
5.map join
6.大表对大表,将倾斜的key通过采样得出,将倾斜的key的数据单独拿出来做mapjoin,最后union
\7. hive.groupby.skewindata=true控制生成两个MR Job 第一个MRJob 中,Map的输出结果集合会随机分布到Reduce中,每个Reduce做部分聚合操作,并输出结果,这样处理的结果是相同的GroupBy Key有可能被分发到不同的Reduce中,从而达到负载均衡的目的;第二个MRJob再根据预处理的数据结果按照GroupBy Key分布到Reduce中(这个过程可以保证相同的GroupBy Key被分布到同一个Reduce中),最后完成最终的聚合操作。
hiveSQL转化为MapReduce任务的过程
- Antlr定义SQL的语法规则,完成SQL词法,语法解析,将SQL转化为抽象语法树AST Tree
- 遍历AST Tree,抽象出查询的基本组成单元QueryBlock
- 遍历QueryBlock,翻译为执行操作树OperatorTree
- 逻辑层优化器进行OperatorTree变换,合并不必要的ReduceSinkOperator,减少shuffle数据量
- 遍历OperatorTree,翻译为MapReduce任务
- 物理层优化器进行MapReduce任务的变换,生成最终的执行计划
Hive目录下的.开头的数据不会被读取。
Java 写 parquet 文件时注意小文件问题,以及未关闭的文件无法被读取。需要定期合并小文件,并且在任务重启或者消费者rebanlance时需要删除未正常关闭的文件。