我很确定没有简单的方法可以做到这一点,但这是我的用例:
我有一个Spark Streaming作业(版本2.1.0),每个微批次的持续时间为5秒。
我的目标是在每个微分钟间隔消耗来自1个不同主题的数据,总共250个Kafka主题。您可以将下面的代码作为一个简单示例:
val groupId:String = "first_group"
val kafka_servers:String = "datanode1:9092,datanode2:9092,datanode3:9092"
val ss:SparkSession = SparkSession.builder().config("spark.streaming.unpersist","true").appName("ConsumerStream_test").getOrCreate()
val ssc:StreamingContext= new StreamingContext(ss.sparkContext,Duration(5000))
val kafka_parameters:Map[String,Object]=Map(
"bootstrap.servers" -> kafka_servers,
"key.deserializer" -> classOf[StringDeserializer],
"value.deserializer" -> classOf[ByteArrayDeserializer],
"heartbeat.interval.ms" -> (1000:Integer),
"max.poll.interval.ms" -> (100:Integer),
"enable.auto.commit" -> (false: java.lang.Boolean),
"autoOffsetReset" -> OffsetResetStrategy.EARLIEST,
//"connections.max.idle.ms" -> (5000:Integer),
"group.id" -> groupId
)
val r = scala.util.Random
val kafka_list_one_topic=List("topic_"+ r.nextInt(250))
val consumer:DStream[ConsumerRecord[String,Array[Byte]]] = KafkaUtils.createDirectStream(ssc, LocationStrategies.PreferBrokers, ConsumerStrategies.
Subscribe[String, Array[Byte]](kafka_list_one_topic , kafka_parameters))
consumer.foreachRDD( eachRDD => {
// DOING SOMETHING WITH THE DATA...
})
ssc.start()
ssc.awaitTermination()
但是这种方法的问题在于Spark只会运行初始代码(foreachRDD命令之前的所有内容)一次,以便创建Kafka消费者DStream,但是在下面的微批处理中,它只运行&# 34; foreachRDD"言。
作为一个例子,让我们说r.nextInt(250)返回40. Spark Streaming作业将连接到topic_40并处理其数据。但是在下一个微批次中,它仍将连接到topic_40,并忽略foreachRDD语句之前的所有命令。
我想这是预期的,因为foreachRDD语句之前的代码只在Spark驱动程序上运行。
我的问题是,有没有办法我可以做到这一点,而不必每5秒重新启动一个Spark应用程序?
谢谢。
答案 0 :(得分:0)
我的方法非常简单,如果你想让它真正随机并且不关心任何其他后果,可以将kafka_list_one_topic作为一个可变变量并在流代码中进行更改。
val r = scala.util.Random
var kafka_list_one_topic=List("topic_"+ r.nextInt(250))
val consumer:DStream[ConsumerRecord[String,Array[Byte]]] =
KafkaUtils.createDirectStream(ssc, LocationStrategies.PreferBrokers,
ConsumerStrategies.
Subscribe[String, Array[Byte]](kafka_list_one_topic , kafka_parameters))
consumer.foreachRDD( eachRDD => {
// DOING SOMETHING WITH THE DATA...
kafka_list_one_topic=List("topic_"+ r.nextInt(250))
})
ssc.start()
ssc.awaitTermination()