hive任务reduce步骤卡在99%原因及解决

   我们在写sql的时候经常发现读取数据不多,但是代码运行时间异常长的情况,这通常是发生了数据倾斜现象。数据倾斜现象本质上是因为数据中的key分布不均匀,大量的数据集中到了一台或者几台机器上计算,这些数据的计算速度远远低于平均计算速度,从而拉慢了整个计算过程速度。

本文将介绍如何通过日志分析,判断数据中的哪个key分布不均,从而导致了数据倾斜问题。

任务是否发生了倾斜

hive判断

hive运行日志

当我们在hive作业运行日志中,发现reduce任务长时间卡在99%时,即可判断任务发生了数据倾斜。

其原理是这样的:

分布式处理逻辑

分布式处理实际上是按数据中的key将数据分摊到多个机器上运行,假如出现了数据倾斜问题,如上图。可以想象,当1min过去后,我们的任务完成率只有67%,并且在接下来的9min时间内,任务完成率将持续卡在67%上。因此,当我们发现任务完成率长时间卡在99%时,即判断发生了数据倾斜。

spark判断

spark UI界面

我们进入spark UI界面,发现第2个job的运行时间长达1.8h,而其他job运行时间不超过2min,判断该job有可能发生数据倾斜。

进一步分析job,可以看到该job只存在一个stage(9)

stage界面

进一步分析stage,发现不管是duration还是shuffle的数据量,max和median都有明显的差距,可以肯定是job(5)的stage(9)发生倾斜。

hive输出也可以帮助排查

hive数据倾斜表象:Table 0 has 10000 rows for join key [0,0]
有hive任务发生数据倾斜,reduce端一直99%,有一个reduce任务卡主了。
打开这个reduce任务的log日志,发现如下日志:

[INFO] org.apache.hadoop.hive.ql.exec.JoinOperator: Table 0 has 10000 rows for join key [0,0]


打开hive源码定为输入日志行:

if (sz == nextSz) {
    LOG.info("Table {} has {} rows for join key {}", alias, sz, keyObject);
    nextSz = getNextSize(nextSz);
}


输出的类是org.apache.hadoop.hive.ql.exec.JoinOperator,是hive中join运算符的实现类,具体运行机制尚不清楚。
查询资料得知,当一个key关联了超过1000行时,会输出一条该警告日志,此后每1000会输出一条。所以这条日志的目的在于警告可能存在的Join数据倾斜的风险。
 

寻找倾斜key

当我们发现任务倾斜了,自然而然就希望找到倾斜的key,从而修复数据倾斜的现象。当然,这部分我也会分为hive和spark两个部分进行介绍。

hive识别

step1:确认是哪个Job出现了严重的倾斜问题

hive运行日志

通过搜索tracking的方式,我们发现第3个job的reduce任务一直卡在99%上,判断其发生了倾斜问题。

step2:进入相应的Tracking URL,查看SUCCESSFUL REDUCE

很明显,其他的taske都在2min之内完成,只有000000_1需要耗费1个多小时的时间完成。

另外注意,这里面需要排除一种特殊情况。有时候,某个task执行的节点可能有问题,导致任务跑的特别慢。这个时候,mapreduce的推测执行,会重启一个任务。如果新的任务在很短时间内能完成,通常则是由于task执行节点问题导致的个别task慢。如果推测执行后的task执行任务也特别慢,那更能说明该task可能会有倾斜问题。

step3:进入log日志,查看syslog

hive的syslog日志

可以从log日志中看到,该job仅仅运行了file和group操作后,就将数据写入至hive表中。那么,我们可以确认的是,该job运行的是最后一个group by操作。

step4:对照运行sql

运行sql

我们可以看到,在group by阶段,count(distinct)的出现造成了数据倾斜。

spark识别

step1:找到该任务运行的stage

spark UI界面

我们看到该运行任务,可以发现第2个job运行时间长达1.8h,远大于其他job,可以判定倾斜发生在job(5)。

step2:点击SQL,查看Details for Query

Details for Query

可以从sort time total/peak memory total/spill size total看出来,左表的package_name分布不均匀,此时可以通过查看scan parquet了解具体是哪张表。

step3:对照运行sql

运行sql代码

查询package_name的分布情况

select package_name,count(1) as cnt from test1 where date=20220619 group by package_name order by cnt desc limit 10;

package_name的分布验证了我们的猜想,test1.package_name造成了数据倾斜

过滤掉倾斜数据

当少量key重复次数特别多,如果这种key不是业务需要的key,可以直接过滤掉。

比如一张埋点日志表ods.page_event_log,

需要和订单表dw.order_info_fact做join关联。

在执行Hive的过程中发现任务卡在map 100%、reduce 99%,最后的1%一直运行不完。考虑应该是在join的过程中出现了数据倾斜,下面进行排查。

对于ods.page_event_log表查看出现次数最多的key:

select cookieid,
           count(*) as num
    from ods.page_event_log
   where data_date = "20190101"
