Spark分区数据集按列值

时间:2019-05-02 18:21:02

标签: scala apache-spark sharding data-partitioning

(我是Spark的新手)我需要存储大量的数据行,然后处理对这些数据的更新。对于这些行,我们具有唯一的ID(DB PK),并且我们希望将uniqueID % numShards设置的数据分片,以形成大小相等的可寻址分区。由于PK(唯一ID)同时存在于数据和更新文件中,因此很容易确定要更新的分区。我们打算以相同的标准对数据和更新进行分片,并定期重写“分片S +为分片S累积的所有更新=>新分片S”。 (我们知道如何结合碎片S +更新=新碎片S。)

如果这是我们的设计,则需要(1)将DataFrame的一列(例如:K列)分片到|range(K)|分区中,以确保分区中的所有行在K列中具有相同的值,并且(2)知道k = row.uniqueID % numShards就能找到与column_K = k对应的Parquet文件。

这是一个好的设计吗,还是Spark提供了一些开箱即用的东西,使我们的任务容易得多?

我们应该使用哪个Spark类/方法对数据进行分区?我们正在查看RangePartitioner,但是构造函数正在询问分区数。我们要指定“使用column_K进行分区,并为每个不同的值k in range(K)进行一个分区”,因为我们已经创建了column_K = uniqueID % numShards。哪个分区适合分割DataFrame的一列值?我们是否需要创建自定义分区程序,还是使用partitionByrepartitionByRange或...?

这是我们目前所拥有的:

import org.apache.spark.sql.functions._
val df = spark.read
.option("fetchsize", 1000)
.option("driver", "oracle.jdbc.driver.OracleDriver")
.jdbc(jdbc_url, "SCHEMA.TABLE_NAME", partitions, props)
.withColumn("SHARD_ID", col("TABLE_PK") % 1024)
.write
.parquet("parquet/table_name")

现在,我们需要指定在将DataFrame划分为Parquet文件之前,应将SHARD_ID进行分区。

1 个答案:

答案 0 :(得分:0)

这有效:

val df = spark.read
.option("fetchsize", 1000)
.option("driver", "oracle.jdbc.driver.OracleDriver")
.jdbc(jdbc.getString("url"), "SCHEMA.TABLE_NAME", partitions, props)
.withColumn("SHARD_ID", col("TABLE_PK") % 1024)
.write
.partitionBy("SHARD_ID")
.parquet("parquet/table_name")