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

news2024/12/28 20:24:48

   我们在写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的内存和个数,以及小文件合并之类的

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vulkan Tutorial 9 模型加载Mipmaps

目录 28 加载模型 Sample mesh 加载顶点和索引 ​编辑 顶点去重 28 加载模型 我们将使用tinyobjloader库来从OBJ文件中加载顶点和面。它的速度很快,而且很容易集成,因为它是一个像stb_image一样的单文件库。将包含tiny_obj_loader.h的目录添加到Add…

ChatGPT国内镜像站

免费国内镜像推荐(超稳定) 下面为大家收集了目前国内最稳定流畅的ChatGPT镜像网站 目录 机器人 博弈ai 泰cool辣 道合顺 二狗问答 核桃 WOChat GPT中文站 TomChat 利用ChatGPTMindShow三分钟生成PPT ChatGPT国内镜像是啥 ChatGPT 镜像是指…

Xpdf 阅读器源码编译后查看文件中文乱码问题解决

经查阅,是由于缺少中文字体包: 第一步:下载所需要的字体包 下载https://dl.xpdfreader.com/xpdf-t1fonts.tar.gz 包含下载中文字体包(非嵌入字体) http://ftp.gnu.org/gnu/non-gnu/chinese-fonts-truetype/gkai00mp…

pytorch-简单回归问题-手写数字识别

pytorch-简单回归问题-手写数字识别 线性回归添加噪声简单例子分类问题引入-手写数字识别数据集 训练推导手写数字识别1加载数据集编写网络训练网络计算正确率 线性回归添加噪声 使用均方差损失函数来衡量损失 简单例子 通过最小化损失函数,求解出参数w b 下图表示…

封装的函数停发/启动CAN报文,以及报文接收检测,高可用

🍅 我是蚂蚁小兵,专注于车载诊断领域,尤其擅长于对CANoe工具的使用🍅 寻找组织 ,答疑解惑,摸鱼聊天,博客源码,点击加入👉【相亲相爱一家人】🍅 玩转CANoe,博客目录大全,点击跳转👉 📘前言 🍅 在测试过程中,我们可能需要可控的停/发某些报文,今天博主给…

chatgpt赋能python:Python主页面的SEO分析及优化建议

Python主页面的SEO分析及优化建议 Python是一种高级编程语言,广泛应用于人工智能、数据分析、Web开发等领域。Python官方网站是Python社区的一个重要门户,为全球学习Python的开发者提供了全面、权威、可靠的信息。在这篇文章中,我们将分析Py…

Text to image论文精读SeedSelect: 使用SeedSelect微调扩散模型It’s all about where you start

随着文本到图像扩散模型的发展,很多模型已经可以合成各种新的概念和场景。然而,它们仍然难以生成结构化、不常见的概念、组合图像。今年4月巴伊兰大学和OriginAI发表《It’s all about where you start: Text-to-image generation with seed selection》…

软件外包开发项目原型图工具

项目原型图工具有非常重要的作用,尤其是在APP项目开发中,对于整体需求的表达是必不可少的工具。相比于传统的文档需求,图形文字的表达可以更清楚的表达需求,让客户清楚的明白软件功能有哪些,最后的界面是怎样的&#x…

微信海量数据查询如何从1000ms降到100ms?

👉腾小云导读 微信的多维指标监控平台,具备自定义维度、指标的监控能力,主要服务于用户自定义监控。作为框架级监控的补充,它承载着聚合前 45亿/min、4万亿/天的数据量。当前,针对数据层的查询请求也达到了峰值 40万/m…

RL - 强化学习 上置信界算法 (UCB) 和 汤普森采样算法 (TS)

欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://blog.csdn.net/caroline_wendy/article/details/130983835 上置信界算法和汤普森采样算法是两种解决多臂老虎机问题的经典方法。多臂老虎机问题是一种探索与利用的平衡问题,…

Java easypoi 导出excel 并合并相关列

