(我是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
的一列值?我们是否需要创建自定义分区程序,还是使用partitionBy
或repartitionByRange
或...?
这是我们目前所拥有的:
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
进行分区。
答案 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")