最近有个朋友搭建了一套cdh集群并且运行spark任务,发现数据量不大(低于10G)的时候没问题,数据量太大就报错了,希望我能帮助他解决问题。
看到这个现象我第一反应要么是资源不够要么是新的数据有异常导致的,定位问题就必须跟踪日志,所以任务重新启动,开始跟踪日志,发现第一个错误:RECEIVED SIGNAL TERM
看到这个错误我也没什么感觉,但是我看到这个error的上面一直在跟yarn要资源,同时朋友告诉我数据都是代码生成的,内容都是一样的。我初步判断应该就是资源的问题。
我找到他的all application发现他的内存只有15.29G,所以我认为是给yarn的可分配内存太少了,导致资源不够,让他增加每个节点提供给yarn的resourceManager的内存,通过修改参数yarn.nodemanager.resource.memory-mb,从15.29G改成了25G。
保存修改重启之后,继续查看all application,发现是25G内存,不是应该是25*3=75G的吗?看来哪里还是有问题,我第一想法是难道yarn的nodemanage只有一个是和datanode同一个节点吗(这两个角色同一台服务器yarn才能用到datanode的资源),继续查看配置,发现3个nm分别在3个dn上,有点迷惑,再继续看nm发现了问题:3个nm属于不同的nm group。
刚才修改配置的时候忽略了一个问题,就是他们的集群给rm资源的时候分组了,这3个nm分别在不同的组,导致只能用到一个组的资源,所以all application上面只能显示一个节点的25G,因为他们要分组也没有作用,所以就把他们的分组给去掉了,最后终于有75G的内存资源了。
看来资源问题解决了,开开心心的去重新启动spark程序,成功了,正打算高兴,又发现了问题,明明指定了3个excutor,但是通过查看application的excutor情况发现,只启了两个excutor。
这不是on yarn的吗,就算只有3个datanode但是drive可以和excutor在同一个节点的啊,而且就算不在同一个节点,同一台服务器也可以启动两个excutor的啊,这是为什么?难道还是资源问题吗?百度了一下找到了这句话:executor 数量 = spark.cores.max/spark.executor.cores,我突然想到,会不会是因为指定的spark.executor.cores太大了,3*spark.executor.cores>=spark.cores.max所以就只能起2个excutor,把spark.executor.cores降低试试,果然,最后降到5的时候可以了。
最后问题总算解决了。
总结:1、集群刚搭建完成之后最好有专门的运维来做一下集群的参数调优,特别是资源相关;
2、定位问题一定要先找日志;
3、需要对spark的driver、worker、excutor、task这些有所了解