【Spark】SparkJdbc并发读取的partitionColumn规则

【Spark】SparkJdbc并发读取的partitionColumn规则

参考: spark 官方文档

使用spark的jdbc的方式读取数据的操作:

方式1:

spark.read.option(...).jdbc(url,table,properties)

方式2:

spark.fomat('jdbc').option(...).load()

可以注意到,在spark通过jdbc读取数据时候是有一个option的选项的。
本次主要讨论spark jdbc的多连接读取参数:

  • partitionColumn
  • lowerBound
  • upperBound
  • numPartitions

解释一下几个参数:
partitionColumn 这个参数是制定要用来分区查询的列,一般为可排序类型,比如: numeric,date, or timestamp 一般来说是可排序类型的列,有点像sqoop的分区抽取操作的设置。
lowerBoundupperBound 共同用来决定分区的跨度。
numPartitions 设置spark jdbc的最大并发度,其中如果开启这个功能,四个都是必要参数

这些参数可以写在option当中进行配置。

那么,它的现象是怎么样的?
假设有一张mysql的表stu,总共有3万数据。其中有一列id为自增列。利用spark jdbc读取数据的时候。

spark.fomat('jdbc')
         .option("partitionColumn","id")
         .option("lowerBound","100000")
         .option("upperBound","200000")
         .option("numPartitions",4)
         ....  //其他options
         .load()

那么这个设置下的spark 是如何工作的?
根据option中的numPartitions ,可以得知,这个spark jdbc的连接最大可以有4个,
接着lowerBoundupperBound的控制下,spark会生成如下4条sql

1. select * from stu where id<12500 and id is null
2. select * from stu where id>=12500 and id<15000
3. select * from stu where id>=15000 and id<17500
4. select * from stu where id>=17500 

如果当这个 numPartitions设置为5时,spark会生成如下几条sql

1. select * from stu where id<12000 and id is null
2. select * from stu where id>=12000 and id<14000
3. select * from stu where id>=14000 and id<16000
4. select * from stu where id>=16000 and id<18000
5. select * from stu where id>=18000 

什么?你要是问我当numPartitions 设置为3的时候会生成什么sql?

select * from stu where id<13333 and id is null
select * from stu where id>=13333 and id<=16666 
select * from stu where id>=16666

附源码位置:
org.apache.spark.sql.execution.datasources.jdbc.JDBCRelation#columnPartition

 val stride: Long = upperBound / numPartitions - lowerBound / numPartitions

    var i: Int = 0
    val column = partitioning.column
    var currentValue = lowerBound
    val ans = new ArrayBuffer[Partition]()
    while (i < numPartitions) {
      val lBoundValue = boundValueToString(currentValue)
      val lBound = if (i != 0) s"$column >= $lBoundValue" else null
      currentValue += stride
      val uBoundValue = boundValueToString(currentValue)
      val uBound = if (i != numPartitions - 1) s"$column < $uBoundValue" else null
      val whereClause =
        if (uBound == null) {
          lBound
        } else if (lBound == null) {
          s"$uBound or $column is null"
        } else {
          s"$lBound AND $uBound"
        }
      ans += JDBCPartition(whereClause, i)
      i = i + 1
    }

总结:

这个 spark并发读取jdbc的数据时候,一定是全表全量数据 大家可要记住了!!!但是如果真的需要读取全表全量数据的话,这样还挺快的,会提升效率。
如果在这里有什么写错的地方,请大佬多多指教,在评论区留言,谢谢各位了!!!

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值