spark 2.1.1

一 问题重现

问题代码示例

object MethodPositionTest {

  val sparkConf = new SparkConf().setAppName("MethodPositionTest")

  val sc = new SparkContext(sparkConf)

  val spark = SparkSession.builder().enableHiveSupport().getOrCreate()

  def main(args : Array[String]) : Unit = {

    val cnt = spark.sql("select * from test_table").rdd.map(item => mapFun(item.getString(0))).count

    println(cnt)

  }

  def mapFun(str : String) : String = "p:" + str

}

当如下3行代码放到main外时

val sparkConf = new SparkConf().setAppName(getName)

val sc = new SparkContext(sparkConf)

val spark = SparkSession.builder().enableHiveSupport().getOrCreate()

有一定几率报错:

Caused by: java.lang.ExceptionInInitializerError

    at app.package.AppClass$$anonfun$1.apply(AppClass.scala:208)

at org.apache.spark.sql.execution.MapElementsExec$$anonfun$8$$anonfun$apply$1.apply(objects.scala:237)

at org.apache.spark.sql.execution.MapElementsExec$$anonfun$8$$anonfun$apply$1.apply(objects.scala:237)

at scala.collection.Iterator$$anon$11.next(Iterator.scala:409)

at scala.collection.Iterator$$anon$11.next(Iterator.scala:409)

at scala.collection.Iterator$class.foreach(Iterator.scala:893)

at scala.collection.AbstractIterator.foreach(Iterator.scala:1336)

at scala.collection.generic.Growable$class.$plus$plus$eq(Growable.scala:59)

at scala.collection.mutable.ArrayBuffer.$plus$plus$eq(ArrayBuffer.scala:104)

at scala.collection.mutable.ArrayBuffer.$plus$plus$eq(ArrayBuffer.scala:48)

at scala.collection.TraversableOnce$class.to(TraversableOnce.scala:310)

at scala.collection.AbstractIterator.to(Iterator.scala:1336)

at scala.collection.TraversableOnce$class.toBuffer(TraversableOnce.scala:302)

at scala.collection.AbstractIterator.toBuffer(Iterator.scala:1336)

at scala.collection.TraversableOnce$class.toArray(TraversableOnce.scala:289)

at scala.collection.AbstractIterator.toArray(Iterator.scala:1336)

at org.apache.spark.rdd.RDD$$anonfun$collect$1$$anonfun$13.apply(RDD.scala:936)

at org.apache.spark.rdd.RDD$$anonfun$collect$1$$anonfun$13.apply(RDD.scala:936)

at org.apache.spark.SparkContext$$anonfun$runJob$5.apply(SparkContext.scala:1951)

at org.apache.spark.SparkContext$$anonfun$runJob$5.apply(SparkContext.scala:1951)

at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:87)

at org.apache.spark.scheduler.Task.run(Task.scala:99)

    at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:322)

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)

at java.lang.Thread.run(Thread.java:745)

Caused by: org.apache.spark.SparkException: A master URL must be set in your configuration

    at org.apache.spark.SparkContext.<init>(SparkContext.scala:379)

at app.package.AppClass$.<clinit>(AppClass.scala)

二 问题解析

MethodPositionTest 定义了一个匿名函数anonfun,这个匿名函数在RDD.map中调用,即在Executor中执行,匿名函数中又依赖mapFun方法,触发类的初始化:MethodPositionTest$.<clinit>,初始化时会执行main外的spark初始化代码,即在Executor中创建SparkConf和SparkContext,这是不应该发生的,一个spark应用中只能有一个SparkContext并且应该在Driver端而不是Executor,而且发生之后会导致错误,代码如下:

org.apache.spark.SparkContext

  try {

    _conf = config.clone()

    _conf.validateSettings()

    if (!_conf.contains("spark.master")) {

      throw new SparkException("A master URL must be set in your configuration")

    }

问题1)为什么在Driver端不会报错找不到master,而在Executor端会报错

Spark应用代码如下:

val sparkConf = new SparkConf().setAppName(getName)

