Spark- JdbcRDD以及注意事項

先上Demojava

package com.rz.spark.base

import java.sql.DriverManager

import org.apache.spark.rdd.JdbcRDD
import org.apache.spark.{SparkConf, SparkContext}

object JdbcRDDDemo {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf().setAppName(this.getClass.getSimpleName).setMaster("local[2]")
    val sc = new SparkContext(conf)

    val getConn=()=>{
      DriverManager.getConnection("jdbc:mysql://localhost:3306/bigdata?characterEncoding=utf-8","root","root")
    }

    // 建立RDD,這個RDD會記錄之後從MySQL中讀取數據
    val jdbcRDD: JdbcRDD[(Int, String, Int)] = new JdbcRDD(sc,
      getConn,
      "select * from logs where id >= ? and id <= ?",
      1,
      5,
      2, //分區數量
      rs => {
        val id = rs.getInt(1)
        val name = rs.getString(2)
        val age = rs.getInt(3)
        (id, name, age) //將數據庫查詢出來的數據集轉成想要的數據格式
      }
    )
    val rs = jdbcRDD.collect()
    print(rs.toBuffer)
  }
}

返回查詢結果正確mysql

現象

修改查詢的SQL,返回的數據量不對。sql

"select * from logs where id >= ? and id < ?"

緣由

在觸發Action的時候,Task在每一個分區上的業務邏輯是相同的(id >= ? and id < ?"),只是讀取的數據和處理的數據不同。RDD根據數據量和分區數據,均勻地分配每一個分區Task讀取數據的範圍。數據庫

分區1讀取[1,2)的數據,分區2讀取[3,5)的數據。apache

使用相同的邏輯分區1丟掉了id=2的數據,這是爲何,id >= 1 and id < 5"只返回3條數據的緣由,若是隻有一個分區的時候可以讀取到正確的數據量。this

解決辦法

爲了不出現丟數據,讀取數據時,區間兩端都包含。id >= 1 and id < =5。spa

相關文章
相關標籤/搜索