RDD 元素格式為 (時段, 分數, 次數),需計算每個時段的平均分數 = 總分數 / 總次數。
// 假設原始 RDD: rdd[(String, Double, Long)]
val pairRDD = rdd.map { case (period, score, count) => (period, (score, count)) }
// 使用 aggregateByKey 進行分組聚合
// 零值: (0.0, 0L) 代表 (總分數, 總次數)
// seqOp: 在分區內累加 (sumScore, sumCount)
// combOp: 跨分區合併
val aggregated = pairRDD.aggregateByKey((0.0, 0L))(
(acc, v) => (acc._1 + v._1, acc._2 + v._2), // seqOp
(acc1, acc2) => (acc1._1 + acc2._1, acc1._2 + acc2._2) // combOp
)
// 計算平均
val averages = aggregated.mapValues { case (sumScore, sumCount) => sumScore / sumCount }
| 方案 | Shuffle 次數 | 程式碼複雜度 | 適用場景 |
|---|---|---|---|
| aggregateByKey(推薦) | 1 | 低 | 大多數聚合統計 |
| groupByKey + mapValues | 1 | 中 | 需保留原始值列表時 |
| 雙 RDD 分別 reduceByKey 再 join | 2 | 高 | 極罕見,不推薦 |
salting 或自訂 Partitioner。collect() 回 Driver,大結果應寫入分散式儲存。