这里SparkConf只设置了AppName,为什么在Driver端不会报错找不到master,而在Executor端会报错,这里需要看Spark Submit的执行过程,详见 https://www.cnblogs.com/barneywill/p/9820684.html

Driver端执行时SparkSubmit会将各种参数包括命令行、配置文件、系统环境变量等,统一设置到系统环境变量

for ((key, value) <- sysProps) {

System.setProperty(key, value)

}

然后SparkConf会默认从系统环境变量中加载配置

for ((key, value) <- Utils.getSystemProperties if key.startsWith("spark.")) {

set(key, value, silent)

}

所以Driver端的SparkConf会包含所有的参数,但是Executor端则没有。

问题2)当spark相关的初始化代码在main外时,为什么有时报错,有时不报错

具体情形如下:
1)如果main里边的transformation(示例中的map方法)不依赖外部函数调用,正常;
2)如果main里边的transformation(示例中的map方法)依赖main里的函数,报错;
3)如果main里边的transformation(示例中的map方法)依赖main外的函数,报错;

这里可以通过反编译代码来看原因,示例MethodPositionTest的反编译代码如下:

public final class MethodPositionTest$

{

         public static final MethodPositionTest$ MODULE$ = this;

         private final SparkConf sparkConf = (new SparkConf()).setAppName("MethodPositionTest");

         private final SparkContext sc = new SparkContext(sparkConf());

         private final SparkSession spark;

         public SparkConf sparkConf()

         {

                  return sparkConf;

         }

         public SparkContext sc()

         {

                  return sc;

         }

         public SparkSession spark()

         {

                  return spark;

         }

         public String mapFun(String str)

         {

                  return (new StringBuilder()).append("p:").append(str).toString();

         }

         public void main(String args[])

         {

                  long cnt = spark().sql("select * from test_table").rdd().map(new Serializable() {

                          public static final long serialVersionUID = 0L;

                          public final String apply(Row item)

                          {

                                   return MethodPositionTest$.MODULE$.mapFun(item.getString(0));

                          }

                          public final volatile Object apply(Object v1)

                          {

                                   return apply((Row)v1);

                          }

                  }, ClassTag$.MODULE$.apply(java/lang/String)).count();

                  Predef$.MODULE$.println(BoxesRunTime.boxToLong(cnt));

         }

         private MethodPositionTest$()

         {

                  spark = SparkSession$.MODULE$.builder().enableHiveSupport().getOrCreate();

         }

         static

         {

                  new MethodPositionTest$();

         }

}

可见这里的匿名内部类依赖类MethodPositionTest$的方法mapFun,所以会触发类MethodPositionTest$的加载以及静态代码块执行,触发报错;

综上,不建议将spark的初始化代码放到main外,很容易出问题。

