记一次 ERROR scheduler.AsyncEventQueue: Dropping event from queue shared导致OOM

问题描述

日志:
2022-07-23 01:03:40 ERROR scheduler.AsyncEventQueue: Dropping event from queue shared. This likely means one of the listeners is too slow and cannot keep up with the rate at which tasks are being started by the scheduler.
2022-07-23 01:03:40 WARN scheduler.AsyncEventQueue: Dropped 1 events from shared since the application started.
2022-07-23 01:04:41 WARN scheduler.AsyncEventQueue: Dropped 2335 events from shared since Sat Jul 23 01:03:40 CST 2022.
2022-07-23 01:05:42 WARN scheduler.AsyncEventQueue: Dropped 2252 events from shared since Sat Jul 23 01:04:41 CST 2022.
2022-07-23 01:06:42 WARN scheduler.AsyncEventQueue: Dropped 1658 events from shared since Sat Jul 23 01:05:42 CST 2022.
2022-07-23 01:07:42 WARN scheduler.AsyncEventQueue: Dropped 1405 events from shared since Sat Jul 23 01:06:42 CST 2022.
2022-07-23 01:08:43 WARN scheduler.AsyncEventQueue: Dropped 1651 events from shared since Sat Jul 23 01:07:42 CST 2022.
2022-07-23 01:09:43 WARN scheduler.AsyncEventQueue: Dropped 1983 events from shared since Sat Jul 23 01:08:43 CST 2022.
2022-07-23 01:10:43 WARN scheduler.AsyncEventQueue: Dropped 1680 events from shared since Sat Jul 23 01:09:43 CST 2022.
2022-07-23 01:11:43 WARN scheduler.AsyncEventQueue: Dropped 1643 events from shared since Sat Jul 23 01:10:43 CST 2022.
2022-07-23 01:12:44 WARN scheduler.AsyncEventQueue: Dropped 1959 events from shared since Sat Jul 23 01:11:43 CST 2022.
2022-07-23 01:13:45 WARN scheduler.AsyncEventQueue: Dropped 2315 events from shared since Sat Jul 23 01:12:44 CST 2022.
2022-07-23 01:14:47 WARN scheduler.AsyncEventQueue: Dropped 2473 events from shared since Sat Jul 23 01:13:45 CST 2022.
2022-07-23 01:15:47 WARN scheduler.AsyncEventQueue: Dropped 1962 events from shared since Sat Jul 23 01:14:47 CST 2022.
2022-07-23 01:16:48 WARN scheduler.AsyncEventQueue: Dropped 1645 events from shared since Sat Jul 23 01:15:47 CST 2022.
2022-07-23 01:17:48 WARN scheduler.AsyncEventQueue: Dropped 1885 events from shared since Sat Jul 23 01:16:48 CST 2022.
2022-07-23 01:18:48 WARN scheduler.AsyncEventQueue: Dropped 2391 events from shared since Sat Jul 23 01:17:48 CST 2022.
2022-07-23 01:19:48 WARN scheduler.AsyncEventQueue: Dropped 1501 events from shared since Sat Jul 23 01:18:48 CST 2022.
2022-07-23 01:20:49 WARN scheduler.AsyncEventQueue: Dropped 1733 events from shared since Sat Jul 23 01:19:48 CST 2022.
2022-07-23 01:21:49 WARN scheduler.AsyncEventQueue: Dropped 1867 events from shared since Sat Jul 23 01:20:49 CST 2022.
2022-07-23 01:22:50 WARN scheduler.AsyncEventQueue: Dropped 1561 events from shared since Sat Jul 23 01:21:49 CST 2022.
2022-07-23 01:23:51 WARN scheduler.AsyncEventQueue: Dropped 1364 events from shared since Sat Jul 23 01:22:50 CST 2022.
2022-07-23 01:24:52 WARN scheduler.AsyncEventQueue: Dropped 1579 events from shared since Sat Jul 23 01:23:51 CST 2022.
2022-07-23 01:25:52 WARN scheduler.AsyncEventQueue: Dropped 1847 events from shared since Sat Jul 23 01:24:52 CST 2022.

