Spark優化(七):廣播大變數
廣播大變數
有時在開發過程中,會遇到需要在運算元函式中使用外部變數的場景(尤其是大變數,比如100M以上的大集合),那麼此時就應該使用Spark的廣播(Broadcast)功能來提升效能。
在運算元函式中使用到外部變數時,預設情況下,Spark會將該變數複製多個副本,通過網路傳輸到task中,此時每個task都有一個變數副本。如果變數本身比較大的話(比如100M,甚至1G),那麼大量的變數副本在網路中傳輸的效能開銷,以及在各個節點的Executor中佔用過多記憶體導致的頻繁GC,都會極大地影響效能。
因此對於上述情況,如果使用的外部變數比較大,建議使用Spark的廣播功能,對該變數進行廣播。
廣播後的變數,會保證每個Executor的記憶體中,只駐留一份變數副本,而Executor中的task執行時共享該Executor中的那份變數副本。這樣的話,可以大大減少變數副本的數量,從而減少網路傳輸的效能開銷,並減少對Executor記憶體的佔用開銷,降低GC的頻率。
廣播大變數的程式碼示例
// 以下程式碼在運算元函式中,使用了外部的變數。
// 此時沒有做任何特殊操作,每個task都會有一份list1的副本。
val list1 = ...
rdd1.map(list1...)
// 以下程式碼將list1封裝成了Broadcast型別的廣播變數。
// 在運算元函式中,使用廣播變數時,首先會判斷當前task所在Executor記憶體中,是否有變數副本。
// 如果有則直接使用;如果沒有則從Driver或者其他Executor節點上遠端拉取一份放到本地Executor記憶體中。
// 每個Executor記憶體中,就只會駐留一份廣播變數副本。
val list1 = ...
val list1Broadcast = sc.broadcast(list1)
rdd1.map(list1Broadcast...)