Spark入門3(累加器和廣播變量)
一、概要
通常情況下,當向Spark操作傳遞一個函數時,它會在一個遠程集群節點上執行,它會使用函數中所有變量的副本。這些變量被復制到所有的機器上,遠程機器上並沒有被更新的變量會向驅動程序回傳。在任務之間使用通用的,支持讀寫的共享變量是低效的。盡管如此,Spark提供了兩種有限類型的共享變量,廣播變量和累加器。
二、廣播變量
通常情況下,當一個RDD的很多操作都需要使用driver中定義的變量時,每次操作,driver都要把變量發送給worker節點一次,如果這個變量中的數據很大的話,會產生很高的傳輸負載,導致執行效率降低。
使用廣播變量可以使程序高效地將一個很大的只讀數據發送給多個worker節點,而且對每個worker節點只需要傳輸一次,每次操作時executor可以直接獲取本地保存的數據副本,不需要多次傳輸。
該Executor上的各個Task再從所在節點的BlockManager獲取變量,而不是從Driver獲取變量,從而提升了效率。一個Executor只需要在第一個Task啟動時,獲得一份Broadcast數據,之後的Task都從本節點的BlockManager中獲取相關數據。
這意味著當我們需要在多個階段的任務之間使用相同的數據,或者以反序列化形式緩存數據是十分重要的時候,顯式地創建廣播變量才有用。
另外,廣播過程可能由於變量的序列化時間過程或者序列化變量的傳輸過程過程而成為瓶頸,而Spark Scala中使用的默認的Java序列化方法通常是低效的,因此可以通過spark.serializer屬性為不同的數據類型實現特定的序列化方法(如Kryo)來優化這一過程。
三、累加器
使用累加器可以很簡便地對各個worker返回給driver的值進行聚合。只有driver能獲取到Accumulator的值(使用value方法),Task只能對其做增加操作(使用 +=)。
Spark入門3(累加器和廣播變量)