Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.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流媒体作业中使用不同的卡夫卡主题?_Scala_Apache Spark_Apache Kafka_Spark Streaming - Fatal编程技术网

Scala 如何在每批Spark流媒体作业中使用不同的卡夫卡主题?

Scala 如何在每批Spark流媒体作业中使用不同的卡夫卡主题?,scala,apache-spark,apache-kafka,spark-streaming,Scala,Apache Spark,Apache Kafka,Spark Streaming,我很确定没有简单的方法可以做到这一点,但下面是我的用例: 我有一个Spark流作业(版本2.1.0),每个微批次的持续时间为5秒 我的目标是,在每一个微博客时间间隔内使用来自1个不同主题的数据,总共250个卡夫卡主题。您可以将下面的代码作为一个简单的示例: val groupId:String = "first_group" val kafka_servers:String = "datanode1:9092,datanode2:9092,datanode3:9092" val ss:

我很确定没有简单的方法可以做到这一点,但下面是我的用例:

我有一个Spark流作业(版本2.1.0),每个微批次的持续时间为5秒

我的目标是,在每一个微博客时间间隔内使用来自1个不同主题的数据,总共250个卡夫卡主题。您可以将下面的代码作为一个简单的示例:

 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 consumer数据流,但在下面的微批处理中,它只运行“foreachRDD”语句

例如,假设r.nextInt(250)返回40。Spark Streaming作业将连接到主题_40并处理其数据。但在接下来的微批处理中,它仍将连接到topic40,并忽略foreachRDD语句之前的所有命令

我想这是意料之中的,因为foreachRDD语句之前的代码只在Spark驱动程序上运行

我的问题是,有没有一种方法可以做到这一点,而不必每5秒重新启动一次Spark应用程序


多谢各位

我的方法非常简单,如果您希望它是真正随机的,并且不关心任何其他后果,请将kafka_列表作为一个可变变量,并在流式代码中更改它

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()

你不能创建一个所有主题的列表并使用数据吗?@ShankarKoirala,如果我有5到10个主题可以使用,那么这种方法就可以了。但是对于250,连接到Kafka代理需要很长时间,主要是因为到每个主题的连接不是并行的,而是顺序的(您可以在这里找到更多信息)@ShankarKoirala每个主题都有一个分区,并从不同的数据源接收数据。出于组织和可伸缩性的目的,以这种方式保持数据分离是一种常见做法。我想知道您为什么要这样做?您试图在这里实现的设计模式是什么?@RobinMoffatt,下面是一个用例:我有250个数据源,每个数据源都通过卡夫卡制作人向卡夫卡主题发送数据。然后,Spark流媒体作业每5秒消耗一次这些主题的数据来处理这些数据。然而,并不是所有的主题在给定的微批次中都有新数据。因此,基于主题偏移量,我决定在该微批处理中应该连接到哪些主题。我之所以这么做,是因为试图同时连接所有250个卡夫卡主题花费的时间太长,我需要完成处理时间。谢谢你的回答。不幸的是,正如我上面所说的,随机部分纯粹是一个示例,表明主题名称随每次迭代而变化。此外,消费者仍然只会使用kafka_list_one的第一个值连接到主题,而不会连接到另一个,独立于val或var