背景

在刚使用hive的过程中,碰到过很多问题,任务经常需要运行7,8个小时甚至更久,在此记录一下这个过程中,我的一些收获

join长尾

背景

SQL在Join执行阶段会将Join Key相同的数据分发到同一个执行Instance上处理。如果某个Key上的数据量比较多,会导致该Instance执行时间比其他Instance执行时间长。其表现为:执行日志中该Join Task的大部分Instance都已执行完成,但少数几个Instance一直处于执行中,这种现象称之为长尾

长尾类别&优化方法

小表长尾

Join倾斜时,如果某路输入比较小,可以采用Mapjoin避免倾斜。Mapjoin的原理是将Join操作提前到Map端执行,这样可以避免因为分发Key不均匀导致数据倾斜。但是Mapjoin的使用有限制,必须是Join中的从表比较小才可用。所谓从表,即Left Outer Join中的右表,或者Right Outer Join中的左表。

热点值长尾

如果是因为热点值导致长尾,并且Join的输入比较大无法用Mapjoin,可以先将热点Key取出,对于主表数据用热点Key切分成热点数据和非热点数据两部分分别处理,最后合并。我们举一个电商的例子,假设我们需要计算所有商品的pv。我们有如下两张表

日志表 log 用户点击的日志, 包含商品的id p_id

商品表 product 包含商品名称 p_name, 商品id p_id

  • 取热点值, 取商品pv大于10000的商品到临时表
INSERT TABLE topk_product
SELECT
distinct p_id
FROM
(
SELECT
p_id,
count(1) AS pv
FROM log
GROUP BY p_id
) a
WHERE pv >= 10000
  • 取出非热点值和商品(product) join 得到非热点商品的pv
SELECT p.p_id
, p.p_name
, l.pv
FROM (
SELECT p_id
, p_name
FROM product
) p
JOIN (
SELECT /*+mapjoin(b)*/ a.*
FROM (
SELECT p_id
, COUNT(1) AS pv
FROM log
) a
LEFT OUTER JOIN (
SELECT p_id
FROM topk_product
) b
ON a.p_id = b.p_id
AND b.p_id IS NULL
) l
ON p.p_id = l.p_id
  • 取出热点值和商品(product) join 得到热点商品的pv
SELECT p.p_id
, p.p_name
, l.pv
FROM (
SELECT /*+mapjoin(b)*/ a.*
FROM (
SELECT p_id
, p_name
FROM product
) a
JOIN (
SELECT p_id
FROM topk_product
) b
ON a.p_id = b.p_id
) p
JOIN (
SELECT /*+mapjoin(d)*/ c.*
FROM (
SELECT p_id
, COUNT(1) AS pv
FROM log
) c
JOIN (
SELECT p_id
FROM topk_product
) d
ON c.p_id = d.p_id
) l
ON p.p_id = l.p_id
  • union all 热点和非热点的数据

空值长尾

join时,假设左表(left_table)存在大量的空值,空值聚集到一个reduce上。由于left_table 存在大量的记录,无法使用mapjoin 。此时可以使用 coalesce(left_table.key, rand()*9999)将key为空的情况下赋予随机值,来避免空值集中造成长尾。

map长尾

Map端读取数据时,由于文件大小分布不均匀,一些map任务读取并处理的数据特别多,一些map任务处理的数据特别少,造成map端长尾。这种情形没有特别好的方法,只能调节splitsize来增加mapper数量,让数据分片更小,以期望获得更均匀的分配。

reduce长尾

由于Distinct操作的存在,数据无法在Map端的Shuffle阶段根据Group By先做一次聚合操作,减少传输的数据量,而是将所有的数据都传输到Reduce端,当Key的数据分发不均匀时,就会导致Reduce端长尾,特别当多个Distinct同时出现在一段SQL代码中时,数据会被分发多次,不仅会造成数据膨胀N倍,也会把长尾现象放大N倍。

我们用代码举个例子:

只有一个distinct 的情况

  • 原sql
SELECT D1
, D2
, COUNT(DISTINCT CASE
WHEN A IS NOT NULL THEN B
END) AS B_distinct_cnt
FROM xxx
GROUP BY D1,
D2
  • 改后的sql
create table tmp1
as
select D1,D2,B,
count( case when A is not null then B end ) as B_cnt
from xxx
group by D1, D1, B select D1,D2,
sum(case when B_cnt > 0 then 1 else 0 end) as B_distinct_cnt
from tmp1
group by D1,D2

多个distinct的情况

  • 原始sql
select D1,D2,
count(distinct case when A is not null then B end) as B_distinct_cnt ,
count(distinct case when E is not null then C end) as C_distinct_cnt
from xxx group by D1,D2
  • 修改后的sql
create table tmp1
as
select D1,D2,B,
count( case when A is not null then B end ) as B_cnt
from xxx
group by D1, D1, B create table tmp1_1
as
select D1,D2,
sum(case when B_cnt > 0 then 1 else 0 end) as B_distinct_cnt
from tmp1
group by D1,D2 create table tmp2
as
select D1,D2,C,
count( case when E is not null then C end ) as C_cnt
from xxx
group by D1, D1, C create table tmp2_1
as
select D1,D2,
sum(case when C_cnt > 0 then 1 else 0 end) as C_distinct_cnt
from tmp1
group by D1,D2 select
t1.D1,t1.D2,
t1.B_distinct_cnt,
t2.C_distinct_cnt
from tmp1_1 t1
left outer join tmp2_1 t2
on t1.D1=t2.D1 and t1.D2=t2.D2