Exception in thread "streaming-job-executor-0" java.lang.OutOfMemoryError: GC overhead limit exceeded
	at org.apache.xbean.asm7.ClassReader.readLabel(ClassReader.java:2447)
	at org.apache.xbean.asm7.ClassReader.createDebugLabel(ClassReader.java:2477)
	at org.apache.xbean.asm7.ClassReader.readCode(ClassReader.java:1689)
	at org.apache.xbean.asm7.ClassReader.readMethod(ClassReader.java:1284)
	at org.apache.xbean.asm7.ClassReader.accept(ClassReader.java:688)
	at org.apache.xbean.asm7.ClassReader.accept(ClassReader.java:400)
	at org.apache.spark.util.ClosureCleaner$.clean(ClosureCleaner.scala:359)
	at org.apache.spark.util.ClosureCleaner$.clean(ClosureCleaner.scala:162)
	at org.apache.spark.SparkContext.clean(SparkContext.scala:2362)
	at org.apache.spark.rdd.RDD.$anonfun$mapPartitions$1(RDD.scala:834)
	at org.apache.spark.rdd.RDD$$Lambda$2785/604434085.apply(Unknown Source)
	at org.apache.spark.rdd.RDDOperationScope$.withScope(RDDOperationScope.scala:151)
	at org.apache.spark.rdd.RDDOperationScope$.withScope(RDDOperationScope.scala:112)
	at org.apache.spark.rdd.RDD.withScope(RDD.scala:388)
	at org.apache.spark.rdd.RDD.mapPartitions(RDD.scala:833)
	at org.apache.spark.sql.Dataset.rdd$lzycompute(Dataset.scala:3200)
	at org.apache.spark.sql.Dataset.rdd(Dataset.scala:3198)
	at cn.huorong.utils.PhoenixUtil$.jdbcBatchInsert(PhoenixUtil.scala:216)
	at cn.huorong.run.SampleTaskSinkHbaseMapping_OfficialService.storePhoenix(SampleTaskSinkHbaseMapping_OfficialService.scala:94)
	at cn.huorong.run.SampleTaskSinkHbaseMapping_OfficialService.$anonfun$sink$1(SampleTaskSinkHbaseMapping_OfficialService.scala:74)
	at cn.huorong.run.SampleTaskSinkHbaseMapping_OfficialService.$anonfun$sink$1$adapted(SampleTaskSinkHbaseMapping_OfficialService.scala:37)
	at cn.huorong.run.SampleTaskSinkHbaseMapping_OfficialService$$Lambda$1277/1357069303.apply(Unknown Source)
	at org.apache.spark.streaming.dstream.DStream.$anonfun$foreachRDD$2(DStream.scala:629)
	at org.apache.spark.streaming.dstream.DStream.$anonfun$foreachRDD$2$adapted(DStream.scala:629)
	at org.apache.spark.streaming.dstream.DStream$$Lambda$1291/1167476357.apply(Unknown Source)
	at org.apache.spark.streaming.dstream.ForEachDStream.$anonfun$generateJob$2(ForEachDStream.scala:51)
	at org.apache.spark.streaming.dstream.ForEachDStream$$Lambda$1576/1966952151.apply$mcV$sp(Unknown Source)
	at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23)
	at org.apache.spark.streaming.dstream.DStream.createRDDWithLocalProperties(DStream.scala:417)
	at org.apache.spark.streaming.dstream.ForEachDStream.$anonfun$generateJob$1(ForEachDStream.scala:51)
	at org.apache.spark.streaming.dstream.ForEachDStream$$Lambda$1563/607343052.apply$mcV$sp(Unknown Source)
	at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23)
  
  2022-07-23 02:01:34 WARN scheduler.AsyncEventQueue: Dropped 429 events from shared since Sat Jul 23 02:00:29 CST 2022.
Exception in thread "dispatcher-event-loop-0" java.lang.OutOfMemoryError: GC overhead limit exceeded
	at scala.runtime.ObjectRef.create(ObjectRef.java:24)
	at org.apache.spark.rpc.netty.Inbox.process(Inbox.scala:86)
	at org.apache.spark.rpc.netty.MessageLoop.org$apache$spark$rpc$netty$MessageLoop$$receiveLoop(MessageLoop.scala:75)
	at org.apache.spark.rpc.netty.MessageLoop$$anon$1.run(MessageLoop.scala:41)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

原因分析:

1.主要原因:
2022-07-23 01:03:40 WARN scheduler.AsyncEventQueue: Dropped 1 events from shared since the application started.
  • 所有 Spark 作业、阶段和任务都被推送到事件队列。
  • 后端侦听器从该队列读取 Spark UI 事件,并呈现 Spark UI。
  • 事件队列(spark.scheduler.listenerbus.eventqueue.capacity)的默认容量为 10000。

如果推送到事件队列的事件数超过后端侦听器可使用的事件数,则会从队列中删除最旧的事件,并且侦听器永远不会使用它们。

这些事件会丢失,并且不会在 Spark UI 中呈现。

2.源码分析
/**
  初始化 event队列大小
  LISTENER_BUS_EVENT_QUEUE_PREFIX = "spark.scheduler.listenerbus.eventqueue"
  LISTENER_BUS_EVENT_QUEUE_CAPACITY = .createWithDefault(10000)
**/
private[scheduler] def capacity: Int = {
  val queueSize = conf.getInt(s"$LISTENER_BUS_EVENT_QUEUE_PREFIX.$name.capacity",
                              conf.get(LISTENER_BUS_EVENT_QUEUE_CAPACITY))
  assert(queueSize > 0, s"capacity for event queue $name must be greater than 0, " +
         s"but $queueSize is configured.")
  queueSize //默认10000
}
3.Spark官网

