十年網(wǎng)站開發(fā)經(jīng)驗 + 多家企業(yè)客戶 + 靠譜的建站團(tuán)隊
量身定制 + 運營維護(hù)+專業(yè)推廣+無憂售后,網(wǎng)站問題一站解決
這篇文章主要介紹“Spark性能優(yōu)化用foreachPartition還是與foreach”,在日常操作中,相信很多人在Spark性能優(yōu)化用foreachPartition還是與foreach問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Spark性能優(yōu)化用foreachPartition還是與foreach”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!
創(chuàng)新互聯(lián)建站專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都網(wǎng)站建設(shè)、網(wǎng)站設(shè)計、集寧網(wǎng)絡(luò)推廣、小程序開發(fā)、集寧網(wǎng)絡(luò)營銷、集寧企業(yè)策劃、集寧品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎;創(chuàng)新互聯(lián)建站為所有大學(xué)生創(chuàng)業(yè)者提供集寧建站搭建服務(wù),24小時服務(wù)熱線:18980820575,官方網(wǎng)址:www.cdcxhl.com
首先,我們對比一下foreachPartition和foreach兩個方法的實現(xiàn),有什么不同的地方:
def foreach(f: T => Unit): Unit = withScope {
val cleanF = sc.clean(f)
sc.runJob(this, (iter: Iterator[T]) => iter.foreach(cleanF))
}
def foreachPartition(f: Iterator[T] => Unit): Unit = withScope {
val cleanF = sc.clean(f)
sc.runJob(this, (iter: Iterator[T]) => cleanF(iter))
}
2個方法,參數(shù)都是一個函數(shù)文本,不同的是foreach當(dāng)中,函數(shù)文本希望的參數(shù)是T,也就是RDD當(dāng)中的元素類型;foreachPartition當(dāng)中,函數(shù)文本希望的參數(shù)是Iterator[T],也就是一個partition。
而在內(nèi)部實現(xiàn)上,其實是大同小異的。對于foreachPartition而言,直接在各個partition上運行傳入的函數(shù)文本;而對于foreach而言,是把傳入的函數(shù)文本,交給各個partition的foreach去執(zhí)行。
我們查看一些spark性能優(yōu)化指南,會提到用foreachPartition替代foreach,有助于性能的提高。那么我們要怎樣來理解這句話呢?看看下面這段代碼:
rdd.foreach { x => {
val dbClient = new DBClient
dbClient.ins(x)
}}
在上面這段代碼當(dāng)中,針對RDD當(dāng)中的每一條數(shù)據(jù),都會new一個db client,這樣的效率,顯然是無比底下的。正確的寫法應(yīng)該是這個樣子的:
rdd.foreachPartition { part => {
val dbClient = new DBClient
part.foreach{ x => {
dbClient.ins(x)
}}
}}
那么這種寫法究竟好在哪里,還是要從spark的核心概念開始講起,我們都知道spark是一個分布式的實時計算系統(tǒng),而RDD是分布式計算的基礎(chǔ),而partition分區(qū)又是這個當(dāng)中的關(guān)鍵,比如我們搭建一個3*4core的spark集群,對于一個大任務(wù)而言,我們往往是希望有12個線程一起來完成這個任務(wù),用下面的代碼來構(gòu)建rdd就能夠達(dá)到我們的目的:
val rdd = sc.textFile("hdfs://master:9000/woozoom/mavlink1.log", 12)
注意紅色字體的部分,代表著構(gòu)建出來的rdd的分區(qū)數(shù)量。之后,rdd.foreachPartition,spark集群會把12個分區(qū)分別交給12個線程來分別進(jìn)行處理。結(jié)合上面的代碼,dbClient 會在每個線程當(dāng)中分別構(gòu)建,會有12個db client被構(gòu)建。
那么有沒有另一種可能性,我們只構(gòu)建一個db client,12個線程都用這一個db client來執(zhí)行數(shù)據(jù)庫操作,像下面這樣:
val dbClient = new DBClient
rdd.foreach { x => {
dbClient.ins(x)
}}
要這么寫,需要有2個前提:1、dbClient 是線程安全的,2、dbClient 實現(xiàn)了java的序列化接口。而在很多情況下,例如在對hbase進(jìn)行訪問的時候,這兩個條件都是不滿足的。
到此,關(guān)于“Spark性能優(yōu)化用foreachPartition還是與foreach”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>
網(wǎng)站題目:Spark性能優(yōu)化用foreachPartition還是與foreach
鏈接地址:http://m.jiaotiyi.com/article/jecsed.html