reduceByKey的numPartitions不影响速度

时间:2016-08-16 14:32:25

标签: scala apache-spark mapreduce spark-streaming

我正在接收时间序列数据,并希望仅根据特定键保留/插入我们获得的最新条目。我们过去常常使用mapWithState进行聚合,我们能够在qa环境下以大约6k / sec的速率在本地处理大约1k / sec,在我们最强大的环境中大约45k / sec。

我删除了很多代码,因为我们有一些需求更改,我认为我看到这种缓慢行为的原因是因为reduceByKey这里有少量代码:

rawStream
    .map(timeSeries => (timeSeries.key, AggregationEngine.createSingleItemAggregate(timeSeries)))
    // Select the last value for the key
    .reduceByKey((accumulator: AggregationResult, aggregationResult: AggregationResult) => {
        if (accumulator.firstTimeMillis > aggregationResult.firstTimeMillis) {
            accumulator
        } else {
            aggregationResult
        }
    }, numPartitions = numberOfReduceTasks)
    // Send back table name and aggregate
    .map(aggResultPair => (aggResultPair._2.tableName, aggResultPair._2) )

在本地处理500个数据点大约需要3-5分钟,而在我们的qa环境中,小批量处理的速度相当慢。我知道应该放慢速度,因为在一切都是一个阶段之前,现在因为改组,它分为两个阶段,而且洗牌需要很长时间。我应该使用理想的numPartitions值吗?也许每个核心应该添加X分区,或者每个内存你应该添加X个更多的分区。我一直在本地运行它,并试图找出它,但没有什么能让我得到合理的处理时间。

1 个答案:

答案 0 :(得分:1)

我在一个小型集群上与Spark有类似的经历,在RDD中有大约2000个项目。重新划分到许多不同的分区计数没有任何区别。一旦我运行了更多项目(大约4000但我认为这取决于你拥有的执行程序的数量),它开始按预期运行。尝试使用更多数据点运行它。