在这里插入图片描述


解决方案:

1.解决丢event的方法实际上是用Spark提供的参数,静态的让队列在初始化的时候容量变大了,这需要driver的内存大一点

2.将群集级别的群集的 Spark 配置中的 spark.scheduler.listenerbus.eventqueue.capacity 值设置为大于 10000 的值。

3.此值设置应用状态事件队列的容量,其中包含内部应用程序状态侦听器的事件。 增大此值后,事件队列可以容纳更多的事件,但可能会导致驱动程序使用更多内存。

#参考
Spark里Histroy Server丢task,job和Stage问题调研


新发现

最近,同事找到了git上别人提的PR,发现了问题的本质,下面贴出原链接
https://github.com/apache/spark/pull/31839

原文:

在这里插入图片描述

翻译一下:
这个 PR 提出了一种修复 ExectionListenerBus 的内存泄漏的替代方法,这种方法会自动清除这些内存泄漏。

基本上,我们的想法是将 registerSparkListenerForCleanup 添加到 ContextCleaner,
这样当 SparkSession 被 GC‘ ed 时,我们就可以从 LiveListenerBus 中删除 ExectionListenerBus。

另一方面,为了使 SparkSession 能够 GC,我们需要去掉 ExectionListenerBus 中的 SparkSession 引用。
因此,我们引入了 sessionUUID (一个 SparkSession 的唯一标识符)来替换 SparkSession 对象。
SPARK-34087

在这里插入图片描述


分析

从这我们可以看出,这个是spark3.0.1的一个bug,ExecutionListenerBus这个玩意会一直增长,gc后也不会减小,又因为默认队列长度只有1万,增长到1万,会删除旧的,但是有个问题就是删除旧的速度 小于新增加的速度,那队列就会变得很长,一直在内存里面就会导致Driver OOM

下面记录一下如何查看 ExecutionListenerBus
  • 1.找到driver所在节点
    1. 找到driver所在的AM
[node04 userconf]# jps |  grep ApplicationMaster
168299 ApplicationMaster
168441 ApplicationMaster
[node04 userconf]# ps -ef | grep application_1658675121201_0408 | grep 168441
hadoop   168441 168429 24 Jul27 ?        07:53:51 /usr/java/jdk1.8.0_202/bin/java -server -Xmx2048m -Djava.io.tmpdir=/tmp/hadoop-hadoop/nm-local-dir/usercache/hadoop/appcache/application_1658675121201_0408/container_e47_1658675121201_0408_01_000001/tmp -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -Dspark.yarn.app.container.log.dir=/var/log/udp/2.0.0.0/hadoop/userlogs/application_1658675121201_0408/container_e47_1658675121201_0408_01_000001 org.apache.spark.deploy.yarn.ApplicationMaster --class cn.huorong.SampleTaskScanMapping_Official --jar file:/data/udp/2.0.0.0/dolphinscheduler/exec/process/5856696115520/5888199825472_7/70/4192/spark实时/taskmapping_official_stream-3.0.3.jar --arg -maxR --arg 100 --arg -t --arg hr_task_scan_official --arg -i --arg 3 --arg -g --arg mappingOfficialHbaseOfficial --arg -pn --arg OFFICIAL --arg -ptl --arg SAMPLE_TASK_SCAN,SCAN_SHA1_M_TASK,SCAN_TASK_M_SHA1 --arg -hp --arg p --arg -local --arg false --properties-file /tmp/hadoop-hadoop/nm-local-dir/usercache/hadoop/appcache/application_1658675121201_0408/container_e47_1658675121201_0408_01_000001/__spark_conf__/__spark_conf__.properties --dist-cache-conf /tmp/hadoop-hadoop/nm-local-dir/usercache/hadoop/appcache/application_1658675121201_0408/container_e47_1658675121201_0408_01_000001/__spark_conf__/__spark_dist_cache__.properties

  • 3.进入 arthas
//切到普通用户
java -jar arthas-boot.jar --telnet-port 9998 -http-port -1
找到168441 对应坐标
  • 4 利用arthas 查看实例数量
//多执行几次 可以看到 实例数量一直在增长
[arthas@168441]$ vmtool --action getInstances --className *ExecutionListenerBus --limit 10000 --express 'instances.length'
@Integer[2356]

解决:

spark官方建议,升级到spark 3.0.3即可解决,我们原本是3.0.1,小版本升级,就替换了spark jar包即可,再去监控一下listenerBus数量,就发现数量就会出现波动了。
把那个任务开启,观察了2天,发现一切正常。至此,排查了5天算是解决了。

