当前位置: 首页 > news >正文

spark性能优化2:Window操作和groupBy操作的区别

GroupBy操作

什么时候触发shuffle

# 以下操作都会触发shuffle
df.groupBy("column").count()
df.groupBy("column").sum("value")
df.groupBy("column").agg(F.sum("value"), F.avg("value"))

为什么触发shuffle

因为groupBy需要将具有相同key的数据重新分布到同一个分区中进行聚合计算。

Window操作

什么时候不触发shuffle

pythonfrom pyspark.sql.window import Window# 如果数据已经按partitionBy的列进行了分区,则不会触发shuffle
window1 = Window.partitionBy("segment_id")
df.withColumn("count", F.count("*").over(window1))# 即使添加排序也不会触发shuffle(只要数据已经按partitionBy列分区)
window2 = Window.partitionBy("segment_id").orderBy("event_time")
df.withColumn("rank", F.row_number().over(window2))

什么时候会触发shuffle

Window操作本身不会触发shuffle,但如果数据没有按照 partitionB y 的列进行预先分区,则在执行Window操作前可能需要进行shuffle来重新组织数据。

Window操作和GroupBy操作有什么区别

我在使用这两种操作时出现了混淆,下面来看下它们之间的区别

核心区别

  1. Window操作
    Window操作是一种逐行计算的操作,它不会改变数据的行数,只是为每一行添加新的计算列。
  2. GroupBy操作
    GroupBy操作是一种聚合操作,它会将多行数据聚合成一行,减少数据的行数。
    举个具体例子

假设我们有以下数据:

segment_id	value
A	10
A	20
B	30
B	40

使用Window操作:

pythonwindow_spec = Window.partitionBy("segment_id")
df.withColumn("sum_value", F.sum("value").over(window_spec))

结果:

segment_id	value	sum_value
A	10	30
A	20	30
B	30	70
B	40	70

使用GroupBy操作:

pythondf.groupBy("segment_id").sum("value")

结果:

segment_id	sum(value)
A	30
B	70

Window版本 (优化后):

def segment_count_over_100(df):"""保留分段条数大于100的数据"""# 使用Window函数避免shuffle操作window_spec = Window.partitionBy("segment_id")df_with_count = df.withColumn("segment_count", F.count("*").over(window_spec)) \.filter(F.col("segment_count") > 100) \.drop("segment_count")return df_with_count

这个操作:

  1. 为每一行添加一个 segment_ count 列,表示该segment_id的总记录数
  2. 然后过滤掉记录数小于100的行
  3. 最后删除临时列 segment_count
  4. 行数可能会减少,但不是通过聚合,而是通过过滤

GroupBy版本 (原始):

def segment_count_over_100(df):"""保留分段条数大于100的数据"""# 统计segment的数据的条数,保留大于100条数的数据count_df = df.groupBy("segment_id").count().filter(F.col("count") > 100)df = df.join(count_df, "segment_id").drop("count")return df

这个操作:

  1. 先对数据进行聚合,得到每个segment_id的记录数
  2. 过滤掉记录数小于100的segment_id
  3. 将结果与原始数据进行join操作
  4. 行数可能会减少,通过聚合和连接实现

Shuffle情况分析

  • Window版本:

    • 不触发shuffle(假设数据已经按segment_id分区)
    • 在每个分区内独立计算
  • GroupBy版本:

    • 触发shuffle(需要将相同segment_id的数据发送到同一节点)
    • 然后再触发一次shuffle(join操作需要将数据重新分布)

为什么结果相同但性能不同

虽然两种方法最终得到的数据是相同的,但它们的执行过程完全不同:

  1. Window版本:

    • 保持原有数据行数
    • 通过窗口函数计算每个分组的统计信息
    • 通过过滤操作移除不需要的行
    • 只在必要时触发shuffle
  2. GroupBy版本:

    • 先聚合减少行数
    • 再通过join操作恢复详细数据
    • 多次触发shuffle

使用Window函数的版本更加高效,因为它:

  1. 避免了多次shuffle操作
  2. 保持了数据的局部性
  3. 减少了网络传输开销
  4. 实现了相同的业务逻辑

这就是为什么我们推荐使用Window函数替代GroupBy + Join的原因

http://www.dtcms.com/a/581309.html

相关文章:

  • 用spark-md5实现切片上传前端起node模拟上传文件大小,消耗时间
  • 做网站优化竞价区别开发工具的种类及使用方法
  • Mac安装pnpm步骤以及会出现的问题
  • ofd在线预览js+springboot跳转
  • 基于SpringBoot实习管理系统的设计与实现的设计与实现
  • abuild的使用说明-如何使用vscode进行c/c++开发
  • 宝山php网站开发培训可以看那种东西的手机浏览器
  • 算法28.0
  • Spring Cloud中的@LoadBalanced注解实现原理
  • 建站快车的使用方法电子商务网站对比分析
  • 分布式Web应用场景下存在的Session问题
  • 12.线程(一)
  • 如何做二维码跳转到网站建设网站专家
  • 前端i18n实现中英文切换
  • Java基础——常用算法4
  • SQL50+Hot100系列(11.7)
  • Python 第二十六节 多线程应用详细介绍及使用注意事项
  • 网站建设交接表wordpress编程视频教程
  • LeafView(轻量级电脑图片查看器) v3.8.1 中文绿色便携版
  • MySQL死锁问题分析与解决方案
  • shell中获取达梦信息方法示例
  • calibre QRC提取寄生参数
  • 【Hot100 |5-LeetCode 11. 盛最多水的容器】
  • 【MicroPython编程-ESP32篇】-DH11温度湿度传感器驱动
  • 字节deer-flow项目模块详解
  • 【Python】Python并发与并行编程图解
  • 清城网站seodiscuz自适应模板
  • 优秀网页设计网站是wordpress php开发
  • 内部网关协议——OSPF 协议(开放最短路径优先)(链路状态路由协议)
  • rman-08137:warning:archived log not deleted