我正在接收时间序列数据,并希望仅根据特定键保留/插入我们获得的最新条目。我们过去常常使用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个更多的分区。我一直在本地运行它,并试图找出它,但没有什么能让我得到合理的处理时间。
答案 0 :(得分:1)
我在一个小型集群上与Spark有类似的经历,在RDD中有大约2000个项目。重新划分到许多不同的分区计数没有任何区别。一旦我运行了更多项目(大约4000但我认为这取决于你拥有的执行程序的数量),它开始按预期运行。尝试使用更多数据点运行它。