Scala 《星火》卡夫卡主题系列消费

Scala 《星火》卡夫卡主题系列消费,scala,apache-spark,apache-kafka,spark-streaming,Scala,Apache Spark,Apache Kafka,Spark Streaming,给定以下代码: def createKafkaStream(ssc: StreamingContext, kafkaTopics: String, brokers: String): DStream[(String, String)] = { // some configs here KafkaUtils.createDirectStream[String, String, StringDecoder, StringD

给定以下代码:

def createKafkaStream(ssc: StreamingContext, 
                      kafkaTopics: String, brokers: String): DStream[(String, String)] = {
    // some configs here
    KafkaUtils.createDirectStream[String, String, StringDecoder,
        StringDecoder](ssc, props, topicsSet)
}

def consumerHandler(): StreamingContext = {
    val ssc = new StreamingContext(sc, Seconds(10))

    createKafkaStream(ssc, "someTopic", "my-kafka-ip:9092").foreachRDD(rdd => {
        rdd.foreach { msg =>
            // Now do some DataFrame-intensive work.
            // As I understand things, DataFrame ops must be run
            // on Workers as well as streaming consumers.
        }
    })

    ssc
}

StreamingContext.getActive.foreach {
    _.stop(stopSparkContext = false)
}

val ssc = StreamingContext.getActiveOrCreate(consumerHandler)
ssc.start()
ssc.awaitTermination()
我的理解是Spark和Kafka将自动协同工作,以确定要部署到可用工作节点的用户线程数量,这可能导致并行处理Kafka主题之外的消息

但是如果我不想要多个并行的消费者呢?如果想要一个且只有一个消费者阅读某个主题的下一条消息,完全处理它,然后重新开始并轮询下一条消息,该怎么办

另外,当我打电话时:

val ssc = new StreamingContext(sc, Seconds(10))
这是否意味着:

  • 单个消费者线程将接收在过去10秒内发布到主题的所有消息
  • 单个消费者线程将接收来自主题的下一条(单个)消息,并且每10秒轮询一次下一条消息
但是如果我不想要多个并行的消费者呢?如果你想要呢 只有一名消费者阅读某个主题的下一条消息, 完全处理它,然后重新开始 轮询下一条消息

如果这是您的用例,我会说为什么要使用Spark?它的全部优点是你可以并行阅读。我所能想到的唯一的黑客解决方法是用一个分区创建一个卡夫卡主题,这会使Spark将整个偏移范围分配给一个工作者,但这很难看

这是否意味着单个使用者线程将接收所有已发送的消息 在最后10秒钟内发布到主题或单个 消费者线程将从主题接收下一条(单个)消息, 它会每10秒轮询一次下一条消息吗


都不是。由于您使用的是直接(无接收器)流方法,这意味着每10秒,您的驱动程序将要求Kafka为所述主题的每个分区提供自上一批更改后的偏移范围。然后,Spark将获取每个这样的偏移范围,并将其发送给其中一个工人,直接从卡夫卡消费。这意味着使用直接流方法,Kafka分区和Spark分区之间有1:1的对应关系。

感谢您的反馈,您说了几句话:“对于初学者来说,您展示的伪代码无法生成有效的Spark应用程序(您无法在操作内执行数据帧密集型工作)。”(1)你说不能执行是什么意思?我一直在运行调用数据帧操作的操作,所以你是说我不应该这样做吗?或者你的意思是说,我已经做了几个星期了,现在真的不可能这么做吗?!?