1. 程式人生 > >Spark支援四種方式從資料庫中讀取資料

Spark支援四種方式從資料庫中讀取資料

目前Spark支援四種方式從資料庫中讀取資料,這裡以Mysql為例進行介紹。

一、不指定查詢條件

  這個方式連結MySql的函式原型是:

def jdbc(url: String, table: String, properties: Properties): DataFrame

  我們只需要提供Driver的url,需要查詢的表名,以及連線表相關屬性properties。下面是具體例子:

val prop = new Properties() val df = sqlContext.read.jdbc(url, "iteblog", prop ) println(df.count())
println(df.rdd.partitions.size)

  我們執行上面的程式,可以看到df.rdd.partitions.size輸出結果是1,這個結果的含義是iteblog表的所有資料都是由RDD的一個分割槽處理的,所以說,如果你這個表很大,很可能會出現OOM

WARN TaskSetManager: Lost task 0.0 in stage 1.0 (TID 14, spark047219): java.lang.OutOfMemoryError: GC overhead limit exceeded at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java
:3380)

這種方式在資料量大的時候不建議使用。


如果想及時瞭解Spark、Hadoop或者Hbase相關的文章,歡迎關注微信公共帳號:iteblog_hadoop

二、指定資料庫欄位的範圍

  這種方式就是通過指定資料庫中某個欄位的範圍,但是遺憾的是,這個欄位必須是數字,來看看這個函式的函式原型:

def jdbc( url: String, table: String, columnName: String, lowerBound: Long, upperBound: Long, numPartitions: Int, connectionProperties: Properties)
: DataFrame

  前兩個欄位的含義和方法一類似。columnName就是需要分割槽的欄位,這個欄位在資料庫中的型別必須是數字;lowerBound就是分割槽的下界;upperBound就是分割槽的上界;numPartitions是分割槽的個數。同樣,我們也來看看如何使用:

val lowerBound = 1 val upperBound = 100000 val numPartitions = 5 val prop = new Properties() val df = sqlContext.read.jdbc(url, "iteblog", "id", lowerBound, upperBound, numPartitions, prop)

  這個方法可以將iteblog表的資料分佈到RDD的幾個分割槽中,分割槽的數量由numPartitions引數決定,在理想情況下,每個分割槽處理相同數量的資料,我們在使用的時候不建議將這個值設定的比較大,因為這可能導致資料庫掛掉!但是根據前面介紹,這個函式的缺點就是隻能使用整形資料欄位作為分割槽關鍵字。

  這個函式在極端情況下,也就是設定將numPartitions設定為1,其含義和第一種方式一致。

三、根據任意欄位進行分割槽

  基於前面兩種方法的限制,Spark還提供了根據任意欄位進行分割槽的方法,函式原型如下:

def jdbc( url: String, table: String, predicates: Array[String], connectionProperties: Properties): DataFrame

這個函式相比第一種方式多了predicates引數,我們可以通過這個引數設定分割槽的依據,來看看例子:

val predicates = Array[String]("reportDate <= '2014-12-31'", "reportDate > '2014-12-31' and reportDate <= '2015-12-31'") val prop = new Properties() val df = sqlContext.read.jdbc(url, "iteblog", predicates, prop)

最後rdd的分割槽數量就等於predicates.length。

四、通過load獲取

Spark還提供通過load的方式來讀取資料。

  options函式支援url、driver、dbtable、partitionColumn、lowerBound、upperBound以及numPartitions選項,細心的同學肯定發現這個和方法二的引數一致。是的,其內部實現原理部分和方法二大體一致。同時load方法還支援json、orc等資料來源的讀取。