使用spark并行读取sql数据库而不知道上限

时间:2017-07-11 04:04:03

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

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源数据库,在这种情况下,进行分区的最佳方法或做法。

一种方法是估计你的上限,但我不确定这是一种正确的方法。

2 个答案:

答案 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仅用于决定分区步幅,而不是用于过滤表中的行。因此,表中的所有行都将被分区并返回。此选项仅适用于阅读。