公司里面你的机器节点通常都是虚拟机啊!因此yarn-client会有网络激增的问题!Yarn-client模式能够跑,可是Yarn-cluster模式不能跑,就是报那么一个JVM永久代溢出的那么一个问题!node
- spark-submit脚本提交spark application到ResourceManager
- 去ResourceManager申请启动ApplicationMaster
- 通知一个NodeManager去启动ApplicationMaster(Driver进程)
- ApplicationMaster去找ResourceManager申请Executor
- ResourceManager分配container,container表明你能启动的Executor占有的资源,包括内存+CPU返回已经启动container的NodeManager的地址
- ApplicationMaster去找NodeManager在container里面申请启动Executor
- Executor进程会反过来去向Driver注册上去
- 最后Driver接收到了Executor资源以后就能够去进行咱们spark代码的执行了
- 执行到某个action就触发一个JOB
- DAGScheduler会划分JOB为一个个Stage
- TaskScheduler会划分Stage为一个个Task
- Task发送到Executor执行
- Driver就来进行Task的调度
到这里为止,ApplicationMaster(Driver),就知道本身有哪些资源能够用(executor)。而后就会去执行job、拆分stage、提交stage的task,进行task调度,分配到各个executor上面去执行。sql
总结一下yarn-client和yarn-cluster模式的不一样之处:网络
- yarn-client模式,driver运行在本地机器上的;
- yarn-cluster模式,driver是运行在yarn集群上某个nodemanager节点上面的。
- yarn-client会致使本地机器负责spark做业的调度,因此网卡流量会激增;
- yarn-cluster模式就没有这个问题。
- yarn-client的driver运行在本地,一般来讲本地机器跟yarn集群都不会在一个机房的,因此说性能可能不是特别好;
- yarn-cluster模式下,driver是跟yarn集群运行在一个机房内,性能上来讲,也会好一些。
实践经验,碰到的yarn-cluster的问题:app
- 有的时候,运行一些包含了spark sql的spark做业,可能会碰到yarn-client模式下,能够正常提交运行;yarn-cluster模式下,多是没法提交运行的,会报出JVM的PermGen(永久代)的内存溢出,OOM。JVM里面的一个区域,就是会放Class里面一些字符串常量这些东西的。
- yarn-client模式下,driver是运行在本地机器上的,spark使用的JVM的PermGen的配置,是本地的spark-class文件(spark客户端是默认有配置的),JVM的永久代的大小是128M,这个是没有问题的;可是呢,在yarn-cluster模式下,driver是运行在yarn集群的某个节点上的,使用的是没有通过配置的默认设置(PermGen永久代大小),82M。
- spark-sql,它的内部是要进行很复杂的SQL的语义解析、语法树的转换等等,特别复杂,在这种复杂的状况下,若是说你的sql自己特别复杂的话,极可能会比较致使性能的消耗,内存的消耗。可能对PermGen永久代的占用会比较大。
因此,此时,若是对永久代的占用需求,超过了82M的话,可是呢又在128M之内;就会出现如上所述的问题,yarn-client模式下,默认是128M,这个还能运行;若是在yarn-cluster模式下,默认是82M,就有问题了。会报出PermGen Out of Memory error log。jvm
如何解决这种问题?性能
多讲一句,可能还有一个问题(spark sql,sql,要注意,一个问题)测试
- sql,有大量的or语句。好比where keywords='' or keywords='' or keywords='' ,当or语句,有成百上千的时候,此时可能就会出现一个driver端的jvm stack overflow,JVM栈内存溢出的问题
- JVM栈内存溢出,基本上就是因为调用的方法层级过多,由于产生了大量的,很是深的,超出了JVM栈深度限制的,递归。递归方法。咱们的猜想,spark sql,有大量or语句的时候,spark sql内部源码中,在解析sql,好比转换成语法树,或者进行执行计划的生成的时候,对or的处理是递归。or特别多的话,就会发生大量的递归。
- JVM Stack Memory Overflow,栈内存溢出。
- 这种时候,建议不要搞那么复杂的spark sql语句。采用替代方案:将一条sql语句,拆解成多条sql语句来执行。每条sql语句,就只有100个or子句之内;一条一条SQL语句来执行。根据生产环境经验的测试,一条sql语句,100个or子句之内,是还能够的。一般状况下,不会报那个栈内存溢出。