Spark允许您从sql db源并行读取,并且可以基于滑动窗口进行分区,例如(来自book,第7章)
val colName = "count"
val lowerBound = 0L
val upperBound = 348113L // this is the max count in our table
val numPartitions = 10
spark.read.jdbc(url,
tablename,
colName,
lowerBound,
upperBound,
numPartitions,
props).count()
这里,上限是事先已知的。
让我们说,一张桌子在一天内获得'x'行数(可能在1-2百万之间),在一天结束时我们提交一个火花作业,做一些转换并写一个Parquet / CSV / JSON。如果我们事先不知道将写入多少行(因为它从1-2百万不等)到SQL源数据库,在这种情况下,进行分区的最佳方法或做法。
一种方法是估计你的上限,但我不确定这是一种正确的方法。
答案 0 :(得分:1)
我有完全相同的问题。我也需要随机发布。所以我选择一个int列并获得mod 10。这样我就可以分开任何东西而不需要关心 界限或分布。
options += ("numPartitions" -> numPartitions,"partitionColumn"->"mod(my_int_column,10)","lowerBound"->"0","upperBound"->"9")
答案 1 :(得分:0)
每天行数不同的事实并没有太大变化。假设你想要有20个分区,那么有一天你在一个分区中大约有1M / 20行,而另一天大约有2M / 20。如果有更多数据并且分区数量是固定的,那么显然分区中将包含更多数据。
如果有关于下限和上限的混淆,我想清除lowerBound和upperBound引用要分区的列的值而不是行数。此外,表中未对这些值进行过滤,这意味着如果您的行的值小于lowerBound或大于upperBound,则仍会包含这些行。
请参阅: Whats meaning of partitionColumn, lowerBound, upperBound, numPartitions parameters?
来自文档:http://spark.apache.org/docs/latest/sql-programming-guide.html#jdbc-to-other-databases
partitionColumn,lowerBound,upperBound:如果指定了任何选项,则必须全部指定这些选项。此外,必须指定numPartitions。它们描述了在从多个工作者并行读取时如何对表进行分区。 partitionColumn必须是相关表中的数字列。请注意,lowerBound和upperBound仅用于决定分区步幅,而不是用于过滤表中的行。因此,表中的所有行都将被分区并返回。此选项仅适用于阅读。