HiveSql调优经验的更多相关文章

  1. GC浅析之三-性能调优经验总结

    性能调优经验总结 问题的出现: 在日常环境下,以某server 为例,该机器的每秒的访问量均值在368左右,最大访问量在913.对外提供服务的表现为每两三个小时就有秒级别的时间客户端请求超时,在访问量 ...

  2. JVM性能调优经验总结

    本文转载自JVM性能调优经验总结 说明 调优是一个循序渐进的过程,必然需要经历多次迭代,最终才能换取一个较好的折中方案. 在JVM调优这个领域,没有任何一种调优方案是适用于所有应用场景的,同时,切勿极 ...

  3. jvm 性能调优 经验总结---转

    最近因项目存在内存泄漏,故进行大规模的JVM性能调优 , 现把经验做一记录. 一.JVM内存模型及垃圾收集算法 1.根据Java虚拟机规范,JVM将内存划分为: New(年轻代) Tenured(年老 ...

  4. jvm调优经验分享

    当Java程序申请内存,超出VM可分配内纯的时候,VM首先可能会GC,假设GC完还是不够,或者申请的直接超够VM可能有的,就会抛出内 存溢出异常.从VM规范中我们能够得到,一下几种异常. java.l ...

  5. spark调优经验(待续)

    spark调优是须要依据业务须要调整的,并非说某个设置是一成不变的,就比方机器学习一样,是在不断的调试中找出当前业务下更优的调优配置.以下零碎的总结了一些我的调优笔记. spark 存储的时候存在严重 ...

  6. 一份 Tomcat 和 JVM 的性能调优经验总结!拿走不谢

    Tomcat性能调优 找到Tomcat根目录下的conf目录,修改server.xml文件的内容.对于这部分的调优,我所了解到的就是无非设置一下Tomcat服务器的最大并发数和Tomcat初始化时创建 ...

  7. HiveSql调优系列之Hive严格模式,如何合理使用Hive严格模式

    目录 综述 1.严格模式 1.1 参数设置 1.2 查看参数 1.3 严格模式限制内容及对应参数设置 2.实际操作 2.1 分区表查询时必须指定分区 2.2 order by必须指定limit 2.3 ...

  8. Etl之HiveSql调优(设置map reduce 的数量)

    前言: 最近发现hivesql的执行速度特别慢,前面我们已经说明了left和union的优化,下面咱们分析一下增加或者减少reduce的数量来提升hsql的速度. 参考:http://www.cnbl ...

  9. Etl之HiveSql调优(left join where的位置)

    一.前言 公司实用Hadoop构建数据仓库,期间不可避免的实用HiveSql,在Etl过程中,速度成了避无可避的问题.本人有过几个数据表关联跑1个小时的经历,你可能觉得无所谓,可是多次Etl就要多个小 ...

随机推荐

  1. 对Deeplung检测+两样性分类的一个整合

    整体的流程分为以下几步: 读取原始数据(.mhd文件)——> 生成mask ——> 对数据预处理 ——> 执行检测 ——> 对检测结果进行分类 ——>可视化 懒一点,不贴 ...

  2. Java之集合(十五)Set综述

    转载请注明源出处:http://www.cnblogs.com/lighten/p/7427554.html 1.前言 原本按照顺序应该是list.queue然后就是set的讲解,但是因为set的实现 ...

  3. 【数组】Maximum Product Subarray

    题目: Find the contiguous subarray within an array (containing at least one number) which has the larg ...

  4. 【数组】Spiral Matrix II

    题目: Given an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order. ...

  5. lower类的accessCode解读

    /** Access codes for dereferencing(解引用), assignment, * and pre/post increment/decrement. * Access co ...

  6. ztree树的递归

    function clickAssignBtn(){ $('#assignBtn').off('click').on('click',function(){ var checkFlag=getRole ...

  7. shell中的(),{}几种语法用法

    转自:https://www.cnblogs.com/HKUI/p/6423918.html 查看脚本语法是否有错误:bash -n modify_suffix.sh跟踪执行sh -x modify_ ...

  8. facebook 摘要生成阅读笔记(一) A Neural Attention Model for Sentence Summarization

    流程: 1.文本和摘要全部输入到模型中. 2.训练时,对生成摘要取前C个词,从头开始取,如果生成的摘要不足C,那么不足的地方直接补<s>. 3.训练时,最大化生成的摘要与原摘要的概率,即每 ...

  9. nlp 总结 分词,词义消歧,词性标注,命名体识别,依存句法分析,语义角色标注

    分词 中文分词 (Word Segmentation, WS) 指的是将汉字序列切分成词序列. 因为在汉语中,词是承载语义的最基本的单元.分词是信息检索.文本分类.情感分析等多项中文自然语言处理任务的 ...

  10. lucene源码分析(3)facet实例

    简单的facet实例 public class SimpleFacetsExample { private final Directory indexDir = new RAMDirectory(); ...