apache-spark - PySpark - 在镶木地板读取后优化分区数
问题描述
year
在一个由和划分的镶木地板数据湖month
中,spark.default.parallelism
设置为 ie 4
,假设我想创建一个 DataFrame ,该数据帧由 2017 年的第 11~12 个月和 2018 年的第 1~3 个月的两个来源A
和B
.
df = spark.read.parquet(
"A.parquet/_YEAR={2017}/_MONTH={11,12}",
"A.parquet/_YEAR={2018}/_MONTH={1,2,3}",
"B.parquet/_YEAR={2017}/_MONTH={11,12}",
"B.parquet/_YEAR={2018}/_MONTH={1,2,3}",
)
如果我得到分区数,spark.default.parallelism
则默认使用 Spark:
df.rdd.getNumPartitions()
Out[4]: 4
考虑到创建后df
我需要在每个时期执行join
和groupBy
操作,并且数据或多或少均匀分布在每个时期(每个时期大约 1000 万行):
问题
- 重新分区会提高我后续操作的性能吗?
- 如果是这样,如果我有 10 个不同的时期(A 和 B 每年 5 个),我是否应该按时期数重新分区并明确引用重新分区(
df.repartition(10,'_MONTH','_YEAR')
)的列?
解决方案
重新分区会提高我后续操作的性能吗?
通常不会。Dataset
抢先对数据进行重新分区的唯一原因是,当基于相同的条件将相同的数据用于多个连接时,避免进一步洗牌
如果是这样,如果我有 10 个不同的时期(A 和 B 每年 5 个),我是否应该按时期数重新分区并明确引用要重新分区的列 (df.repartition(10,'_MONTH','_YEAR') )?
让我们一步一步来:
我应该按周期数重新分区吗
从业者不保证级别和分区之间的 1:1 关系,所以唯一要记住的是,您不能拥有比唯一键更多的非空分区,因此使用显着更大的值没有意义。
并明确引用要重新分区的列
如果您
repartition
随后join
或groupBy
对这两个部分使用相同的列集是唯一明智的解决方案。
概括
repartitoning
before join 在两种情况下有意义:
如果有多个后续
joins
df_ = df.repartition(10, "foo", "bar") df_.join(df1, ["foo", "bar"]) ... df_.join(df2, ["foo", "bar"])
当所需的输出分区数量不同时使用单连接
spark.sql.shuffle.partitions
(并且没有广播连接)spark.conf.get("spark.sql.shuffle.partitions") # 200 spark.conf.set("spark.sql.autoBroadcastJoinThreshold", -1) df1_ = df1.repartition(11, "foo", "bar") df2_ = df2.repartition(11, "foo", "bar") df1_.join(df2_, ["foo", "bar"]).rdd.getNumPartitions() # 11 df1.join(df2, ["foo", "bar"]).rdd.getNumPartitions() # 200
这可能比:
spark.conf.set("spark.sql.shuffle.partitions", 11) df1.join(df2, ["foo", "bar"]).rdd.getNumPartitions() spark.conf.set("spark.sql.shuffle.partitions", 200)
推荐阅读
- php - 为大量多个连接创建连接类的最佳方法
- .net - Concat 在 OnGetAsync Razor 页面中不起作用
- php - 为什么我的 MySQL 查询只在脚本的一部分上失败?
- shiny - 网络掉线不会导致 session$onSessionEnded 触发
- android - onScrollBeginDrag 在 Android 上可用吗?
- java - BEEWARE:任务“:transformClassesWithDexBuilderForDebug”执行失败
- html - 滑块没有响应并在其下方的部分中创建额外的高度
- python - Python-Selenium 爬虫冻结,尤其是在无头模式下(不可重现的错误)
- java - 如何修复:我的 Web 应用程序强制所有用户与同一个列表“交互”,而不是为每个用户提供自己的列表
- node.js - 通过 http put 请求访问对象中的数据