group by cookieid
distribute by cookieid
sort by num desc limit 10

同样的,对另一张join表也做对应的排查

select cookieid,
    count(*) as num
from dw.order_info_fact
group by cookieid
distribute by cookieid
sort by num desc limit 10

从sql统计的结果可以看出,日志表和订单表通过cookieid进行join,当cookieid为0的时候,join操作将会产生142286×142286条数据,数量如此庞大的节点系统无法处理过来。同样当cookieid为NULL值和空值时也会出现这种情况,而且cookieid为这3个值时并没有实际的业务意义。因此在对两个表做关联时,排除掉这3个值以后,就可以很快计算出结果了,所以做好前期的数据清洗对一个大数据平台是至关重要的,生产无小事。

引入随机数

当我们用sql对数据group by时,MR会将相同的key拉取到同一个节点上进行聚合,如果某组的数据量很大时,会出现当前节点任务负载过重,从而导致数据倾斜。这时候可以考虑引入随机数,将原来的一个key值拆分成多组进行聚合。

比如现在需要统计用户的订单量,sql如下:

select t1.user_id,
       t2.order_num
    from (select user_id
          from dim.user_info_fact   # 用户维度表
       where data_date = "20190101"            
          and user_status_id=1
       ) t1 
  join ( select user_id,
            count(*) as order_num 
       from dw.dw_order_fact      # 订单表
       where site_id in (600, 900)
          and order_status_id in(1,2,3)
     group by user_id

        ) t2 
    on t1.user_id = t2.user_id

其中,用户维度表有2000w条数据,订单表有10亿条数据,任务在未优化前跑了一小时还没跑完,怀疑出现了数据倾斜。这里可以把key值加上一定的前缀转换成多个key,这样原本一个task上处理的key就会分发到其他多个task,然后去掉前缀再进行一次聚合得到最终结果。

优化后的sql如下: 这里把原来可能1个task执行的任务并行成了1000个随机数task做聚合,再把聚合的结果通过user_id做sum,在集群的整体性能不受影响的情况下,可以有效提高整体的计算速度。

select t1.user_id,
       t2.order_num
    from (select user_id
       from dim_user_info_fact
       where data_date = "20190101"                           
       ) t1 
  join (   select t.user_id,
            sum(t.order_num) as order_num
       from (select user_id,
                round(rand()*1000) as rnd,
                count(1) as order_num 
           from dw.order_info_fact
           where pay_status in (1,3)
           group by user_id,round(rand()*1000)
             ) t 
         group by t.user_id
    ) t2 
  on t1.user_id = t2.user_id

还有一种可能 

可能仅仅是因为你给的资源太少了 ,适当增加map和reduce的内存和个数,以及小文件合并之类的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/24739.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

NVM-Nodejs多版本管理工具

NVM:🔎:下载点我 下载含有 setup.exe的 下载完成之后修改一下settings.txt 文件,在原有的基础上直接加入这些配置 root: D:\nvm path: D:\nvm\nodejs node_mirror: https://npm.taobao.org/mirrors/node/ npm_mirror: https://npm.taobao.org/mirrors…

旅游有哪些好玩的地方? 今天用python分析适合年轻人的旅游攻略

前言 嗨喽,大家好呀~这里是爱看美女的茜茜呐 “旅”是旅行,外出,即为了实现某一目的而在空间上从甲地到乙地的行进过程; “游”是外出游览、观光、娱乐,即为达到这些目的所作的旅行。 二者合起来即旅游。所以&#…

JavaScript 基础 DOM (四)

