【发布时间】:2021-11-15 06:25:46
【问题描述】:
我正在尝试将 Spark 用于一个非常简单的用例:给定大量文件 (90k),其中包含数百万台设备的设备时间序列数据,将给定设备的所有时间序列读取分组为一个一组文件(分区)。现在假设我们的目标是 100 个分区,给定的设备数据显示在同一个输出文件中并不重要,只是同一个分区。
鉴于此问题,我们提出了两种方法来解决此问题 - repartition 然后 write 或 write 将 partitionBy 应用于 Writer。其中任何一个的代码都非常简单:
repartition(添加了哈希列以确保与下面的partitionBy代码的比较是一对一的):
df = spark.read.format("xml") \
.options(rowTag="DeviceData") \
.load(file_path, schema=meter_data) \
.withColumn("partition", hash(col("_DeviceName")).cast("Long") % num_partitions) \
.repartition("partition") \
.write.format("json") \
.option("codec", "org.apache.hadoop.io.compress.GzipCodec") \
.mode("overwrite") \
.save(output_path)
partitionBy:
df = spark.read.format("xml") \
.options(rowTag="DeviceData") \
.load(file_path, schema=meter_data) \
.withColumn("partition", hash(col("_DeviceName")).cast("Long") % num_partitions) \
.write.format("json") \
.partitionBy(“partition”) \
.option("codec", "org.apache.hadoop.io.compress.GzipCodec") \
.mode("overwrite") \
.save(output_path)
在我们的测试中,repartition 比 partitionBy 快 10 倍。这是为什么呢?
根据我的理解,repartition 会引发洗牌,我的 Spark 学习告诉我要尽可能避免这种洗牌。另一方面,partitionBy(根据我的理解)只对每个节点进行本地排序操作 - 不需要随机播放。我是否误解了某些东西,让我认为partitionBy 会更快?
【问题讨论】:
标签: apache-spark pyspark apache-spark-sql apache-spark-xml