在项目开发中经常会使用到合并列&#xff0c;格式如下&#xff1a; 1.引入easypoi <dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-annotation</artifactId></dependency><dependency><groupId>cn.aftertur…

设计模式详解之策略模式

作者&#xff1a;刘文慧 策略模式是一种应用广泛的行为型模式&#xff0c;核心思想是对算法进行封装&#xff0c;委派给不同对象来管理&#xff0c;本文将着眼于策略模式进行分享。 一、概述 我们在进行软件开发时要想实现可维护、可扩展&#xff0c;就需要尽量复用代码&#x…

chatgpt赋能python:Python什么情况下用类

Python什么情况下用类 在Python编程中&#xff0c;类是一种重要的数据结构&#xff0c;它是面向对象编程的核心。类可定义数据类型&#xff0c;并把数据与操作数据的函数组合在一起。因此&#xff0c;通过使用类&#xff0c;我们可以将数据、函数和其他方法组合在一起&#xf…

OLAP系列:四、clickhouse分布式表使用指南

一、背景 ClickHouse中最强大的表引擎当属MergeTree&#xff08;合并树&#xff09;引擎及该系列&#xff08;*MergeTree&#xff09;中的其他引擎&#xff0c;支持索引和分区&#xff0c;地位可以相当于innodb之于Mysql。 而且基于MergeTree&#xff0c;还衍生出了很多小弟&a…

【量化分析】绘制指标线EWM和MACD(1)

目录 一、说明 二、使用mplfinance的前提 2.1 mplfinance生态圈 2.1 安装mplfinance 三、mplfinance绘图 3.1 单变量图 3.2 将用户自己生成的曲线添加到 mplfinance plot() 四、显示EWM和MACD 一、说明 在做量化分析的时候&#xff0c;需要有能力计算种种曲线&#xff…

ShowMeBug 持续升级,提供高信效度支撑的技术招聘方案

去年年底&#xff0c;全新升级版的 ShowMeBug ——一款支持实战编程的技术能力评估平台&#xff0c;首次揭开了它神秘的面纱。 而近日&#xff0c;ShowMeBug 再次迎来一系列产品更新&#xff0c;它将以全新的面貌&#xff0c;提供高信效度支撑的技术招聘方案&#xff0c;持续助…

chatgpt赋能python:Python人脸登录:这项技术将颠覆传统的登录方式

Python人脸登录&#xff1a;这项技术将颠覆传统的登录方式 简介 在互联网时代&#xff0c;登录是每个人使用网站或软件的第一步&#xff0c;但是传统的用户名和密码登录已经不能满足用户的需求。不断的爆出各种账户泄露事件、密码猜测和密码被盗等问题&#xff0c;导致用户的…

cleanmymac要不要下载装机?好不好用

当我们收到一台崭新的mac电脑&#xff0c;第一步肯定是找到一款帮助我们管理电脑运行的“电脑管家”&#xff0c;监控内存运行、智能清理系统垃圾、清理Mac大文件旧文件、消除恶意软件、快速卸载更新软件、隐私保护、监控系统运行状况等。基本在上mac电脑防护一款CleanMyMac就够…

生成程序片段(程序依赖图PDG)

生成程序片段(程序依赖图PDG) 生成程序片段 标准方法是&#xff1a; 基于依赖性分析的切片。 使用程序依赖图表示依赖。 从中生成切片。 我们将专注于这种方法。但是&#xff0c;还有其他选择。 程序依赖图 The Program Dependence Graph (PDG) 表示数据和控制依赖项&#xf…

Servlet的常用Api—HttpServletResponse

Servlet的常用Api—HttpServletResponse &#x1f50e;核心方法setContentType && setCharacterEncodingsendRedirect关于Keep-Alive关于状态码 && Body &#x1f50e;结尾 &#x1f50e;核心方法 方法描述(void) setStatus(int sc)为该响应设置状态码(void) s…