今天在一个集群上通过spark-submit方式提交作业,但发现作业在运行不久后,控制台的日志就停住不变了,一直到CRT的session超时也没有变化,截图如下:
![C]9TWSOXPF8L2Q{PXA6M11Y.png](http://upload-images.jianshu.io/upload_images/4359319-fbf3a54f60aa3aa9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
发现这个情况,只好查看application的日志了,通过命令
yarn -logs applicationId=application_xxxx_xxx 查看当前应用的日志:发现除kill应用程序产生的ERROR外,并无其他日志出现:
从截图中可以看出作业运行一段时间后就不再产生日志,直到被kill时。
同时查看spark web界面,发现作业没有往下执行
![`]0VLV9%UOU_%5R9B8AT~)K.png](http://upload-images.jianshu.io/upload_images/4359319-61b87cb4af892f7f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
实在是太诡异了,下面说下我的排查思路吧:
因为日志留在广播数据那里,因此特地查了一下Spark 广播变量的原理:
默认情况下,task算子中,使用了外部变量,每个task都会从Driver获取一份变量的副本,要通过网络通信或者网卡。
广播变量,初始的时候,就在Driver上有一份副本。task在运行时,想要使用广播变量中的数据,此时首先会在自己本地的Executor对应的BlockManager中,尝试获取变量副本;如果本地没有,那么就从Driver拉取副本,并保存在本地的BlockManager中;
此后这个executor上的task,都会直接使用本地的BlockManager中的副本
executor的BlockManager除了从driver上拉取,也可能从其他节点的BlockManger上拉取变量副本,距离越近越好。
推测的可能的原因:
-
作业配置参数问题:
当前spark-submit脚本配置为
查看当前linux集群环境:
# 总核数 = 物理CPU个数 X 每颗物理CPU的核数
总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数
查看物理CPU个数
cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l查看每个物理CPU中core的个数(即核数)
cat /proc/cpuinfo| grep "cpu cores"| uniq查看逻辑CPU的个数
cat /proc/cpuinfo| grep "processor"| wc -l查看线程数
cat /proc/cpuinfo | grep 'processor' | sort -u | wc -l
已知当前集群七台节点,224G内存,336个VCores。按照当前配置,应该是可以运行
的,因此排除了这个原因。
此外关闭了一个配置,conf.set("spark.shuffle.service.enabled ", "false")
![Paste_Image.png](http://upload-images.jianshu.io/upload_images/4359319-
887c50c8edabadd5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
截图中的原因是说:会启用额外的Shuffle服务,BlockManager通讯会有些问题,这种额
外的shuffle服务不是actormodel的方式,没有具体深入。 - 代码问题:
既然集群环境和配置没问题,那么多半就是代码的问题了。拷贝一些数据到本地,发现在本地程序也不能执行。最后终于发现,是由于集群上的数据格式被改变了,字段数增多了。而切分字段是使用的一个工具类,修改限制,运行后可正常运行。
可以说是一个很无语的问题,至于为什么会卡住,推测是由于我把异常的地方catch住了。