Hive原理及优化

 

1.  join原理(common join)

join 以连接字段为key,通过shuttle的过程,将待连接的两张表的相同key的记录打到一个reduce节点上,在该节点上对这两张表的记录进行合并。

还有一种特殊的join方式 就是map join。顾名思义就是在在map端进行join,

其实现的基础是小表放入内存和大表比对,然后完成join。如果产生了数据倾斜,而且符合

这种大小表的特征,就可以使用mapjoin

报了数据倾斜,但是倾斜在哪里?是否分配到某一个reduce节点是否是有连接键来决定的。??

如果是应该据此来对连接键的分布进行分析。这又涉及到join原理。

## group by原理

以group by字段组合作为key,然后通过shuttle的过程,将key值相同打到同一个节点

## 分区

分区:根据业务需要将一个大的数据集划分为若干个小的数据集

划分标准:1、要起到划分的效果,如果一列仅有两个列值,分成两块很明显没有起到划分的效果。如果划分选取user_id之类的会导致划分过多,形成很多小文件,hdfs本身就适合大文件存储,不适合小文件,而且小文件过多也会影响job运行。

2. 划分后增长均匀,数据分布均匀

使用partition by语句指定分区,

从逻辑上看就是子数据集,从物理存储来看分区对应着hdfs文件系统的一个文件夹。

比如我们分区一般使用dt,使用dt分区数的增长是均匀的,而且分区的体积的增长也是相对均匀的。

3、分区之动态分区/静态分区

http://www.aboutyun.com/thread-14558-1-1.html

hive默认是静态分区,每次插入数据的时候都必须指定分区值(by dt 要指出数据插入到dt='20170523'中,至于没有该分区会不会会不会自动创建),动态分区就自动插入,不用每次指定具体插入那个分区。

动态分区:

(1) hive.exec.max.dynamic.partitions.pernode

查询在某个节点上可以创建的最大动态分区数 ,默认100

(2) hive.exec.max.dynamic.partitions

一个HiveQL语句可以创建的最大动态分区数 ,默认1000

(3)hive.exec.max.created.files

一个查询总共可以创建的最大动态分区数 ,默认1000000

https://zhuanlan.zhihu.com/p/24906106

分区与distribute by之间的关系,后者是指定数据以何种形式分发到reduce。这种dis后面跟着分区列,

是不是意味着 同一个分区的就分配到一个reduce节点。不适用dis是不是就会以默认的连接join连接键的值来决定数据往reduce的分配方式?这样是不是会出现非常多的分区,是不是意味着一个mapred任务会创建很多分区导致分区溢出?

## 并行化

该配置参数是将没有依赖关系的stage并行执行

2 关于桶的概念

http://www.jianshu.com/p/6970c47eec5c

桶是表-->分区--》下一级的概念,是记录的存储位置。通过对列值的hash计算,决定记录放到哪个桶中。这样进行表join时候,表连接字段相同,两条记录必将在一个桶中,在该桶中直接进行join就行。能有效提升运行效率。

## 数据倾斜

http://tech.meituan.com/hive-sql-to-mapreduce.html

过多的数据打到了一个节点,

比如join、group by的倾斜是以为过多的数据到了一个节点上。比如存在大量空置或者某个特殊值。

但是count distinct为什么会导致倾斜??

map和reduce的个数

http://lxw1234.com/archives/2015/04/15.htm

其实就是map启动时间和逻辑处理时间的权衡问题

如果每个文件都很小 这样启动时间远大于逻辑处理时间,这个时候就需要我们合并文件

反之如果文件大小可以,但是逻辑处理非常复杂 远大于启动时间,就算我们拆分后每个的逻辑处理时间依然大于启动时间,我们则可以增加map/reduce数目

3 NaN

http://kevin12.iteye.com/blog/1905224

hive和Java一样,0/0会报错,0.0/0.0会得到一个NaN

4 hive 文件格式

ORC文件格式  存储压缩效率高  查询快 加载慢

text文本格式    存储耗费空间大  查询慢 加载快

Q&A  

1.ORC文件格式在修改表结构的情况下,测试上线操作和文本格式相同吗?

5 xt平台与HIve部分参数

对于公司的平台对每个节点的分区数限制在150不能更改(总分区数这个参数可以修改),因此对于too many dynamic partitions只能用distribute by来处理。

对于该产品,是跑全量的并没有分区,

group by
yespoi.wk,
yespoi.poi_id,
if(tag.category_id=-1 or tag.category_id is null,-2,tag.category_id),
coalesce(tag.category_name,'全部')
distribute by poi_id;

1. distribute 并不依赖于分区

2. distribute并不能简单的理解成一个节点上只有一个distribute后面字段的值,

以poi_id来分,poi_id有几十万很明显这个是不对的

note: 如果有个场景 由天计算出月比如 group by mo,poi_id,aor_id这种

distribute by后面跟上所有的汇总维度是不是较好的,还是仅仅group by mo??

因此对于修改partition.pernode是没有用的,必须使用distribute by才有用

http://lxw1234.com/archives/2015/06/286.htm

http://blog.csdn.net/cssdongl/article/details/77750503

http://superlxw1234.iteye.com/blog/1677938

每个节点创建文件数

https://www.iteblog.com/archives/1533.html

0 其他问题

hive 关键字不能作为字段名 比如 desc是描述的简写但是也是关键字

hive 没有 not in

6. 参数设置

1 mapjoin

mapjoin默认开启,小表能否装进内存取决于是否大于设置的临界值。如果不行,可以适当调高该参数。

2 mapreduce设置

https://www.iteblog.com/archives/1697.html

现在hive的机制是如果设置了直接以指定的参数为准,如果没有就用input size/bytesPerReducer(默认1G)

这种计算出来的问题在于input size是输出文件大小而不是map输出文件大小。

reduce太多太小都不合适。

http://blog.csdn.net/oopsoom/article/details/34104115

问题在于让系统自动算和自己指定都有不足,有没有一个最佳实践

3 job数

并行优先

但是不能为了并行而搞类似union all的东西

http://www.cnblogs.com/Dhouse/p/7134396.html  

猜你喜欢

转载自blog.csdn.net/xinjianwuhen1991/article/details/81429874