这个问题困扰了我一个周末……一个周末……(然后其实后面又困扰了一周)
而且重启注销,不懂是不是因为ubuntu kylin不稳定
【结果】是因为单集群的问题,导致yarn一次只能运行一个job。在服务器上跑就没有事儿,在自己的虚拟机上跑就不行,因为没配备多个虚拟机。——————【你以为是这样就大错特错了】
【真实原因】未开启yarn多线程模式,也就是scheduler为单线程单队列运行
如图,点开日志可以看到自己写的py程序正确地输出了结果。可以点开log来看。这里吐槽下,有些人忽视web界面的作用,觉得什么都用yarn命令行来查就好……真的很不方便的。web还能自动给你归类好,节省了大量无意义的工作,使你更专注解决exception等问题。
至于为什么会出现一直ACCEPTED不RUNNING的结果,因为Oozie提交pyspark任务是通过mapreduce来提交的。它先提交一个mapreduce任务,而这个mapreduce任务里面包含pyspark任务,造成2个任务同时在提交。如果yarn是单节点的,一次只能运行一个任务,那么就悲剧了。mapreduce提交了pyspark,此时mapreduce任务在running中,yarn已经没有slot给其它job了,然后,虽然pyspark已经ACCEPTED了但就是不能running。pyspark不running并结束,mapreduce也结束不了,无法释放资源给pyspark。
如何发现这样的问题呢?你在yarn命令行通过kill命令杀掉那个mapreduce,然后spark的job就能正常运行并出来结果了。
那么原因既然是没能2个job同时运行,那如何解决呢?我们查看一直在ACCEPTED的job的application_id,连接到相应的log,会发现它一直在重复如下的信息,就是不RUNNING:
INFO [communication thread] .TaskAttemptListenerImpl: Progress of TaskAttempt attempt_1458755526820_9216_m_000000_0 is : 1.0
会觉得这个yarn默认模式笨的感人。解决这个问题有2个方案,一个是配置多个队列,第二个是配置一个FairScheduler。
有人就奇怪了,yarn本身不就是多线程的吗?为什么会出现这个问题,这就要谈到队列的概念。在yarn里面,提交任务需要指定queue(队列)的:
“使用过第一代hadoop的同学应该比较熟悉/这个参数,无论是map还是reduce都可以配置capacity(也就是并发数),表示同时可以有多少个map(或reduce)运行,通过这个参数可以限制一个任务同时占用的资源(节点)数,这样不至于影响其他任务的执行。
第二代hadoop因为使用yarn做资源管理,没有了槽位的概念,所以就没有了capacity。但是在yarn中专门有了CapacityScheduler这个组件。这是一个可插装的调度器,它的用途就是对多用户实现共享大集群并对每个用户资源占用做控制。
对于很豪的公司来说,每个用户(团队)自己有一个hadoop集群,这样可以提高自身的稳定性和资源供应,但是确降低了资源利用率,因为很多集群大多数时间都是空闲的。CapacityScheduler能实现这样的功能:每个组固定享有集群里的一部分资源,保证低保,同时如果这个固定的资源空闲,那么可以提供给其他组来抢占,但是一旦这些资源的固定使用者要用,那么立即释放给它使用。这种机制在实现上是通过queue(队列)来实现的。当然CapacityScheduler还支持子队列(sub-queue)。”——参考
/articles/VNJNBr7
【解决方案】配置
yarn多线程运行模式:
如果一直显示这样的:
INFO [communication thread] .
TaskAttemptListenerImpl: Progress of TaskAttempt attempt_1458755526820_9216_m_000000_0 is : 1.0
那么确实是调度器的问题。
在可行的解决方案中,增加队列可能没那么快,而修改调度器为FairSchduler是比较现成和快的解决方案:
修改文件,添加如下:
<!-- scheduler configuration, for multi-tasks run in queue, avoid mapreduce-run & pyspark ACCEPTED not run problem -->
<!-- 下面配置用来设置集群利用率的阀值, 默认值0.8f,最多可以抢占到集群所有资源的80% -->
|
开启公平调度器。之后我们再在8088端口查看pyspark的job的时候,会发现,虽然刚开始依然处于ACCEPTED的状态,但已经正常分配给拥有nodemanager节点的机子并初始化了。等一阵子后就开始RUNNING了。再也不会发生卡壳的问题。
=============================无关的探索============================
PS:为了解决这个ACCEPTED问题,一直以为是没有更改源码使其支持py,所以总想着重新编译。而重新编译又想着是不是更新下内部软件比较好呢?于是修改了kryo的版本,修改了tomcat的版本,结果编译期间各种出问题。
【问题Unexpected end of ZLIB input stream】
这个只能重新解压源码,配置一遍再重新编译。第二次编译就好了。问题的原因可能是之前编译到一半各种杂七杂八的编码问题导致创建压缩包失败。
【问题JasperListener】
19-Feb-2017 10:23:11.868 WARNING [main] using conf/: Error at (28, 67) :
19-Feb-2017 10:23:11.875 SEVERE [main] Begin event threw exception
进oozie-server/conf把JasperListener注释掉。同理注释掉:
参考类推:/hzw2312/article/details/13621645
【问题 IOException Could not authenticate, Authentication failed】
启动oozie后,查询status遇到
IOException: Error w hile connecting Oozie server. No of retries = 1. Exception = Could not authenticate, Authentication failed, status: 500, message: null
最后咋解决都不行,老老实实编译回tomcat 6可以用了
编译完成后别忘了prepare war。旧的sql数据应该可以继续用,把配置文件直接迁移过来就好
=============================无关的探索==============================
附录:
1、关于公平调度器的介绍:
/jthink_/article/details/50112529
…………调度器将作业组织放入很多“队列”,这些队列会公平的共享所有的集群资源。默认情况下,所有的用户共享一个名叫“defalut”的队列。如果一个作业指定请求某个队列,那么这个作业将被提交到该队列。另外,通过配置可以根据提交作业的用户来分配进入相应的队列。在每个队列内部,同样有一个调度策略调度在每个队列中运行的作业,默认的策略是基于内存的公平分配,但是也可以配置成FIFO或者基于不同类型资源的公平分配。队列可以按照层次结构来划分资源,并和权重一起按照一定的比例共享集群资源…………