问题描述:spark使用dynamicAllocation模式,开启external shuffle service,并且yarn上也正常起了spark-shuffle service ,在shuffle过程中,executor总是报connection reset by peer异常,导致拉取shuffle数据失败,任务失败。
尝试了以下措施:
1. spark.shuffle.blockTransferService=nio
2. 怀疑是服务器最大打开文件数达到上限,导致socket拒绝连接,通过ulimit -a 查看最大文件打开数为65536
3. 调大nodemanager启动内存为2g(很早就意识到应该从nodemnager找原因)
4. 服务器开启jstatd,然后用jvisualvm监控,没有发现内存溢出或内存耗尽的情况,看gc曲线也正常
5. jstat -gccause为发现fullgc
6. 减少executor数量上限为6,以为是连接数过多导致
试了以上方法都没有作用,
后来通过查看nodemanager日志才定位到原因,原来是netty包版本与spark shuffle使用的netty包版本冲突,导致spark shuffle服务的线程报NoSuchMethodError,进而关闭连接,所以executor端收到connection reset by peer异常,通过替换netty包解决,将spark jars目录下的netty包拷到nodemanager的lib目录下,注意hdp有hadoop的lib目录和yarn的lib目录,两个都要替换最后问题解决。
总结:定位问题思路真的很重要,有问题不要急着胡乱搞一通,没有思路可以静下来想一想,思考问题可能出现的环节,连接重置其实很简单,无非就是连接两端的问题,找到两端跟连接相关的进程进行定位,主要通过查看日志。对于各种超时的情况很有可能是内存耗尽,jvm长时间fullgc导致,尤其对于分布式应用一般会使用心跳机制检测存活。