请说明在 PySpark 中,reduceByKey() 与 groupByKey() 这两种转换操作的核心差异是什么?
考察说明
考查对 PySpark 中键值对转换操作的原理理解,特别是 shuffle 和数据传输的差异。
回答思路
- 【回答框架 1】reduceByKey() 会在每个分区内先进行局部合并,再对分区结果进行全局合并,因此传输到下游的数据量较少,能显著减少 shuffle 开销。
- 【回答框架 2】groupByKey() 不进行任何本地合并,它会把每个键的所有值原封不动地发送到下游,导致大量数据在网络中传输,性能较差,尤其是当键对应的值较多时。
- 【回答框架 3】因此,在需要按键进行聚合(如求和、计数)时,应优先使用 reduceByKey(),因为它结合了 map-side 预聚合,效率更高。而 groupByKey() 通常只在需要获取所有值的列表,且无法用更高效的聚合操作替代时使用。
- 【关键点 1】reduceByKey() 有预聚合,groupByKey() 无预聚合。
- 【关键点 2】reduceByKey() 传输数据量小,性能更优。
- 【关键点 3】groupByKey() 仅适用于需要保留全部值且无法用聚合函数替代的场景。
- 【易错点 1】不要混淆 groupByKey() 与 reduceByKey() 在结果形态上的差异,前者返回 (K, Iterable<V>),后者返回 (K, V)。
- 【易错点 2】即使使用 groupByKey() 后进行 mapValues 等操作,也无法弥补其无预聚合带来的性能劣势。
- 【易错点 3】在 PySpark 中,reduceByKey() 要求传入的函数满足交换律和结合律,确保结果确定性。