这个问题的现象是在mr程序中经常有map task的状态处于new,该状态表示container已经分配,但是还未启动起来,在这中间的状态是在执行localizing,即下载资源。
一般这个过程不会持续很久,但是在监控界面上看到一个nodemanager上处于localizing状态的container长期达到半数以上。然后在这个机器上执行jps发现运行的YarnChild进程只有10个,正常应该是20个。其他container全部处于localizing阶段。通过执行jps命令后发现运行的containerLocalizer进程有6个一直在运行(在LinuxContainerExecutor模式下,下载资源的工作会由nodemanager fork出一个子进程来完成,而不是在nm进程内完成。所以这里会看到有单独的containerLocalizer进程。一般这样的进程数配置的是8个)然后通过jstack打印containerLocalizer的线程信息发现线程阻塞在了epoll.await()方法上,这种情况的原因是epoll在等待socket连接或者连接中断。通过netstat -anupt | grep 50010命令发现这些进程都是连到某台datanode上,在读取的时候这台datanode当掉了。导致这边的连接丢失,由于hdfs 2.4.0版本的dfsclient中并没有socket超时机制,所以连接丢失后,进程一直挂起。最后的结果就是大部分进程由于这个原因都不再工作,container会一直处于localizing状态,导致mr作业长时间挂起。解决的方法就是把dfsclient的socket超时机制加上,即:
peer.setReadTimeout(dfsClientConf.socketTimeout);