Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala Spark Streaming 1.6+;卡夫卡:太多的批次;排队;地位_Scala_Apache Kafka_Spark Streaming_Apache Spark 1.6 - Fatal编程技术网

Scala Spark Streaming 1.6+;卡夫卡:太多的批次;排队;地位

Scala Spark Streaming 1.6+;卡夫卡:太多的批次;排队;地位,scala,apache-kafka,spark-streaming,apache-spark-1.6,Scala,Apache Kafka,Spark Streaming,Apache Spark 1.6,我使用spark streaming来消费来自Kafka主题的消息,该主题有10个分区。我使用直接方法从卡夫卡消费,代码如下所示: def createStreamingContext(conf: Conf): StreamingContext = { val dateFormat = conf.dateFormat.apply val hiveTable = conf.tableName.apply val sparkConf = new SparkConf()

我使用spark streaming来消费来自Kafka主题的消息,该主题有10个分区。我使用直接方法从卡夫卡消费,代码如下所示:

def createStreamingContext(conf: Conf): StreamingContext = {
    val dateFormat = conf.dateFormat.apply
    val hiveTable = conf.tableName.apply

    val sparkConf = new SparkConf()

    sparkConf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
    sparkConf.set("spark.driver.allowMultipleContexts", "true")

    val sc = SparkContextBuilder.build(Some(sparkConf))
    val ssc = new StreamingContext(sc, Seconds(conf.batchInterval.apply))

    val kafkaParams = Map[String, String](
      "bootstrap.servers" -> conf.kafkaBrokers.apply,
      "key.deserializer" -> classOf[StringDeserializer].getName,
      "value.deserializer" -> classOf[StringDeserializer].getName,
      "auto.offset.reset" -> "smallest",
      "enable.auto.commit" -> "false"
    )

    val directKafkaStream = KafkaUtils.createDirectStream[String, String, StringDecoder, StringDecoder](
      ssc,
      kafkaParams,
      conf.topics.apply().split(",").toSet[String]
    )

    val windowedKafkaStream = directKafkaStream.window(Seconds(conf.windowDuration.apply))
    ssc.checkpoint(conf.sparkCheckpointDir.apply)

    val eirRDD: DStream[Row] = windowedKafkaStream.map { kv =>
      val fields: Array[String] = kv._2.split(",")
      createDomainObject(fields, dateFormat)
    }

    eirRDD.foreachRDD { rdd =>
      val schema = SchemaBuilder.build()
      val sqlContext: HiveContext = HiveSQLContext.getInstance(Some(rdd.context))
      val eirDF: DataFrame = sqlContext.createDataFrame(rdd, schema)

      eirDF
        .select(schema.map(c => col(c.name)): _*)
        .write
        .mode(SaveMode.Append)
        .partitionBy("year", "month", "day")
        .insertInto(hiveTable)
    }
    ssc
  }
从代码中可以看出,我使用window实现了这一点(,如果我错了,请纠正我:):因为有一个操作要插入到配置单元表中,所以我希望避免过于频繁地写入HDFS,所以我想要的是在内存中保存足够的数据,然后才写入文件系统。我认为使用window将是实现它的正确方法

现在,在下图中,您可以看到有许多批正在排队,正在处理的批需要很长时间才能完成

我还提供了正在处理的单个批次的详细信息:

当批处理中没有太多事件时,为什么插入操作有这么多任务?有时,拥有0个事件也会产生数千个任务,这些任务需要花费很长时间才能完成

我用Spark处理微博客的方式是错误的吗

谢谢你的帮助

一些额外的细节:

纱线容器的最大容量为2gb。 在此纱线队列中,容器的最大数量为10个。
当我查看执行此spark应用程序的队列的详细信息时,容器的数量非常大,大约有15k个挂起的容器。

我终于找到了答案。显然,Spark Streaming无法处理空事件,因此在代码的foreachRDD部分中,我添加了以下内容:

eirRDD.foreachRDD { rdd =>
      if (rdd.take(1).length != 0) {
        //do action
      }
}
这样我们就跳过了空的微批次。isEmpty()方法不起作用

希望这对其他人有帮助!;)