按键对分组进行分组并对数据进行分区

时间:2020-10-22 19:20:48

标签: apache-spark apache-spark-sql

我有一个很大的csv文件,其中的数据具有以下格式。

cityId1,名称,地址,.......,邮政编码

cityId2,名称,地址.... zip

cityId1,名称,地址,.......,邮政编码

........

cityIdN,名称,地址.... zip

我正在对上面的csv文件执行以下操作:

  1. 按cityId分组作为键,将资源列表作为值

    df1.groupBy($“ cityId”)。agg(collect_list(struct(cols.head,cols.tail:_ *))作为“资源”)

  2. 将其更改为jsonRDD

    val jsonDataRdd2 = df2.toJSON.rdd

  3. 遍历每个分区并按键上载到s3

  • 由于业务逻辑约束(从S3读取其他服务的方式),我无法通过写入使用数据帧分区

我的问题:

  • spark分区的默认大小是多少?
  • 假设分区的默认大小为X MB,并且dataFrame中存在一条大记录,其中的键具有Y MBs的数据(Y> X),在这种情况下会发生什么?
  • 在这种情况下,我是否需要担心在不同分区中使用相同的密钥?

1 个答案:

答案 0 :(得分:0)

回答您的问题:

  • 从辅助存储(S3,HDFS)读取时,分区等于文件系统的块大小128MB或256MB;但是您可以立即重新划分RDD,而不是数据帧。 (对于JDBC和Spark结构化流,分区的大小是动态的。)

  • 应用“宽转换”并重新分区时,分区的数量和大小最有可能发生变化。给定分区的大小具有最大值。在Spark 2.4.x中,分区大小增加到8GB。因此,如果任何转换(例如,collect_list与groupBy结合使用)的gens超过此最大大小,您将得到一个错误,程序将中止。因此,您需要明智地进行分区,或者需要有足够数量的分区进行聚合-请参见spark.sql.shuffle.partitions参数。

  • Spark进行处理的并行模型依赖于通过散列,范围分区等方式分配“键”的方式,这些键被分配到一个且仅一个分区-改组。因此,遍历一个分区foreachPartition,mapPartitions没有问题。