【原创】大叔问题定位分享(10)提交spark任务偶尔报错 org.apache.spark.SparkException: A master URL must be set in your configuration的更多相关文章

  1. 【原创】大叔问题定位分享(5)Kafka客户端报错SocketException: Too many open files 打开的文件过多

    kafka0.8.1 一 问题 10月22号应用系统忽然报错: [2014/12/22 11:52:32.738]java.net.SocketException: 打开的文件过多 [2014/12/ ...

  2. 【原创】大叔问题定位分享(29)datanode启动报错:50020端口被占用

    集群中有一台datanode一直启动报错如下: java.net.BindException: Problem binding to [$server1:50020] java.net.BindExc ...

  3. 【原创】大叔问题定位分享(31)hive metastore报错

    hive metastore在建表时报错 [pool-5-thread-2]: MetaException(message:Got exception: java.net.ConnectExcepti ...

  4. Spark异常:A master URL must be set in your configuration处理记录

    问题描述:    项目中一位同事提交了一部分代码,代码分为一个抽象类,里面含有sparkcontent,sparkSession对象:然后又三个子类实例化上述抽象类,这三个子类处理三个任务,最后在同一 ...

  5. myeclipse 10 载入新的项目报错Cannot return from outside a function or method

    myeclipse 10 载入新的项目报错Cannot return from outside a function or method 解决方法: 方法一: window -->prefere ...

  6. Error- Overloaded method value createDirectStream in error Spark Streaming打包报错

    直接上代码 StreamingExamples.setStreamingLogLevels() val Array(brokers, topics) = args // Create context ...

  7. Spark程序编译报错error: object apache is not a member of package org

    Spark程序编译报错: [INFO] Compiling 2 source files to E:\Develop\IDEAWorkspace\spark\target\classes at 156 ...

  8. 【原创】大叔问题定位分享(8)提交spark任务报错 Caused by: java.lang.ClassNotFoundException: org.I0Itec.zkclient.exception.ZkNoNodeException

    spark 2.1.1 一 问题重现 spark-submit --master local[*] --class app.package.AppClass --jars /jarpath/zkcli ...

  9. 【原创】大叔问题定位分享(9)oozie提交spark任务报 java.lang.NoClassDefFoundError: org/apache/kafka/clients/producer/KafkaProducer

    oozie中支持很多的action类型,比如spark.hive,对应的标签为: <spark xmlns="uri:oozie:spark-action:0.1"> ...

随机推荐

  1. jeecg字典表—普通表

    创建普通表 同步数据库(创建对应的表) 验证功能效果 添加用户表,并添加对应的级别属性 同步用户表 字典功能测试 然后生成最新代码,添加到菜单即可

  2. 软件工程(FZU2015) 赛季得分榜,第11回合(beta冲刺+SE总结)

    SE_FZU目录:1 2 3 4 5 6 7 8 9 10 11 12 13 积分规则 积分制: 作业为10分制,练习为3分制:alpha30分:beta30分 团队项目分=团队得分+个人贡献分 个人 ...

  3. HTTP状态码表

    HTTP状态码(英语:HTTP Status Code)是用以表示网页服务器HTTP响应状态的3位数字代码.所有状态码的第一个数字代表了响应的五种状态之一. 1xx消息 这一类型的状态码,代表请求已被 ...

  4. mysql-笔记-命名、索引规范

    1 命名规范 所有数据库对象名称必须使用小写字母并用下划线分割 禁止使用mysql保留关键字 ---如果表名中包含关键字查询时,需要将其有单引号括起来 见名识意,并且最后不要超过32个字符 临时库表以 ...

  5. Nginx 进程间如何共享内存

    L:37 Nginx 针对多进程用的是自旋锁(占用共享内存时间比较短的情况下否则可能会影响性能)注:自旋锁是不停的请求共享内存 而原先的信号量是等待占用者释放后通知等待的进程

  6. 一分钟学会JavaMail(假)__手动滑稽

    因为公司内部办公系统(OA)需要增加一个发送邮件的功能,所以学习了这个感觉比较冷门的JavaMail   1.先上成功截图 : 2.准备事项:Java Mail虽然是官方写的,但是没有集成到jdk里面 ...

  7. 清北澡堂 Day2 下午 一些比较重要的数论知识整理

    1.欧拉定理 设x1,x2,.....,xk,k=φ(n)为1~n中k个与n互质的数 结论一:axi与axj不同余 结论二:gcd(axi,n)=1 结论三:x1,x2,...,xk和ax1,ax2, ...

  8. hihoCoder #1770 : 单调数(数位dp)

    题面 我们定义一个数是单调数,当且仅当构成这个数每一个数位都是单调不降或不增的. 例如 \(123\) 和 \(321\) 和 \(221\) 和 \(111\) 是单调的,而 \(312\) 不是单 ...

  9. Python【初识篇】简介

    python是什么? 为什么学python? python在权威语言排序网站上的热度 python历史排名 python应用领域 哪些公司在用python python官方简介 上面的话简单的总结来说 ...

  10. 【mysql】mysql存储引擎

    了解存储引擎我们先看下mysql的体系架构. 上图是mysql的逻辑架构图,可以看到分了几层. 第一层是大部分网路客户端工具,比如php,python  ,JDBC等,主要功能就是连接处理,授权认证等 ...