背景

在刚使用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. java --Method

    MethodDemo class MethodDemo { public static void main(String[] args) { //调用自定义的方法. draw(4,5); draw(8 ...

  2. (转)Linux ldconfig 与 ldd指令

    原文:https://blog.csdn.net/iamzhangzhuping/article/details/49203981 一.ldconfig ldconfig是一个动态链接库管理命令,为了 ...

  3. Failed to create prime the NuGet cache

    在centos 7上使用dotnet core时: dotnet core 安装环境在root下完成,并成功运行“hello world”程序.切换到其他账户使用dotnet命令时,报“Failed ...

  4. linux 下screen 使用

    screen命令的常规用法: screen -d -r:连接一个screen进程,如果该进程是attached,就先踢掉远端用户再连接. screen -D -r:连接一个screen进程,如果该进程 ...

  5. Eclipse中Maven项目出现红色感叹号问题

    在Eclipse环境下,有时我们会遇到Maven项目出现红色感叹号的情形,而一旦项目出现感叹号,Eclipse便无法帮我们进行自动编译等工作,尽管有时候不会影响运行,但每次只能手动启动Maven重新编 ...

  6. NoSQL数据库--简介

    一.What's NoSQL? NoSQL,全称是”Not Only Sql”,指的是非关系型的数据库.这类数据库主要有这些特点:非关系型的.分布式的.开源的.水平可扩展的.原始的目的是为了大规模we ...

  7. 不用bootstrap,只用CSS创建网格布局

    本文译自[http://j4n.co/blog/Creating-your-own-css-grid-system],英语好的,可直接查看原网页,不需要FQ. 翻译拿不准的地方会有英文原文,方便大家理 ...

  8. [转]UTF-8 encoding support for the BCP utility and BULK INSERT Transact-SQL command in SQL Server 2014 SP2

    本文转自:https://support.microsoft.com/en-us/help/3136780/utf-8-encoding-support-for-the-bcp-utility-and ...

  9. 淺談 Entity 的概念

    延續上一篇文章<Drupal Commerce 概念架構>,本來打算要繼續講 Commerce 與 Views 整合的主題.不過由於這個主題牽涉到 Views 中的 Relationshi ...

  10. .NET编译过程

    总结一下.NET的编译过程, 一般的高级编程语言会把代码编译成机器码,也就是我们说的非托管代码,执行在编译它的电脑上. 而.NET编译代码的时候会把高级编程语言编译成中间语言 运行在CLR(公共语言运 ...