spark sql通過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 預期的分區數
connectionProperties mysql的配置參數,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)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM