使用Spark StreamingContext从Kafka主题消费

时间:2016-08-10 13:52:21

标签: scala apache-spark apache-kafka spark-streaming

我是Spark& S的新手。 Kafka和我试图获得一些Scala代码(作为Spark工作运行)作为一个长期运行的进程(不仅仅是一个短期/计划任务),并不断轮询Kafka代理消息。当它收到消息时,我只想将它们打印到控制台/ STDOUT。同样,这需要一个长期运行的过程,并且基本上(尝试)永远存在。

在做了一些挖掘之后,好像我想要使用StreamingContext。这是我最好的尝试:

import org.apache.spark._
import org.apache.spark.sql._
import org.apache.spark.storage._
import org.apache.spark.streaming.{StreamingContext, Seconds, Minutes, Time}
import org.apache.spark.streaming.dstream._
import org.apache.spark.streaming.kafka._
import kafka.serializer.StringDecoder

def createKafkaStream(ssc: StreamingContext, kafkaTopics: String, brokers: String): DStream[(String, String)] = {
    val topicsSet = kafkaTopics.split(",").toSet
    val props = Map(
        "bootstrap.servers" -> "my-kafka.example.com:9092",
        "metadata.broker.list" -> "my-kafka.example.com:9092",
        "serializer.class" -> "kafka.serializer.StringEncoder",
        "value.serializer" -> "org.apache.kafka.common.serialization.StringSerializer",
        "value.deserializer" -> "org.apache.kafka.common.serialization.StringDeserializer",
        "key.serializer" -> "org.apache.kafka.common.serialization.StringSerializer",
        "key.deserializer" -> "org.apache.kafka.common.serialization.StringDeserializer"
    )
    KafkaUtils.createDirectStream[String, String, StringDecoder, StringDecoder](ssc, props, topicsSet)
}

def processEngine(): StreamingContext = {
    val ssc = new StreamingContext(sc, Seconds(1))

    val topicStream = createKafkaStream(ssc, "mytopic", "my-kafka.example.com:9092").print()

    ssc
}

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

val ssc1 = StreamingContext.getActiveOrCreate(processEngine)
ssc1.start()
ssc1.awaitTermination()

当我运行它时,我没有异常/错误,但似乎没有任何事情发生。我可以确认有关于该主题的消息。关于我出错的地方有任何想法吗?

2 个答案:

答案 0 :(得分:3)

当您foreachRDD时,输出将打印在工作节点中,而不是 Master 。我假设你正在看Master的控制台输出。您可以改为使用DStream.print

val ssc = new StreamingContext(sc, Seconds(1))
val topicStream = createKafkaStream(ssc, "mytopic", "my-kafka.example.com:9092").print()

此外,请不要忘记在ssc.awaitTermination()之后致电ssc.start()

ssc.start()
ssc.awaitTermination()

作为旁注,我假设您复制粘贴此示例,但如果您实际上没有计划对{{1}执行任何操作,则无需在transform上使用DStream }}

答案 1 :(得分:1)

这是您的完整代码吗?你在哪里创建sc?你必须在流式传输上下文之前创建spark上下文。你可以像这样创建sc:

endpoints.flyway.enabled=false

此外,如果没有SparkConf sc = new SparkConf().setAppName("SparkConsumer"); ,则很难捕获并打印在后台数据处理期间发生的异常。您可以在最后添加awaitTermination,看看是否有任何错误。