【发布时间】:2017-04-26 09:32:02
【问题描述】:
在 Spark 中通过 JDBC 连接从 SQL Server 获取数据时,我发现我可以设置一些并行化参数,例如 partitionColumn、lowerBound、upperBound 和 numPartitions。我已经通过spark documentation 但无法理解它。
谁能解释一下这些参数的含义?
【问题讨论】:
标签: apache-spark jdbc apache-spark-sql
在 Spark 中通过 JDBC 连接从 SQL Server 获取数据时,我发现我可以设置一些并行化参数,例如 partitionColumn、lowerBound、upperBound 和 numPartitions。我已经通过spark documentation 但无法理解它。
谁能解释一下这些参数的含义?
【问题讨论】:
标签: apache-spark jdbc apache-spark-sql
只想添加到经过验证的答案中,
没有它们你会丢失一些数据是误导..
从文档中, 请注意,lowerBound 和 upperBound 仅用于决定分区步长,而不用于过滤表中的行。所以表中的所有行都会被分区并返回。此选项仅适用于阅读。
这意味着你的表有 1100 行,并且你指定
lowerBound0
upperBound1000 和
numPartitions: 10
, 您不会丢失 1000 到 1100 行。您最终会得到一些分区的行数超过预期的结果。(步幅值为 100)。
【讨论】:
创建分区不会因为过滤而导致数据丢失。
upperBound、lowerbound 和 numPartitions 只是定义了如何创建分区。 upperBound 和 lowerbound 没有定义要获取的 partitionColumn 值的范围(过滤器)。
For a given input of lowerBound (l), upperBound (u) and numPartitions (n)
The partitions are created as follows:
stride, s= (u-l)/n
**SELECT * FROM table WHERE partitionColumn < l+s or partitionColumn is null**
SELECT * FROM table WHERE partitionColumn >= l+s AND <2s
SELECT * FROM table WHERE partitionColumn >= l+2s AND <3s
...
**SELECT * FROM table WHERE partitionColumn >= l+(n-1)s**
例如,对于upperBound = 500、lowerBound = 0 和numPartitions = 5。分区将根据以下查询:
SELECT * FROM table WHERE partitionColumn < 100 or partitionColumn is null
SELECT * FROM table WHERE partitionColumn >= 100 AND <200
SELECT * FROM table WHERE partitionColumn >= 200 AND <300
SELECT * FROM table WHERE partitionColumn >= 300 AND <400
...
SELECT * FROM table WHERE partitionColumn >= 400
根据partitionColumn的实际取值范围,每个分区的结果大小会有所不同。
【讨论】:
partitionColumn 中的值的假设?如果您没有像 1、2、3、4、...这样的唯一整数 ROWID,我无法理解这是如何工作的。
实际上,上面的列表遗漏了几件事,特别是第一个和最后一个查询。
没有它们,您将丢失一些数据(lowerBound 之前的数据和upperBound 之后的数据)。从示例中不清楚,因为下限为 0。
完整列表应该是:
SELECT * FROM table WHERE partitionColumn < 100
SELECT * FROM table WHERE partitionColumn BETWEEN 0 AND 100
SELECT * FROM table WHERE partitionColumn BETWEEN 100 AND 200
...
SELECT * FROM table WHERE partitionColumn > 9000
【讨论】:
upperBound 设置得太低,一个执行器将比其他执行器完成更多的工作,并且可能会耗尽内存。
BETWEEN 包含上下限。实际实现分别使用>=和<:Spark doc
partitionColumn 的值从 1 增加到 1000,例如?否则没有意义。我有一个由 Netezza 数据库分配的partitionColumn,它是一个很大的数字234235000 到234234999。如果upperBound 指的是元素的数量,而不是partitionColumn 中的值,那么这个答案对我来说没有意义。
很简单:
partitionColumn 是用于确定分区的列。lowerBound 和 upperBound 确定要获取的值的范围。完整的数据集将使用与以下查询对应的行:
SELECT * FROM table WHERE partitionColumn BETWEEN lowerBound AND upperBound
numPartitions 确定要创建的分区数。在lowerBound 和upperBound 之间的范围被划分为numPartitions,每个numPartitions 的步幅等于:
upperBound / numPartitions - lowerBound / numPartitions
例如,如果:
lowerBound: 0upperBound: 1000numPartitions: 10
Stride 等于 100,分区对应于以下查询:
SELECT * FROM table WHERE partitionColumn BETWEEN 0 AND 100SELECT * FROM table WHERE partitionColumn BETWEEN 100 AND 200...SELECT * FROM table WHERE partitionColumn BETWEEN 900 AND 1000【讨论】:
BETWEEN 包含上下限。实际实现分别使用>=和<:Spark doc