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的东西