内存溢出问题
但是,上述情况是在yarn-cluster模式下出现,yarn-client模式运行时倒是正常的,原来在$SPARK_HOME/bin/spark-class文件中已经设置了持久代大小:
在Spark中使用hql方法执行hive语句时,由于其在查询过程中调用的是Hive的获取元数据信息、SQL解析,并且使用Cglib等进行序列化反序列化,中间可能产生较多的class文件,导致JVM中的持久代使用较多,如果配置不当,可能引起类似于如下的OOM问题:
原因是实际使用时,如果用的是JDK1.6版本,
Server模式的持久代默认大小是64M,Client模式的持久代默认大小是32M,而Driver端进行SQL处理时,其持久代的使用可能会达到90M,导致OOM溢出,任务失败。
解决方法就是在Spark的conf目录中的
spark-defaults.conf里,增加对Driver的JVM配置,因为Driver才负责SQL的解析和元数据获取。配置如下:
但是,上述情况是在yarn-cluster模式下出现,yarn-client模式运行时倒是正常的,原来在$SPARK_HOME/bin/spark-class文件中已经设置了持久代大小:
当以yarn-client模式运行时,driver就运行在客户端的spark-submit进程中,其JVM参数是取的spark-class文件中的设置,所谓未出现持久代溢出现象。
总结一下Spark中各个角色的JVM参数设置:
(1)Driver的JVM参数:
-Xmx,-Xms,如果是yarn-client模式,则默认读取 spark-env文件中的SPARK_DRIVER_MEMORY值,-Xmx,-Xms值一样大小;如果是yarn-cluster模式,则读取的是spark-default.conf文件中的spark.driver.extraJavaOptions对应的JVM参数值。
PermSize,如果是yarn-client模式,则是默认读取spark-class文件中的JAVA_OPTS="-XX:MaxPermSize=256m $OUR_JAVA_OPTS"值;如果是yarn-cluster模式,读取的是spark-default.conf文件中的spark.driver.extraJavaOptions对应的JVM参数值。
GC方式,如果是yarn-client模式,默认读取的是spark-class文件中的JAVA_OPTS;如果是yarn-cluster模式,则读取的是spark-default.conf文件中的spark.driver.extraJavaOptions对应的参数值。
以上值最后均可被spark-submit工具中的--driver-java-options参数覆盖。
-Xmx,-Xms,如果是yarn-client模式,则默认读取 spark-env文件中的SPARK_DRIVER_MEMORY值,-Xmx,-Xms值一样大小;如果是yarn-cluster模式,则读取的是spark-default.conf文件中的spark.driver.extraJavaOptions对应的JVM参数值。
PermSize,如果是yarn-client模式,则是默认读取spark-class文件中的JAVA_OPTS="-XX:MaxPermSize=256m $OUR_JAVA_OPTS"值;如果是yarn-cluster模式,读取的是spark-default.conf文件中的spark.driver.extraJavaOptions对应的JVM参数值。
GC方式,如果是yarn-client模式,默认读取的是spark-class文件中的JAVA_OPTS;如果是yarn-cluster模式,则读取的是spark-default.conf文件中的spark.driver.extraJavaOptions对应的参数值。
以上值最后均可被spark-submit工具中的--driver-java-options参数覆盖。
(2)Executor的JVM参数:
-Xmx,-Xms,如果是yarn-client模式,则默认读取spark-env文件中的SPARK_EXECUTOR_MEMORY值,-Xmx,-Xms值一样大小;如果是yarn-cluster模式,则读取的是spark-default.conf文件中的spark.executor.extraJavaOptions对应的JVM参数值。
PermSize,两种模式都是读取的是 spark-default.conf文件中的spark.executor.extraJavaOptions对应的JVM参数值。
GC方式,两种模式都是读取的是spark-default.conf文件中的spark.executor.extraJavaOptions对应的JVM参数值。
-Xmx,-Xms,如果是yarn-client模式,则默认读取spark-env文件中的SPARK_EXECUTOR_MEMORY值,-Xmx,-Xms值一样大小;如果是yarn-cluster模式,则读取的是spark-default.conf文件中的spark.executor.extraJavaOptions对应的JVM参数值。
PermSize,两种模式都是读取的是 spark-default.conf文件中的spark.executor.extraJavaOptions对应的JVM参数值。
GC方式,两种模式都是读取的是spark-default.conf文件中的spark.executor.extraJavaOptions对应的JVM参数值。
(3)Executor数目及所占CPU个数
如果是yarn-client模式,Executor数目由spark-env中的SPARK_EXECUTOR_INSTANCES指定,每个实例的数目由SPARK_EXECUTOR_CORES指定; 如果是yarn-cluster模式,Executor的数目由spark-submit工具的--num-executors参数指定,默认是2个实例,而每个Executor使用的CPU数目由--executor-cores指定,默认为1核。
每个Executor运行时的信息可以通过yarn logs命令查看到,类似于如下:
如果是yarn-client模式,Executor数目由spark-env中的SPARK_EXECUTOR_INSTANCES指定,每个实例的数目由SPARK_EXECUTOR_CORES指定; 如果是yarn-cluster模式,Executor的数目由spark-submit工具的--num-executors参数指定,默认是2个实例,而每个Executor使用的CPU数目由--executor-cores指定,默认为1核。
每个Executor运行时的信息可以通过yarn logs命令查看到,类似于如下:
其中,akka.tcp://spark@sparktest1:41606/user/CoarseGrainedScheduler表示当前的Executor进程所在节点,后面的1表示Executor编号,sparktest2表示ApplicationMaster的host,接着的3表示当前Executor所占用的CPU数目。