Spark Streaming:如何为DStream添加更多分区?

时间:2016-02-05 03:53:45

标签: apache-spark yarn partitioning spark-streaming spark-dataframe

我有一个火花流媒体应用程序,如下所示:

val message = KafkaUtils.createStream(...).map(_._2)

message.foreachRDD( rdd => {

  if (!rdd.isEmpty){
    val kafkaDF = sqlContext.read.json(rdd)

    kafkaDF.foreachPartition(
      i =>{
        createConnection()
        i.foreach(
          row =>{
            connection.sendToTable()
          }
        )
        closeConnection()
      }
    )

并且,我使用

在纱线群集上运行它
spark-submit --master yarn-cluster --num-executors 3 --driver-memory 2g --executor-memory 2g --executor-cores 5....

当我尝试记录kafkaDF.rdd.partitions.size时,结果大多为“1”或“5”。我很困惑,是否可以控制我的DataFrame的分区数量? KafkaUtils.createStream似乎不接受任何与我想要的rdd分区数相关的参数。我试过了kafkaDF.rdd.repartition( int ),但它似乎也没有用。

如何在代码中实现更多并行性?如果我的方法是错误的,那么实现它的正确方法是什么?

1 个答案:

答案 0 :(得分:5)

在Spark Streaming中,可以在两个方面实现并行性:(a)消费者/接收者(在您的情况下是Kafka消费者),以及(b)处理(由Spark完成)。

默认情况下,spark streaming会为每个消费者分配一个核心(也就是Thread)。因此,如果您需要获取更多数据,则需要创建更多消费者。每个消费者都将创建一个DStream。然后,您可以将DStream联合以获取一个大流。

// A basic example with two threads for consumers
val messageStream1 = KafkaUtils.createStream(...) // say, reading topic A
val messageStream2 = KafkaUtils.createStream(...) // and this one reading topic B

val combineStream = messageStream1.union(messageStream2)

Alternatively,通过重新分区输入流可以增加接收者/消费者的数量:

inputStream.repartition(<number of partitions>))

流式应用程序可用的所有剩余核心都将分配给Spark。

因此,如果您拥有N个核心(通过spark.cores.max定义),并且您拥有C个消费者,那么您可以使用N-C核心。

#Partitions =~  #Consumers x (batch duration / block interval)

阻止间隔 =消费者在将其创建的数据作为火花块(定义为配置spark.streaming.blockInterval)推送之前等待的时间。

请记住,Spark Streaming有两个不断发生的功能。一组读取当前微批(消费者)的线程,以及一组处理前一个微批(Spark)的线程。

有关更多性能调整提示,请参阅hereherehere