使用Kafka的Spark Streaming:空集合异常

时间:2017-01-29 19:56:26

标签: scala apache-spark spark-streaming

我正在使用Kafka和Spark Streaming开发算法。这是我接收器的一部分:

val Array(brokers, topics) = args
val sparkConf = new SparkConf().setAppName("Traccia2014")
val ssc = new StreamingContext(sparkConf, Seconds(10))

 // Create direct kafka stream with brokers and topics
val topicsSet = topics.split(",").toSet
val kafkaParams = Map[String, String]("metadata.broker.list" -> brokers)
val messages = KafkaUtils.createDirectStream[String, String, StringDecoder, StringDecoder](ssc, kafkaParams, topicsSet)
val slice=30
val lines = messages.map(_._2)
val dStreamDst=lines.transform(rdd => {
    val y= rdd.map(x => x.split(",")(0)).reduce((a, b) => if (a < b) a else b)
    rdd.map(x => (((x.split(",")(0).toInt - y.toInt).toLong/slice).round*slice+" "+(x.split(",")(2)),1)).reduceByKey(_ + _)
})
dStreamDst.print()

我得到以下错误:

 ERROR JobScheduler: Error generating jobs for time 1484927230000 ms
 java.lang.UnsupportedOperationException: empty collection
    at org.apache.spark.rdd.RDD$$anonfun$reduce$1$$anonfun$apply$42.apply(RDD.scala:1034)
    at org.apache.spark.rdd.RDD$$anonfun$reduce$1$$anonfun$apply$42.apply(RDD.scala:1034)

这意味着什么?我该怎么解决? 真的很感激任何形式的帮助。谢谢你提前

更新 解决了。不要使用transform或print()方法。使用foreachRDD,是最好的解决方案。

1 个答案:

答案 0 :(得分:1)

您正在使用transform()API遇到这个与DStream交互的b / c。使用该方法时,您将获得表示该数据快照的RDD,在您的情况下为10秒窗口。您的代码失败,因为在特定时间窗口,没有数据,并且您正在操作的RDD为空,当您调用reduce()时,会给出“空集合”错误。

使用rdd.isEmpty()确保在调用操作之前RDD不为空。

lines.transform(rdd => {
  if (rdd.isEmpty)
    rdd
  else {
    // rest of transformation
  }
})