Spark:仅选择特定分区

时间:2018-03-24 09:37:26

标签: apache-spark apache-spark-sql spark-dataframe apache-spark-dataset

我的RDBMS数据库中有一个巨大的表,其中包含不同的帐户类型的记录。 我将这些数据加载到spark中一次,并根据帐户类型多次循环遍历此表以生成一些报告。

我在此表上创建了一个临时全局视图。

Player

现在,我想基于account_type列将此视图划分为多个分区,其中数据被分成块,因此每次我在此视图上循环访问account_type时,我只想选择该特定分区。

该特定列的重新分区可以轻松解决这个问题吗?如果是,我是否需要重新分配df然后创建一个全局临时视图,或者我对此不确定。 而且,我如何确保每次循环时只选择该特定分区。 请指教。

1 个答案:

答案 0 :(得分:1)

例如,您可以使用df.repartition(partition_size, col("account_type"))。在这里,我设置分区大小和我想要分区的列。否则,如果您想使用Spark SQL,可以使用:

SET spark.sql.shuffle.partitions = partition_size
SELECT * FROM df CLUSTER BY account_type

CLUSTER BY的工作方式类似于重新分区,但它也会对您的数据框进行排序。

使用与下一个分区类似的代码访问每个分区中的数据:

df.foreachPartition {
      p => /*your code goes here*/
}

您可以在其中进行所有计算并生成所需的报告。

要估计分区大小,您可以从默认值开始,例如:200,如果在控制期间出现Out Of Memory异常,则可以增加分区数,例如1024,直到您的作业成功执行。没有标准的方法来计算确切的分区数,因为它取决于几个因素,例如群集的大小(可用内核,内存)和数据大小。

此外,由于RDD在群集中随机分布,因此无法确定分区将包含哪些数据。确定这一点的唯一方法是使用foreachPartition中的自定义过滤器。例如,您可以将自定义条件应用为下一个:

df.foreachPartition( iter => {
        iter.foreach { i =>
          if(i.some_column == "somevalue")
            //write populate data

        }
    })
祝你好运