正则表达式正则表达式 正则基本使用 定义规则 const reg /表达式/其中/ /是正则表达式字面量正则表达式也是对象 使用正则 test()方法 用来查看正则表达式与指定的字符串是否匹配 如果正则表达式与指定的字符串匹配 ,返回true,否则false reg.test(…

【算法】【算法杂谈】旋转数组的二分法查找

目录 前言问题介绍解决方案代码编写java语言版本c语言版本c语言版本 思考感悟写在最后 前言 当前所有算法都使用测试用例运行过,但是不保证100%的测试用例,如果存在问题务必联系批评指正~ 在此感谢左大神让我对算法有了新的感悟认识! 问题介…

1722_PolySpace Bug Finder的几种启动方式

全部学习汇总: GreyZhang/g_matlab: MATLAB once used to be my daily tool. After many years when I go back and read my old learning notes I felt maybe I still need it in the future. So, start this repo to keep some of my old learning notes servral …

pinia

一、pinia是什么? 🚜🚜🚜Pinia是最接近西班牙语中的菠萝的词;背景:大概2019年,是作为一个实验为Vue重新设计状态管理,让它用起来像组合式API。从那时到现在,最初的设计原…

Vulkan Tutorial 5 顶点缓冲区

目录 16 顶点缓冲区 顶点着色器 顶点数据 管道顶点输入 17 顶点缓冲区创建 缓冲区创建 内存要求 内存分配 填充顶点缓冲区 18 暂存缓冲区 传输队列 使用暂存缓冲区 19 索引缓冲区 索引缓冲区创建 使用索引缓冲区 16 顶点缓冲区 我们将用内存中的顶点缓冲区替换…

5。STM32裸机开发(4)

嵌入式软件开发学习过程记录,本部分结合本人的学习经验撰写,系统描述各类基础例程的程序撰写逻辑。构建裸机开发的思维,为RTOS做铺垫(本部分基于库函数版实现),如有不足之处,敬请批评指正。 &…

拥抱 Spring 全新 OAuth 解决方案

以下全文 Spring Authorization Server 简称为: SAS 背景 Spring 团队正式宣布 Spring Security OAuth 停止维护,该项目将不会再进行任何的迭代 目前 Spring 生态中的 OAuth2 授权服务器是 Spring Authorization Server 已经可以正式生产使用 作为 SpringBoot 3.0…

FastThreadLocal 原理解析

FastThreadLocal 每个 FastThread 包含一个 FastThreadLocalMap,每个 FastThreadLocalThread 中的多个 FastThreadLocal 占用不同的索引。每个 InternalThreadLocalMap 的第一个元素保存了所有的 ThreadLocal 对象。之后的元素保存了每个 ThreadLocal 对应的 value …

SpringBoot 之 Tomcat 与 Undertow 容器性能对比

一、前言🔥 环境说明:Windows10 Idea2021.3.2 Jdk1.8 SpringBoot 2.3.1.RELEASE 在上一篇《SpringBoot 之配置 Undertow 容器》一文中写道:“Undertow 的性能和内存使用方面都要优于 Tomcat 容器”, 这一期,我就要给大家来求证…

批处理文件(.bat)启动redis及任何软件(同理)

批处理文件 每次从文件根目录用配置文件格式来启动redis太麻烦了 可以在桌面上使用批处理文件(.bat)启动Redis,请按照以下步骤进行操作: 打开文本编辑器,如记事本。 在编辑器中输入以下内容: 将文件保存…

【JavaSE】Java基础语法(三十六):File IO流

文章目录 1. File1.1 File类概述和构造方法1.2 绝对路径和相对路径1.3 File 类的常用方法1.4 递归删除文件夹及其下面的文件 2. IO2.1 分类2.2 字节输出流2.3 字节输入流2.4 文件的拷贝2.5 文件拷贝效率优化2.6 释放资源2.7 缓冲流2.8 编码表 3. commons-io 工具包3.1 API 1. F…

gitlab搭建与认证登录

gitlab搭建与认证登录 gitlab的安装配置gitlab中Ldap认证配置 gitlab的安装配置 参考链接: Gitlab 仓库搭建(详细版) 以下4项注意点: gitlab安装包,直接访问在浏览器上下载速度很慢,可复制链接到迅雷中进…

怎样用一周时间研究 ChatGPT

我是怎样用一周时间研究 ChatGPT 的? 上周大概开了 20 多个会,其中有一些是见了觉得今年可能会比较活跃出手的机构,其余见的绝大多数是和 ChatGPT 相关。 我后面就以 ChatGPT 为例,讲下我是如何快速一周 cover 一个赛道的&#x…

机器视觉怎么对陶瓷板的外观尺寸进行自动检测?

随着工业自动化的不断发展,机器视觉技术在制造业中的应用越来越广泛。在陶瓷板行业中,机器视觉技术可以用于自动检测陶瓷板的外观尺寸,提高生产效率和产品质量。下面我们来介绍机器视觉如何对陶瓷板的外观尺寸进行自动检测。 一、检测原理 …

vue常用指令

vue是前端框架&#xff0c;使用vue指令时需要导入vue.js文件&#xff1b;vue的常用指令有以下这些&#xff1a; v-bind、v-model&#xff1a;双向绑定数据、链接 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8">&…

SAP-MM-采购申请字段解析

采购申请抬头以及行项目字段解析 1、采购申请类型&#xff1a; 对PR进行分类&#xff1b; 控制PR行项目的编号间隔&#xff1b; 控制PR编号范围&#xff0c;以及是否内/外部给号&#xff1b; 控制PR的屏幕选择格式&#xff1b; 控制PR是否允许凭证抬头审批&#xff0c;如果允…

什么是MQTT?mqtt协议和http协议区别

摘要&#xff1a; 什么是MQTT&#xff1f;MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;译为&#xff1a;消息队列遥测传输&#xff0c;是一种轻量级的通讯协议&#xff0c;用于在网络上传输消息。MQTT 最初由 IBM 发布&#xff0c;后来成为 OASIS&#xf…

会话跟踪cookie和session

什么是会话跟踪技术 会话&#xff1a;用户打开浏览器&#xff0c;访问web服务器的资源&#xff0c;会话建立&#xff0c;直到有一方断开连接&#xff0c;会话结束。在一次会话中可能包含多次请求和响应。 会话跟踪&#xff1a;一种维护浏览器状态的方法&#xff0c;服务器需…