Spark Streaming动态分配ExecutorAllocationManager

时间:2017-03-13 19:42:32

标签: apache-spark spark-streaming

我们有一个带有mapWithState的spark 2.1流应用程序,启用spark.streaming.dynamicAllocation.enabled=true。管道如下:

var rdd_out = ssc.textFileStream()
    .map(convertToEvent(_))
    .combineByKey(...., new HashPartitioner(partitions))
    .mapWithState(stateSpec)
    .map(s => sessionAnalysis(s))
    .foreachRDD( rdd => rdd.toDF().....save(output));

流应用程序以2个执行程序启动,一段时间后它会创建新的执行程序,因为负载会按预期增加。问题是那些执行者不共享负载。

分区的数量足以扩散到新的执行器,并且密钥是均匀分布的,我设置了40多个分区,但我只能看到8个分区(2个执行器x每个4个核心) mapWithState存储空间。我期待在分配新的执行程序时,将这8个分区拆分并分配给新的分区,但这种情况永远不会发生。

请告知。

谢谢,

1 个答案:

答案 0 :(得分:0)

显然答案是盯着我的脸:)。根据下面的文档,RDD应该继承上游分区。

   * Otherwise, we use a default HashPartitioner. For the number of partitions, if
   * spark.default.parallelism is set, then we'll use the value from SparkContext
   * defaultParallelism, otherwise we'll use the max number of upstream partitions.

mapWithState中的状态没有上游RDD。因此,除非您直接在状态中指定分区,否则将设置为默认并行度,如下面的示例所示。

val stateSpec = StateSpec.function(crediting.formSession _)
        .timeout(timeout)
        .numPartitions(partitions)  // <----------

var rdd_out = ssc.textFileStream()
    .map(convertToEvent(_))
    .combineByKey(...., new HashPartitioner(partitions))
    .mapWithState(stateSpec)
    .map(s => sessionAnalysis(s))
    .foreachRDD( rdd => rdd.toDF().....save(output));

仍然需要弄清楚如何使动态分配动态分区,这应该在运行时更改。