* 注:本文原创,转载请注明出处,本人保留对未注明出处行为的责任追究。
Hive的一些优化:
优化方向:
1)表的调整:
外部表: 防止数据被删除
分区表: 将数据依据某字段aaa分入不同的目录,使得查找的数据量迅速降低
例如: 以month为分区字段,假如每月产生10TB数据,此时就不需要从120TB数据中进行查找,而是依据where month ? 等条件直接查找1个或多个10TB数据即可
另外,这10TB数据会分别存储在 /user/hive/warehouse/xxx.db/month=xxxxxx/下。
大表的拆分:通过as select 方式对大表进行拆分,将它们分别拆入分区表进行存储
2)数据格式与压缩 这部分详细一些可以参考我的另一篇blog:https://www.cnblogs.com/yosql473/p/10756906.html
数据格式: OLAP建议采用诸如Parquet、ORCFILE等列式存储格式,采用这些格式一是方便压缩,二是节省读取资源,读取数据不再需要像行式存储一般将所有的字段读入,只需从索引中查询到指定列,
读出进行处理即可。
数据压缩: 采用Snappy或者Lzo这些有一定压缩能力,主要是压缩解压性能高的压缩算法进行压缩。
3)MR优化
这部分主要参考: https://www.cnblogs.com/wcwen1990/p/7601252.html,感谢
Map Task :
为什么Map Task数量不能过多? 1.过多的Map任务会产生大量的小的中间文件,从而导致namenode中元数据存储内存增大。 2.map的启动会花大量的资源,过多的map进行处理如果小题大做会浪费大量资源.
Map的数量与2个因素有关: 1.input的文件数量和大小 2.文件块的大小:可以在hive中设置dfs.block.size进行调整。
例如: 有4个文件 分别为 100M,200M,300M,400M ,hadoop默认块大小为128M,因此这4个文件分为: 1 + 2 + 3 + 4 = 10个块,因此就有10个mapper任务进行处理
调大思路:将dfs.block.size进行调大(默认大小为128M)。
Reduce Task:
为什么Reduce Task数量不能过多? 1.过多的Reduce任务会产生大量的小的结果文件,从而导致namenode中元数据存储内存增大。2.Reduce也会占用大量资源
Reduce数量的影响因素: 1.每个reducer任务处理的数据量 2.任务的最大reducer数目 3.输入的总数据量 N = min(每个人物的最大reducer数据量 , 该任务总数据量/每个reduce任务处理的数据量)
hive.exec.reducers.bytes.per.reducer(每个reduce任务处理的数据量,默认为1000^3=1G)
hive.exec.reducers.max(每个任务最大的reduce数,默认为999) 计算reducer数的公式很简单N=min(参数2,总输入数据量/参数1)调整思路: 把每个任务的最大reducer数据量调小,把每个reduce task处理的数据量调大
JVM重用
推测执行
4)Join优化 TODO
map join : map join 适用于一张大表与小表的连接操作,大表从文件中读取,小表数据通过DistributedCache这个类加载进内存,再从内存中取得。也就是大表在磁盘、小表在内存。
reduce join/shuffle join/common join: shuffle join 适用于一张大表与大表的一般join,也就是我们寻常进行大表连接大表时,如果没有设置分桶,就会走这个reduce join,大表连接大表,每个表都是从文件中进行读取。
smb join :全称为Sort-Merge-Bucket Join ,很明显与 哈希 + join + 合并的大数据合并思路吻合,首先依据连接字段进行分表,因此连接字段相同的纪律都会被分到相同的分桶,两表相同序号的分桶进行join。
5)SQL优化 TODO
fetch task