Spark JDBC 中的伪列
Posted
技术标签:
【中文标题】Spark JDBC 中的伪列【英文标题】:Pseudocolumn in Spark JDBC 【发布时间】:2017-12-03 06:41:55 【问题描述】:我正在使用查询从 mysql 中获取数据,如下所示:
var df = spark.read.format("jdbc")
.option("url", "jdbc:mysql://10.0.0.192:3306/retail_db")
.option("driver" ,"com.mysql.jdbc.Driver")
.option("user", "retail_dba")
.option("password", "cloudera")
.option("dbtable", "orders")
.option("partitionColumn", "order_id")
.option("lowerBound", "1")
.option("upperBound", "68883")
.option("numPartitions", "4")
.load()
问题是,我可以在指定partitionColumn
的option
中使用伪列(如Oracle 中的ROWNUM
或DB2 中的RRN(employeeno)
)吗?
如果不是,我们可以指定一个不是主键的分区列吗?
【问题讨论】:
【参考方案1】:我可以使用伪列吗(如 Oracle 中的 ROWNUM 或 DB2 中的 RRN(employeeno))
TL;DR 可能没有。
虽然 Spark 不考虑 PRIMARY KEY
或 UNIQUE
之类的约束条件,但对 partitionColumn
的要求非常重要,文档中没有明确说明 - 它必须确定性。
每个执行程序都使用单独的事务获取自己的数据。如果数字列不是确定性的(稳定的,在事务之间保留),Spark 看到的数据状态可能会不一致,并且可能会重复或跳过记录。
因为ROWNUM
的实现通常是不稳定的(取决于不稳定的排序,并且会受到索引等功能的影响),所以partitionColumn
的选择并不安全。出于同样的原因,您不能使用随机数。
此外,一些供应商可能会进一步限制对伪列的允许操作,使它们不适合用作分区列。 For example Oracle ROWNUM
对大于正整数的 ROWNUM 值进行条件测试始终为假。
可能会静默失败,导致错误结果。
我们能否指定一个不是主键的分区列
可以,只要满足上述标准。
【讨论】:
【参考方案2】:根据Spark's official documentation,partitionColumn
可以是任何数字列(不一定是主键列)。
partitionColumn 必须是相关表中的数字列。
参考:https://spark.apache.org/docs/latest/sql-data-sources-jdbc.html
【讨论】:
请说得更具体一些——它可以是一个伪列吗?例如,像 Oracle ROWNUM ? 您是否尝试过在代码中使用 ROWNUM 而不是 order_id?以上是关于Spark JDBC 中的伪列的主要内容,如果未能解决你的问题,请参考以下文章