<think>好的,用户遇到了JavaScript中的TypeError: Cannot read properties of undefined (reading 'type')错误,需要解决这个问题。首先,我需要理解这个错误的原因。通常,这种错误发生在试图访问一个未定义(undefined)对象的属性时,比如obj.type中的obj是undefined。 接下来,我应该分步骤考虑可能的解决方法。首先,检查代码中报错的位置,确定是哪个变量未定义。用户提供的文件列表中有dataSample.js、reset function、Scheduler.js、task.js、util.js等,可能需要在这些文件中查找问题。 第一步,建议用户使用开发者工具进行断点调试,或者添加console.log语句来输出相关变量,确认变量在出错时的状态。例如,在访问obj.type之前,先打印obj,看看是否是undefined。 第二步,考虑变量未定义的原因。可能是异步操作未完成,比如数据未正确加载或初始化,导致变量未被正确赋值。这时候需要确保变量在使用前已经被正确初始化,或者在访问前进行空值检查,比如使用可选链操作符obj?.type。 第三步,检查函数调用和参数传递是否正确。例如,在调用reset函数或Scheduler.js中的方法时,是否遗漏了必要的参数,导致传入的变量为undefined。需要确保所有函数调用时参数正确,并且依赖的模块正确导入。 第四步,检查模块导入和导出是否正确。例如,在util.js中导出的函数或变量,在其他文件中是否正确导入,路径是否正确,是否存在拼写错误。如果导入失败,变量会是undefined,访问其属性就会出错。 第五步,考虑作用域问题。是否在某个作用域内意外覆盖了变量,导致其值为undefined。比如在函数内部声明了同名的变量,导致外部变量被覆盖。 第六步,查看是否有拼写错误或属性名错误。例如,属性名是否是type,而不是typo或者其他名称,尤其是在动态生成属性名的情况下,容易出错。 第七步,如果是第三方库或框架的问题,检查相关文档,确认使用方式是否正确。比如在React或Vue中,是否正确初始化了组件或状态。 第八步,使用TypeScript或添加类型检查,可以在开发阶段捕获这类错误,但用户当前可能没有使用,所以需要手动检查。 最后,结合用户提供的引用内容,引用[1]提到在页面加载完成后执行代码,如果代码在DOM未加载时执行,可能会访问未初始化的元素,导致变量未定义。因此,需要确保代码在正确的事件(如load事件)中执行,避免在元素未加载时访问它们。 综合以上步骤,用户需要逐步排查变量未定义的原因,从代码位置、变量初始化、函数调用、模块导入、作用域等方面进行检查,并使用调试工具确认变量的状态,从而解决这个TypeError。</think>### JavaScript TypeError: Cannot read properties of undefined (reading 'type') 解决方案 #### 1. 定位错误来源 首先通过浏览器开发者工具(F12)查看报错堆栈,确定具体代码文件和行号。例如在`dataSample.js`第15行出现`obj.type`访问错误,说明`obj`此时为`undefined`[^3]。 #### 2. 基础调试方法 在访问属性前添加空值检查: ```javascript // 修改前(错误示例) console.log(obj.type); // 修改后(添加可选链操作符) console.log(obj?.type); ``` 或显式判断对象存在性: ```javascript if (obj && obj.type) { // 安全操作 } ``` #### 3. 常见原因与修复 - **场景1:异步数据未就绪** 在数据加载完成前访问属性会导致错误: ```javascript // 错误示例(假设fetchData是异步函数) const data = fetchData(); console.log(data.type); // data可能为undefined // 修复:确保在异步操作完成后访问 fetchData().then(data => { console.log(data.type); }); ``` - **场景2:函数参数缺失** 在`reset`函数或`Scheduler.js`中检查参数传递: ```javascript // 错误示例 function reset(config) { console.log(config.type); // config未传入时导致错误 } // 修复:添加默认值 function reset(config = { type: 'default' }) { console.log(config.type); } ``` - **场景3:模块导入失败** 检查`util.js`或`task.js`的导出/导入语句: ```javascript // util.js export const helper = { type: 'utils' }; // Scheduler.js import { helper } from './util.js'; // 确保路径正确 ``` #### 4. 高级调试技巧 在`util.js`中添加日志跟踪: ```javascript export function getTask() { console.trace('检查任务对象来源'); // 追踪调用链 return currentTask; // 可能返回undefined } ``` #### 5. 预防措施 - 使用TypeScript定义接口类型 - 启用ESLint规则`no-undef`检测未定义变量 - 关键操作添加`try-catch`块: ```javascript try { const type = obj.type; } catch (error) { console.error('对象未定义', error); } ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值