Scala 用于databricks可扩展集群的Spark重新分区逻辑
Databricks spark cluster可根据负载进行更换 我正在spark中读取gzip文件,并对rdd进行重新分区,以获得并行性,因为gzip文件将在单核上读取并生成 根据理想的分区数是集群中我可以在重新分区期间设置的核心数,但是在自动缩放集群的情况下,这个数字将根据集群的状态和其中有多少执行器而变化 那么,对于一个可自动伸缩的spark集群,分区逻辑应该是什么呢 编辑1: 文件夹不断增长,gzip文件定期出现在其中,gzip文件大小约为10GB,未压缩大小约为150GB。我知道多个文件可以并行读取。但对于单个超大文件,databricks可能会尝试自动扩展集群,但即使在扩展集群中的核心后,我的数据帧的分区数会减少(基于集群以前的状态,它可能具有较少的核心) 即使我的集群将自动扩展(横向扩展),处理也将限于我所使用的分区数Scala 用于databricks可扩展集群的Spark重新分区逻辑,scala,apache-spark,gzip,azure-databricks,Scala,Apache Spark,Gzip,Azure Databricks,Databricks spark cluster可根据负载进行更换 我正在spark中读取gzip文件,并对rdd进行重新分区,以获得并行性,因为gzip文件将在单核上读取并生成 根据理想的分区数是集群中我可以在重新分区期间设置的核心数,但是在自动缩放集群的情况下,这个数字将根据集群的状态和其中有多少执行器而变化 那么,对于一个可自动伸缩的spark集群,分区逻辑应该是什么呢 编辑1: 文件夹不断增长,gzip文件定期出现在其中,gzip文件大小约为10GB,未压缩大小约为150GB。我知道多个
num_partitions = <cluster cores before scaling>
df.repartition(num_partitions)
num\u分区=
重新分区(num_分区)
对于可拆分的文件/数据,分区将主要根据核心、操作范围窄或宽、文件大小等自动创建。分区也可以使用合并
和重新分区
进行编程控制。但是对于一个gzip/un可拆分文件,一个文件只有一个任务,它可以是尽可能多的并行内核(如您所说)
对于动态集群,您可以选择将作业指向包含大量gzip文件的文件夹/存储桶。假设你有1000个文件要处理,你有10个内核,那么10个将并行。当集群动态增加到20时,20将并行运行。这是自动发生的,您无需为此编写代码。唯一的问题是,您不能缩放比可用内核更少的文件。这是不可拆分文件的一个已知缺陷
另一个选项是根据可用文件的数量和大小定义作业的集群大小。您可以找到基于历史运行时间的时间公式。假设您有5个大文件和10个小文件(大小为大文件的一半),那么您可以分配20个内核(10+2*5)来高效地使用集群资源 对于可拆分的文件/数据,分区将主要根据核心、操作范围窄或宽、文件大小等自动创建。分区也可以使用
coalesce
和repartition
进行编程控制。但是对于一个gzip/un可拆分文件,一个文件只有一个任务,它可以是尽可能多的并行内核(如您所说)
对于动态集群,您可以选择将作业指向包含大量gzip文件的文件夹/存储桶。假设你有1000个文件要处理,你有10个内核,那么10个将并行。当集群动态增加到20时,20将并行运行。这是自动发生的,您无需为此编写代码。唯一的问题是,您不能缩放比可用内核更少的文件。这是不可拆分文件的一个已知缺陷
另一个选项是根据可用文件的数量和大小定义作业的集群大小。您可以找到基于历史运行时间的时间公式。假设您有5个大文件和10个小文件(大小为大文件的一半),那么您可以分配20个内核(10+2*5)来高效地使用集群资源 标准gzip文件是不可拆分的,因此Spark将只使用一个内核、一个任务来处理gzip文件,无论您的设置是什么[从Spark 2.4.5/3.0起]。希望在创建大型文件时,世界将转向bzip2或其他可拆分压缩技术 如果您直接将数据写入拼花地板,您将得到一个可拆分的拼花地板文件。这将由一个核心写出。 如果坚持使用默认的gzip编解码器,最好在读取后重新分区,并写出多个拼花文件
from pyspark.sql.types import StructType, StructField, StringType, DoubleType, IntegerType
schema = StructType([
StructField("a",IntegerType(),True),
StructField("b",DoubleType(),True),
StructField("c",DoubleType(),True)])
input_path = "s3a://mybucket/2G_large_csv_gzipped/onebillionrows.csv.gz"
spark.conf.set('spark.sql.files.maxPartitionBytes', 1000 * (1024 ** 2))
df_two = spark.read.format("csv").schema(schema).load(input_path)
df_two.repartition(32).write.format("parquet").mode("overwrite").save("dbfs:/tmp/spark_gunzip_default_remove_me")
我最近发现了一个可拆分的gzip编解码器,并且初步测试非常有希望。该编解码器实际上多次读取该文件,每个任务先扫描一定数量的字节(不进行解压缩),然后开始解压缩。
当需要将数据框作为拼花文件写入时,这种方法的好处就会得到回报。您将得到多个并行写入的文件,以获得更高的吞吐量和更短的挂钟时间(您的CPU时间将更高)
参考:
我的测试用例:
from pyspark.sql.types import StructType, StructField, StringType, DoubleType, IntegerType
schema = StructType([
StructField("a",IntegerType(),True),
StructField("b",DoubleType(),True),
StructField("c",DoubleType(),True)])
input_path = "s3a://mybucket/2G_large_csv_gzipped/onebillionrows.csv.gz"
spark.conf.set('spark.sql.files.maxPartitionBytes', 1000 * (1024 ** 2))
df_gz_codec = (spark.read
.option('io.compression.codecs', 'nl.basjes.hadoop.io.compress.SplittableGzipCodec')
.schema(schema)
.csv(input_path)
)
df_gz_codec.write.format("parquet").save("dbfs:/tmp/gunzip_to_parquet_remove_me")
标准的gzip文件是不可拆分的,因此Spark将只使用一个内核、一个任务来处理gzip文件,无论您的设置是什么[从Spark 2.4.5/3.0起]。希望在创建大型文件时,世界将转向bzip2或其他可拆分压缩技术 如果您直接将数据写入拼花地板,您将得到一个可拆分的拼花地板文件。这将由一个核心写出。 如果坚持使用默认的gzip编解码器,最好在读取后重新分区,并写出多个拼花文件
from pyspark.sql.types import StructType, StructField, StringType, DoubleType, IntegerType
schema = StructType([
StructField("a",IntegerType(),True),
StructField("b",DoubleType(),True),
StructField("c",DoubleType(),True)])
input_path = "s3a://mybucket/2G_large_csv_gzipped/onebillionrows.csv.gz"
spark.conf.set('spark.sql.files.maxPartitionBytes', 1000 * (1024 ** 2))
df_two = spark.read.format("csv").schema(schema).load(input_path)
df_two.repartition(32).write.format("parquet").mode("overwrite").save("dbfs:/tmp/spark_gunzip_default_remove_me")
我最近发现了一个可拆分的gzip编解码器,并且初步测试非常有希望。该编解码器实际上多次读取该文件,每个任务先扫描一定数量的字节(不进行解压缩),然后开始解压缩。
当需要将数据框作为拼花文件写入时,这种方法的好处就会得到回报。您将得到多个并行写入的文件,以获得更高的吞吐量和更短的挂钟时间(您的CPU时间将更高)
参考:
我的测试用例:
from pyspark.sql.types import StructType, StructField, StringType, DoubleType, IntegerType
schema = StructType([
StructField("a",IntegerType(),True),
StructField("b",DoubleType(),True),
StructField("c",DoubleType(),True)])
input_path = "s3a://mybucket/2G_large_csv_gzipped/onebillionrows.csv.gz"
spark.conf.set('spark.sql.files.maxPartitionBytes', 1000 * (1024 ** 2))
df_gz_codec = (spark.read
.option('io.compression.codecs', 'nl.basjes.hadoop.io.compress.SplittableGzipCodec')
.schema(schema)
.csv(input_path)
)
df_gz_codec.write.format("parquet").save("dbfs:/tmp/gunzip_to_parquet_remove_me")
当你否决投票时,请留下评论。请看我的回答是否有帮助。我没有投反对票,我投赞成票