Apache spark 如何在启用检查点的情况下连接dstream和JDBCRDD?

Apache spark 如何在启用检查点的情况下连接dstream和JDBCRDD?,apache-spark,spark-streaming,Apache Spark,Spark Streaming,我们有一个启用了检查点的spark流作业,它第一次正确执行,但从检查点重新启动时抛出以下异常 org.apache.spark.SparkException:RDD转换和操作可以 只能由驱动程序调用,不能在其他转换内部调用; 例如,rdd1.map(x=>rdd2.values.count()*x)无效,因为 无法在内部执行值转换和计数操作 在rdd1.map转换中。有关更多信息,请参阅SPARK-5063。 位于org.apache.spark.rdd.rdd.org$apache$spark

我们有一个启用了检查点的spark流作业,它第一次正确执行,但从检查点重新启动时抛出以下异常

org.apache.spark.SparkException:RDD转换和操作可以 只能由驱动程序调用,不能在其他转换内部调用; 例如,rdd1.map(x=>rdd2.values.count()*x)无效,因为 无法在内部执行值转换和计数操作 在rdd1.map转换中。有关更多信息,请参阅SPARK-5063。 位于org.apache.spark.rdd.rdd.org$apache$spark$rdd$rdd$$sc(rdd.scala:87) 位于org.apache.spark.rdd.rdd.withScope(rdd.scala:352) 位于org.apache.spark.rdd.rdd.union(rdd.scala:565) 位于org.apache.spark.streaming.Repo$$anonfun$createContext$1.apply(Repo.scala:23) 位于org.apache.spark.streaming.Repo$$anonfun$createContext$1.apply(Repo.scala:19) 在org.apache.spark.streaming.dstream.dstream$$anonfun$foreachRDD$1$$anonfun$apply$mcV$sp$3.apply(dstream.scala:627)

请建议解决此问题的任何方法。 示例应用程序如下:

String URL = "jdbc:oracle:thin:" + USERNAME + "/" + PWD + "@//" + CONNECTION_STRING;

Map<String, String> options = ImmutableMap.of(
  "driver", "oracle.jdbc.driver.OracleDriver",
  "url", URL,
  "dbtable", "READINGS_10K",
  "fetchSize", "10000");

DataFrame OracleDB_DF = sqlContext.load("jdbc", options);
JavaPairRDD<String, Row> OracleDB_RDD = OracleDB_DF.toJavaRDD()
  .mapToPair(x -> new Tuple2(x.getString(0), x));

Dstream.transformToPair(rdd -> 
  rdd.mapToPair(record -> 
    new Tuple2<>(record.getKey().toString(), record))
    .join(OracleDB_RDD)) // <-- PairRDD.join inside DStream transformation
.print();
String URL=“jdbc:oracle:thin:”+USERNAME+“/”+PWD+“@/”+CONNECTION\u字符串;
映射选项=ImmutableMap.of(
“驱动程序”,“oracle.jdbc.driver.OracleDriver”,
“url”,url,
“dbtable”、“读数_10K”,
“尺寸”、“10000”);
DataFrame OracleDB_DF=sqlContext.load(“jdbc”,选项);
javapairdd OracleDB_RDD=OracleDB_DF.toJavaRDD()
.mapToPair(x->new Tuple2(x.getString(0),x));
数据流。transformToPair(rdd->
rdd.mapToPair(记录->
新元组2(record.getKey().toString(),record))

.join(OracleDB_RDD))/让我从这个问题开始,我相信你一定也在问自己

OracleDB\u RDD有多大

如果它足够小,它可以充当事实表,并可以首先广播。这反过来会使您的解决方案不仅有效而且高效

(这就是为什么现在使用Spark SQL 2.0会使这个问题和类似的问题变得过时,因为这是查询优化器的一种优化)


如果它很大,您必须在
foreach
操作(如中所述)中创建数据帧,或者创建您自己的数据流以返回数据流之间连接的RDD(请参见)。

让我从这个问题开始,我肯定您也已经问过自己了

OracleDB\u RDD有多大

如果它足够小,它可以充当事实表,并可以首先广播。这反过来会使您的解决方案不仅有效,而且高效

(这就是为什么现在使用Spark SQL 2.0会使这个问题和类似的问题变得过时,因为这是查询优化器的一种优化)


如果数据流很大,则必须在
foreach
操作中创建数据帧(如中所述)或创建自己的数据流以返回数据流之间联接的RDD(请参阅).

我已经尝试过使用广播,但没有帮助。我在重新启动时仍会遇到相同的异常。在foreach中读取大型数据库对我来说似乎不是一个解决方案。我已经尝试过使用广播,但没有帮助。我在重新启动时仍会遇到相同的异常。在foreach中读取大型数据库似乎不是一个好办法我的解决方案。