spark jdbc(mysql) 讀取并發(fā)度優(yōu)化

很多人在spark中使用默認(rèn)提供的jdbc方法時,在數(shù)據(jù)庫數(shù)據(jù)較大時經(jīng)常發(fā)現(xiàn)任務(wù) hang 住,其實是單線程任務(wù)過重導(dǎo)致,這時候需要提高讀取的并發(fā)度濒憋。
下文以 mysql 為例進(jìn)行說明。

在spark中使用jdbc

spark-env.sh 文件中加入:

export SPARK_CLASSPATH=/path/mysql-connector-java-5.1.34.jar

任務(wù)提交時加入:

--jars /path/mysql-connector-java-5.1.34.jar

1. 單partition(無并發(fā))

調(diào)用函數(shù)

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

使用:

val url = "jdbc:mysql://mysqlHost:3306/database"
val tableName = "table"

// 設(shè)置連接用戶&密碼
val prop = new java.util.Properties
prop.setProperty("user","username")
prop.setProperty("password","pwd")

// 取得該表數(shù)據(jù)
val jdbcDF = sqlContext.read.jdbc(url,tableName,prop)

// 一些操作
....

查看并發(fā)度

jdbcDF.rdd.partitions.size # 結(jié)果返回 1

該操作的并發(fā)度為1陶夜,你所有的數(shù)據(jù)都會在一個partition中進(jìn)行操作凛驮,意味著無論你給的資源有多少,只有一個task會執(zhí)行任務(wù)条辟,執(zhí)行效率可想而之黔夭,并且在稍微大點(diǎn)的表中進(jìn)行操作分分鐘就會OOM。

更直觀的說法是羽嫡,達(dá)到千萬級別的表就不要使用該操作本姥,count操作就要等一萬年,no zuo no die ,don't to try !

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

2. 根據(jù)Long類型字段分區(qū)

調(diào)用函數(shù)

  def jdbc(
  url: String,
  table: String,
  columnName: String,    # 根據(jù)該字段分區(qū)杭棵,需要為整形婚惫,比如id等
  lowerBound: Long,      # 分區(qū)的下界
  upperBound: Long,      # 分區(qū)的上界
  numPartitions: Int,    # 分區(qū)的個數(shù)
  connectionProperties: Properties): DataFrame

使用:

val url = "jdbc:mysql://mysqlHost:3306/database"
val tableName = "table"

val columnName = "colName"
val lowerBound = 1,
val upperBound = 10000000,
val numPartitions = 10,

// 設(shè)置連接用戶&密碼
val prop = new java.util.Properties
prop.setProperty("user","username")
prop.setProperty("password","pwd")

// 取得該表數(shù)據(jù)
val jdbcDF = sqlContext.read.jdbc(url,tableName,columnName,lowerBound,upperBound,numPartitions,prop)

// 一些操作
....

查看并發(fā)度

jdbcDF.rdd.partitions.size # 結(jié)果返回 10

該操作將字段 colName 中1-10000000條數(shù)據(jù)分到10個partition中,使用很方便魂爪,缺點(diǎn)也很明顯先舷,只能使用整形數(shù)據(jù)字段作為分區(qū)關(guān)鍵字。

3000w數(shù)據(jù)的表 count 跨集群操作只要2s滓侍。

3. 根據(jù)任意類型字段分區(qū)

調(diào)用函數(shù)

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

下面以使用最多的時間字段分區(qū)為例:

val url = "jdbc:mysql://mysqlHost:3306/database"
val tableName = "table"

// 設(shè)置連接用戶&密碼
val prop = new java.util.Properties
prop.setProperty("user","username")
prop.setProperty("password","pwd")

/**
* 將9月16-12月15三個月的數(shù)據(jù)取出蒋川,按時間分為6個partition
* 為了減少事例代碼,這里的時間都是寫死的
* modified_time 為時間字段
*/

   
val predicates =
    Array(
      "2015-09-16" -> "2015-09-30",
      "2015-10-01" -> "2015-10-15",
      "2015-10-16" -> "2015-10-31",
      "2015-11-01" -> "2015-11-14",
      "2015-11-15" -> "2015-11-30",
      "2015-12-01" -> "2015-12-15"
    ).map {
      case (start, end) =>
        s"cast(modified_time as date) >= date '$start' " + s"AND cast(modified_time as date) <= date '$end'"
    }

// 取得該表數(shù)據(jù)
val jdbcDF = sqlContext.read.jdbc(url,tableName,predicates,prop)

// 一些操作
....

查看并發(fā)度

jdbcDF.rdd.partitions.size # 結(jié)果返回 6

該操作的每個分區(qū)數(shù)據(jù)都由該段時間的分區(qū)組成撩笆,這種方式適合各種場景捺球,較為推薦缸浦。

結(jié)語

mysql 3000W 數(shù)據(jù)量表為例,單分區(qū)count氮兵,僵死若干分鐘報OOM裂逐。

分成5-20個分區(qū)后,count 操作只需要 2s

高并發(fā)度可以大幅度提高讀取以及處理數(shù)據(jù)的速度胆剧,但是如果設(shè)置過高(大量的partition同時讀取)也可能會將數(shù)據(jù)源數(shù)據(jù)庫弄掛絮姆。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市秩霍,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蚁阳,老刑警劉巖铃绒,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異螺捐,居然都是意外死亡颠悬,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門定血,熙熙樓的掌柜王于貴愁眉苦臉地迎上來赔癌,“玉大人,你說我怎么就攤上這事澜沟≡制保” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵茫虽,是天一觀的道長刊苍。 經(jīng)常有香客問我,道長濒析,這世上最難降的妖魔是什么正什? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮号杏,結(jié)果婚禮上婴氮,老公的妹妹穿的比我還像新娘。我一直安慰自己盾致,他們只是感情好主经,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著绰上,像睡著了一般旨怠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蜈块,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天鉴腻,我揣著相機(jī)與錄音迷扇,去河邊找鬼。 笑死爽哎,一個胖子當(dāng)著我的面吹牛蜓席,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播课锌,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼厨内,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了渺贤?” 一聲冷哼從身側(cè)響起雏胃,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎志鞍,沒想到半個月后瞭亮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡固棚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年统翩,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片此洲。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡厂汗,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出呜师,到底是詐尸還是另有隱情娶桦,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布匣掸,位于F島的核電站趟紊,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏碰酝。R本人自食惡果不足惜霎匈,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望送爸。 院中可真熱鬧铛嘱,春花似錦、人聲如沸袭厂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽纹磺。三九已至帖烘,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間橄杨,已是汗流浹背秘症。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工照卦, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人乡摹。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓役耕,卻偏偏與公主長得像,于是被迫代替她去往敵國和親聪廉。 傳聞我的和親對象是個殘疾皇子瞬痘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容