最近在项目中遇到一个问题:在阿里云 oss 上有一些 parquet 文件,这些文件是按照 accountId 进行 partitionBy
写入的,有多个 accountId 对应的目录,总共有 4927 个 parquet 文件,总大小约为 7.3GB。但是使用 Spark 读取然后按 accountId partitionBy
写出去的文件结构跟原来的不一致,而预期是原样读取然后原样写出去。
查阅了相关资料,发现 Spark 有内存分区和磁盘分区的概念,其中 coalesce()
和 repartition()
改变的是内存分区,partitionBy()
改变的是磁盘分区,反映在磁盘中的目录上,每一个内存分区中的数据会按 partitionBy()
分区写到磁盘上。
oss 上的 parquet 文件是使用 MongoSpark 从 MongoDB 中加载的,使用 Dataset.rdd().getNumPartitions()
查看内存分区数为 500 多,而读取这些 parquet 文件之后得到的内存分区数却为 212。
查阅资料得知,可能与 FileSourceStrategy.scala
中的逻辑有关,但是 2.4.x 版本中相关逻辑被抽到了 DataSourceScanExec.scala
中。查看源码:Spark 会对读取到的文件进行重新切分&#