Hive提交到yarn的任务一直在running问题排查

2024-09-04 17:18

本文主要是介绍Hive提交到yarn的任务一直在running问题排查,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • 一、问题描述
    • 二、问题排查
      • Hive提交Spark任务流程
      • 问题定位
      • 问题总结
    • 三、解决方案
    • Tips:

一、问题描述

最近有数据平台的同学反馈yarn上面有一些任务跑了很久没有结束,状态一直处于running中。去Spark HistoryServer查看任务详情也没看到相关运行记录,需要人为手动kill任务才会停止并释放资源。


在这里插入图片描述
在这里插入图片描述

二、问题排查

从Spark HistoryServer可以看出,任务的Driver虽然启动了,但是并未执行job,并且一直阻塞在那没有退出。从yarn的角度来看,这个任务就是在运行中。

因此,我们需要排查是究竟什么原因导致Driver不退出,又不接收job运行呢

由于这是hive提交的任务,我们可以先看一下Hive是怎么提交spark任务的。

Hive提交Spark任务流程

  1. Hive要提交一个Spark任务时,会先通过spark-submit提交一个spark程序到yarn集群运行。而运行的MainClass就是RemoteDriver
  2. RemoteDriver在yarn的container启动后,会主动去连接Hiveserver2开放的rpc端口(这个端口在spark-submit时会带上,因此RemoteDriver知道要连接的host和ip)
  3. 连接建立后,SparkClientImpl这边会根据clientId从RpcServer中找到对应的channel,之后将要运行的job通过kvro工具序列化成字节流发送给RemoteDriver
  4. RemoteDriver这边在连接成功后,就开始准备接收SparkClientImpl发送过来的消息并执行。
  5. 最后,如果在SparkClientImpl关闭时也会相应的关闭远程的RemoteDriver,具体做法是发送一个关闭的消息给RemoteDriver,告诉它可以停掉了。(SparkClientImpl一般是在整个客户端的session关闭时关闭的)

RpcServer在整个Hiveserver2进程中只会有一个,因此需要通过clientId来标识对应的RemoteDriver客户端。这个clientId也会在spark-submit时带上。

问题定位

了解了提交的过程后,我们可以知道RemoteDriver的关闭依赖于SparkClientImpl发送的关闭请求。那么情况无非有两种:

  1. SparkClientImpl发送了关闭消息,但是RemoteDriver没收到或者忽略了该消息
  2. SparkClientImpl由于一些原因,没发送关闭消息

由于这种情况发生了好几例,且网络表现正常,因此基本可以排除掉因网络不佳丢包的可能性。之后仔细看了下RemoteDriver这边Rpc的相关代码,也基本可以排除RemoteDriver忽略消息的可能性。因此大概率是SparkClientImpl没有发送关闭消息导致的。

查了下HiveServer2这边那天的日志,果然发现一些异常,都是在任务启动时报的:
在这里插入图片描述

从异常信息我们可以很清晰的看出,SparkClientImpl在等待RemoteDriver的连接时抛出了InterruptedException。我们再看一下相关代码:

String clientId = UUID.randomUUID().toString();
String secret = rpcServer.createSecret();
//通过spark-submit提交RemoteDriver到yarn集群运行
this.driverThread = startDriver(rpcServer, clientId, secret);
this.protocol = new ClientProtocol();
try {//109行,等待RemoteDriver的连接并获取连接this.driverRpc = rpcServer.registerClient(clientId, secret, protocol).get();
} catch (Throwable e) {if (e.getCause() instanceof TimeoutException) {LOG.error("Timed out waiting for client to connect.\nPossible reasons include network " +"issues, errors in remote driver or the cluster has no available resources, etc." +"\nPlease check YARN or Spark driver's logs for further information.", e);} else {//InterruptedException会走这里LOG.error("Error while waiting for client to connect.", e);}//driverThread是阻塞等待spark-submit子进程跑完的线程driverThread.interrupt();try {driverThread.join();} catch (InterruptedException ie) {// Give up.LOG.debug("Interrupted before driver thread was finished.");}//向外层继续抛出异常throw Throwables.propagate(e);
}

从上面的代码来看,SparkClientImpl在等待RemoteDriver的连接时抛出了InterruptedException,代码除了关闭driverThread外,并没有做其他的事了。

这样就可能存在一个问题,虽然SparkClientImpl在这里退出了,但是RemoteDriver又连接上了RpcServer,它就会一直等待远程的消息并一直运行下去。

后面刚好有一个任务也出现这种情况,登陆RemoteDriver所在的机器看了下tcp连接**,发现连接确实还存活着,但是SparkClientImpl这时已经退出了。**

RemoteDriver所在服务器的端口扫描:
在这里插入图片描述
在这里插入图片描述

问题总结

出现这个问题的原因应该是用户提交一个sql到HiveServer后立马关闭了session,而此时SparkClientImpl又刚好在阻塞等待来自RemoteDriver的连接。因为session的关闭,关闭session的线程会主动interrupt掉SparkClientImpl所在的线程**。**

SparkClientImpl等待连接抛出异常后又没通知rpcServer进行相关解除注册处理,因此RemoteDriver成功的建立了连接,并一直等待来自SparkClientImpl的请求。然而此时SparkClientImpl已经退出,因此除非外界干涉,否则RemoteDriver永远不会停止运行。

三、解决方案

修改源码,在SparkClientImpl抛出InterruptedException时,移除SparkClientImpl对rpcServer的注册,这样客户端在连接过来时,rpcServer就会直接返回错误信息,客户端收到错误信息后就会判定连接失败从而退出进程。

try {//109行,等待RemoteDriver的连接并获取连接this.driverRpc = rpcServer.registerClient(clientId, secret, protocol).get();
} catch (Throwable e) {if (e.getCause() instanceof TimeoutException) {LOG.error("Timed out waiting for client to connect.\nPossible reasons include network " +"issues, errors in remote driver or the cluster has no available resources, etc." +"\nPlease check YARN or Spark driver's logs for further information.", e);} else {//InterruptedException会走这里LOG.error("Error while waiting for client to connect.", e);//以下是添加代码块//其实就是将clientInfo从pendingClients中移除// 在客户端发送连接时,rpcserver发现客户端clientId不在pendingClients中,就会返回失败的信息给客户端rpcServer.cancelClient(clientId,"cancel client for " + e.getMessage());//添加代码块结束}//driverThread是阻塞等待spark-submit子进程跑完的线程driverThread.interrupt();try {driverThread.join();} catch (InterruptedException ie) {// Give up.LOG.debug("Interrupted before driver thread was finished.");}//向外层继续抛出异常throw Throwables.propagate(e);
}

Tips:

如果排查发现不是上面的问题,也可以参考 Hive提交到yarn的任务一直在running问题排查-V2,有个此类问题的终极解决方案

这篇关于Hive提交到yarn的任务一直在running问题排查的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1136541

相关文章

作业提交过程之HDFSMapReduce

作业提交全过程详解 (1)作业提交 第1步:Client调用job.waitForCompletion方法,向整个集群提交MapReduce作业。 第2步:Client向RM申请一个作业id。 第3步:RM给Client返回该job资源的提交路径和作业id。 第4步:Client提交jar包、切片信息和配置文件到指定的资源提交路径。 第5步:Client提交完资源后,向RM申请运行MrAp

好题——hdu2522(小数问题:求1/n的第一个循环节)

好喜欢这题,第一次做小数问题,一开始真心没思路,然后参考了网上的一些资料。 知识点***********************************无限不循环小数即无理数,不能写作两整数之比*****************************(一开始没想到,小学没学好) 此题1/n肯定是一个有限循环小数,了解这些后就能做此题了。 按照除法的机制,用一个函数表示出来就可以了,代码如下

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

购买磨轮平衡机时应该注意什么问题和技巧

在购买磨轮平衡机时,您应该注意以下几个关键点: 平衡精度 平衡精度是衡量平衡机性能的核心指标,直接影响到不平衡量的检测与校准的准确性,从而决定磨轮的振动和噪声水平。高精度的平衡机能显著减少振动和噪声,提高磨削加工的精度。 转速范围 宽广的转速范围意味着平衡机能够处理更多种类的磨轮,适应不同的工作条件和规格要求。 振动监测能力 振动监测能力是评估平衡机性能的重要因素。通过传感器实时监

缓存雪崩问题

缓存雪崩是缓存中大量key失效后当高并发到来时导致大量请求到数据库,瞬间耗尽数据库资源,导致数据库无法使用。 解决方案: 1、使用锁进行控制 2、对同一类型信息的key设置不同的过期时间 3、缓存预热 1. 什么是缓存雪崩 缓存雪崩是指在短时间内,大量缓存数据同时失效,导致所有请求直接涌向数据库,瞬间增加数据库的负载压力,可能导致数据库性能下降甚至崩溃。这种情况往往发生在缓存中大量 k

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

【VUE】跨域问题的概念,以及解决方法。

目录 1.跨域概念 2.解决方法 2.1 配置网络请求代理 2.2 使用@CrossOrigin 注解 2.3 通过配置文件实现跨域 2.4 添加 CorsWebFilter 来解决跨域问题 1.跨域概念 跨域问题是由于浏览器实施了同源策略,该策略要求请求的域名、协议和端口必须与提供资源的服务相同。如果不相同,则需要服务器显式地允许这种跨域请求。一般在springbo

题目1254:N皇后问题

题目1254:N皇后问题 时间限制:1 秒 内存限制:128 兆 特殊判题:否 题目描述: N皇后问题,即在N*N的方格棋盘内放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在同一斜线上。因为皇后可以直走,横走和斜走如下图)。 你的任务是,对于给定的N,求出有多少种合法的放置方法。输出N皇后问题所有不同的摆放情况个数。 输入

vscode中文乱码问题,注释,终端,调试乱码一劳永逸版

忘记咋回事突然出现了乱码问题,很多方法都试了,注释乱码解决了,终端又乱码,调试窗口也乱码,最后经过本人不懈努力,终于全部解决了,现在分享给大家我的方法。 乱码的原因是各个地方用的编码格式不统一,所以把他们设成统一的utf8. 1.电脑的编码格式 开始-设置-时间和语言-语言和区域 管理语言设置-更改系统区域设置-勾选Bata版:使用utf8-确定-然后按指示重启 2.vscode

HTML提交表单给python

python 代码 from flask import Flask, request, render_template, redirect, url_forapp = Flask(__name__)@app.route('/')def form():# 渲染表单页面return render_template('./index.html')@app.route('/submit_form',