Hive下什么是数据倾斜问题?

Hive下的数据倾斜的场景

在我们的学习,还是生活中,经常会出现数据倾斜的问题,那么什么是数据倾斜问题呢,让我们来复现一下我们的要求。
首先,我写了两个表,其中user表5000万数据量,观影表2亿条数据,现如今需要的是,各个年龄段的观影数量排名。
环境:

  1. hadoop 2.7
  2. hive 1.2.1
  3. centos 6.8 虚拟机 1核 8G

来吧让我们愉快的去创造数据把

import java.io.{File, PrintWriter}
import java.util.UUID

import scala.util.Random

/**
  * Copyright (c) 2019 wu ALL Rights Reserved
  *
  * Project: ScalaLanguage
  * Package: 
  * Version: 1.0
  * Created by HeartisTiger on 2019/9/8 21:19
  */
object Test01 {
  def main(args: Array[String]): Unit = {
    val ran = new Random()
    val ages =  Array[Int](15,13,25,26,27,28,29,30,32,34,38,39,40,41,58,52,61,70,80)
    var age = 0;
    val print1 = new PrintWriter(new File("user.txt"))
    val print2 = new PrintWriter(new File("movies.txt"))
    var name = ""
    for(uid <- 1 to 50000000){
        age = ages(ran.nextInt(ages.length))
      name = UUID.randomUUID().toString
      print1.println(s"$uid,$name,$age")
    }
    for(uid <- 1 to 200000000){
           val uid = ran.nextInt(50000000)
           val url = UUID.randomUUID().toString
            print2.println(s"$uid,$url")
    }
    print1.close()
    print2.close()
  }
}

此时我们可以想到,看电影的年龄段,什么时候的看电影最多呢,肯定是我们的20-30-40岁依次递进的,其他的看电影的并不没有以上的年龄段的观影次数多。当然生产环境中年龄肯定不是数字表示,是用生日表示的,为了方便起见我们用年龄来制作我们的模拟数据。

movies.txt
user.txt
这里是截取的我们的数据,我们想要求出来这个需求,我们首先应该是建立我们的测试数据表。
创建表

create table user(
id int,
name string,
age string
)
row format delimited fields terminated by ','
stored as textfile;
create table movies(
id int,
url string)
row format delimited fields terminated by ','
stored as textfile;

此时我们需要对我们的需求进行求取的过程中,需要用到mapjoin操作,此时我们可以把我们user表放置在join字段的左侧,movies放置在我们的右侧,在新版的测试当中,我们mapjoin是自动打开的,此时会在构建语法树的过程中,自动进行我们的map join 优化,所以我只是测试 放置在左边的效果。
查询语句

select age,count(1) ct from (select split(age,'')[0] * 10 as age 
from user1 u join movies m on u.id = m.id)t
group by age;

执行过程
此时执行了934秒的时候,我们的mapper还没有执行完毕,数据量确实比较大,我再继续耐心等待,哈哈。
先去洗澡,跑完不知道什么时候呢,我们慢慢的对我们的hive程序进行优化。

Hive消耗时间

此时我们的时间消耗是34分钟,我们是否可以让我们运行时间进行进一步的缩减了。
那么我们数据倾斜发生在哪里呢,我们的数据倾斜,是发生在我们的shuffle算子的过程中,大量的key聚集到某一个reducer上进行聚合,并不是一个并行的操作,此时我们的处理时长就存在了木桶效应,也就是处理时间最长的分区决定了我们的运行的总时长。
运行时倾斜描述
此时我们同时尝试一下我们的spark的效果

Spark运行时长

Spark 比我们的hadoop 快了很多,其实绝大部分情况下spark比hadoop快,但是有一些很极端的情况下不一定有我们的hadoop快,这是不一定的。
我们在测试的过程中可以明显的看到,spark确实比MR快了10倍,但是这个效果,我们还是不满意怎么办呢。
DAG图

各个Stage执行时间
此时出现了数据倾斜问题,那么我们如何做呢

  1. 首先,开启map段语句和操作
set hive.map.aggr = true
  1. 开启在map端进行聚合的条数,这个不是随机设置的,要根据数据来计算
set hive.groupby.mapaggr.checkinterval = 10000
  1. 开启数据倾斜时,自动负载均衡
set hive.groupby.skewindata = true

优化结果
碍于机器的性能原因,差不多也就这样了。大规模集群会很快的。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值