如何在启用检查点的情况下加入dstream和JDBCRDD?

时间:2016-11-04 09:53:37

标签: apache-spark spark-streaming

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

  

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();

Spark版本1.6,以纱线群集模式运行。

1 个答案:

答案 0 :(得分:0)

让我先从问题开始,我确定你一定也在问自己。

  

OracleDB_RDD有多大?

如果它足够小,它可以作为事实表,可以先播放。这反过来会使您的解决方案不仅有效而且有效。

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

如果它很大,则必须在foreach操作中创建DataFrame(如DataFrame and SQL Operations中所述,或者创建自己的DStream以返回DStream之间的连接的RDD(请参阅{ {3}})。