spark.createDataset无法在群集模式下工作

时间:2019-10-07 15:39:04

标签: apache-spark

我有一个在本地模式下工作的驱动程序,但在集群模式下(独立运行)不工作。该驱动程序是一个Java应用程序。我已将驱动程序应用程序jar添加到spark上下文中(我使用maven shade plugin构建了一个巨型jar)。

驱动程序本质上是在尝试从数据库表中获取单个id值,以供以后在自定义映射函数中使用。

驱动程序代码如下:

import scala.collection.JavaConverters;
import scala.collection.Seq;

String sql = "select * from meta.data_source";
PreparedStatement stm = connection.prepareStatement(sql);
stm.execute();
ResultSet rs = stm.getResultSet();
StructType st = JdbcUtils.getSchema(rs, JdbcDialects.get(ctx.getTargetUrl()), false);
scala.collection.Iterator<Row> it = JdbcUtils.resultSetToRows(rs, st);
Seq<Row> seq = it.toSeq();
RDD<Row> rdd = spark.sparkContext().parallelize(seq, partitionCount, scala.reflect.ClassTag$.MODULE$.apply(Row.class));
Dataset<Row> x = spark.createDataset(rdd, RowEncoder.apply(st));
Row first = x.filter(String.format("name = '%s'", byName)).first();

然后我从执行者那里得到了很多隐秘的错误。

84  WARN 14037 --- [result-getter-0] o.apache.spark.scheduler.TaskSetManager  : Lost task 0.0 in stage 0.0 (TID 0, 192.168.91.89, executor 1): java.lang.ClassCastException: cannot assign instance of org.apache.spark.sql.execution.WholeStageCodegenExec$$anonfun$11 to field org.apache.spark.rdd.RDD$$anonfun$mapPartitionsWithIndex$1$$anonfun$apply$25.cleanedF$2 of type scala.Function2 in instance of org.apache.spark.rdd.RDD$$anonfun$mapPartitionsWithIndex$1$$anonfun$apply$25
    at java.io.ObjectStreamClass$FieldReflector.setObjFieldValues(ObjectStreamClass.java:2287)

org.apache.spark.SparkException: Job aborted due to stage failure: Task 0 in stage 0.0 failed 4 times, most recent failure: Lost task 0.3 in stage 0.0 (TID 3, 192.168.91.89, executor 1): java.lang.ClassCastException: cannot assign instance of org.apache.spark.sql.execution.WholeStageCodegenExec$$anonfun$11 to field org.apache.spark.rdd.RDD$$anonfun$mapPartitionsWithIndex$1$$anonfun$apply$25.cleanedF$2 of type scala.Function2 in instance of org.apache.spark.rdd.RDD$$anonfun$mapPartitionsWithIndex$1$$anonfun$apply$25

我相信这里发生的是在本地模式下,驱动程序线程和执行程序线程都可以访问rs变量。但是,在群集模式下,执行程序线程位于单独的JVM中,并且无法访问rs变量。它仅在调用.first()时失败,因为那是驱动程序从集群请求数据结果,然后尝试评估DAG的时候。

在我看来,代码作者尚未掌握变量的数据局部性(即,执行程序上正在运行的内容以及驱动程序中存在的内容),并且已假设驱动程序进程中的状态/变量/ JVM将在执行程序中可用。

这准确吗?

0 个答案:

没有答案