sparksql通过jdbc读取mysql时划分分区问题

当通过spark读取mysql时,如果数据量比较大,为了加快速度,通常会起多个task并行拉取mysql数据。
其中一个api是

def
jdbc(url: String, table: String, columnName: String, lowerBound: Long, upperBound: Long, numPartitions: Int, connectionProperties: Properties): DataFrame
参数说明
url访问mysql时的jdbc链接,如jdbc:mysql://190.1.98.225:2049/test
table访问的表
columnName用于分区的列,必须是数字类型
lowerBound分区列的最小值
upperBound分区列的最大值
numPartitions预期的分区数
connectionPropertiesmysql的配置参数,key value形式

这里面容易引起混淆的是lowerBound和upperBound。需要注意的是lowerBound和upperBound仅用于决定划分分区时的步长,而不是用于按照这两个值对数据进行过滤。 因此,无论这两个值如何设置,表中的所有行都将被读取。

同时需要注意的是,尽量不要创建太多分区,否则很容易将mysql搞挂。

关于具体的分区,我写了个示例代码,参考如下(本部分代码参考spark源码org.apache.spark.sql.execution.datasources.jdbc中columnPartition方法 )。

代码如下:

import scala.collection.mutable.ArrayBuffer
object PrintJdbcParition {
  case class JDBCPartition(whereClause: String, partitionIndex: Int)
  def main(args: Array[String]): Unit = {
    val numPartitions = 10
    val lowerBound = 100
    val upperBound = 900
    val column = "id"
    // Overflow and silliness can happen if you subtract then divide.
    // Here we get a little roundoff, but that's (hopefully) OK.
    val stride: Long = (upperBound / numPartitions - lowerBound / numPartitions)
    var i: Int = 0
    var currentValue: Long = lowerBound
    var ans = new ArrayBuffer[JDBCPartition]()
    while (i < numPartitions) {
      val lowerBound = if (i != 0) s"$column >= $currentValue" else null
      currentValue += stride
      val upperBound = if (i != numPartitions - 1) s"$column < $currentValue" else null
      val whereClause =
        if (upperBound == null) {
          lowerBound
        } else if (lowerBound == null) {
          upperBound
        } else {
          s"$lowerBound AND $upperBound"
        }
      ans += JDBCPartition(whereClause, i)
      i = i + 1
    }
    ans.toArray.map(println(_))
  }
}

代码执行结果如下:

JDBCPartition(id < 180,0)
JDBCPartition(id >= 180 AND id < 260,1)
JDBCPartition(id >= 260 AND id < 340,2)
JDBCPartition(id >= 340 AND id < 420,3)
JDBCPartition(id >= 420 AND id < 500,4)
JDBCPartition(id >= 500 AND id < 580,5)
JDBCPartition(id >= 580 AND id < 660,6)
JDBCPartition(id >= 660 AND id < 740,7)
JDBCPartition(id >= 740 AND id < 820,8)
JDBCPartition(id >= 820,9)
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值