隨著spark的逐漸成熟完善, 越來越多的可配置引數被新增到spark中來, 本文試圖通過闡述這其中部分引數的工作原理和配置思路, 和大家一起**一下如何根據實際場合對spark進行配置優化。
由於篇幅較長,所以在這裡分篇組織,如果要看最新完整的網頁版內容,可以戳這裡:主要是便於更新內容
storage相關配置引數
spark.local.dir
這個看起來很簡單,就是spark用於寫中間資料,如rdd cache,shuffle,spill等資料的位置,那麼有什麼可以注意的呢。
首先,最基本的當然是我們可以配置多個路徑(用逗號分隔)到多個磁碟上增加整體io頻寬,這個大家都知道。
其次,目前的實現中,spark是通過對檔名採用hash演算法分布到多個路徑下的目錄中去,如果你的儲存裝置有快有慢,比如ssd+hdd混合使用,那麼你可以通過在ssd上配置更多的目錄路徑來增大它被spark使用的比例,從而更好地利用ssd的io頻寬能力。當然這只是一種變通的方法,終極解決方案還是應該像目前hdfs的實現方向一樣,讓spark能夠感知具體的儲存裝置型別,針對性的使用。
需要注意的是,在spark 1.0 以後,spark_local_dirs(standalone, mesos) or local_dirs (yarn)引數會覆蓋這個配置。比如spark on yarn的時候,spark executor的本地路徑依賴於yarn的配置,而不取決於這個引數。
spark.executor.memory
executor 記憶體的大小,和效能本身當然並沒有直接的關係,但是幾乎所有執行時效能相關的內容都或多或少間接和記憶體大小相關。這個引數最終會被設定到executor的jvm的heap尺寸上,對應的就是xmx和xms的值
理論上executor 記憶體當然是多多益善,但是實際受機器配置,以及執行環境,資源共享,jvm gc效率等因素的影響,還是有可能需要為它設定乙個合理的大小。多大算合理,要看實際情況
executor的記憶體基本上是executor內部所有任務共享的,而每個executor上可以支援的任務的數量取決於executor所管理的cpu core資源的多少,因此你需要了解每個任務的資料規模的大小,從而推算出每個executor大致需要多少記憶體即可滿足基本的需求。
如何知道每個任務所需記憶體的大小呢,這個很難統一的衡量,因為除了資料集本身的開銷,還包括演算法所需各種臨時記憶體空間的使用,而根據具體的**演算法等不同,臨時記憶體空間的開銷也不同。但是資料集本身的大小,對最終所需記憶體的大小還是有一定的參考意義的。
通常來說每個分割槽的資料集在記憶體中的大小,可能是其在磁碟上源資料大小的若干倍(不考慮源資料壓縮,j**a物件相對於原始裸資料也還要算上用於管理資料的資料結構的額外開銷),需要準確的知道大小的話,可以將rdd cache在記憶體中,從blockmanager的log輸出可以看到每個cache分割槽的大小(其實也是估算出來的,並不完全準確)
如: blockmanagerinfo: added rdd_0_1on disk on sr438:41134(size: 495.3 mb)
反過來說,如果你的executor的數量和記憶體大小受機器物理配置影響相對固定,那麼你就需要合理規劃每個分割槽任務的資料規模,例如採用更多的分割槽,用增加任務數量(進而需要更多的批次來運算所有的任務)的方式來減小每個任務所需處理的資料大小。
spark.storage.memoryfraction
如前面所說spark.executor.memory決定了每個executor可用記憶體的大小,而spark.storage.memoryfraction則決定了在這部分記憶體中有多少可以用於memory store管理rdd cache資料,剩下的記憶體用來保證任務執行時各種其它記憶體空間的需要。
spark.executor.memory預設值為0.6,官方文件建議這個比值不要超過jvm old gen區域的比值。這也很容易理解,因為rdd cache資料通常都是長期駐留記憶體的,理論上也就是說最終會被轉移到old gen區域(如果該rdd還沒有被刪除的話),如果這部分資料允許的尺寸太大,勢必把old gen區域佔滿,造成頻繁的full gc。
如何調整這個比值,取決於你的應用對資料的使用模式和資料的規模,粗略的來說,如果頻繁發生full gc,可以考慮降低這個比值,這樣rdd cache可用的記憶體空間減少(剩下的部分cache資料就需要通過disk store寫到磁碟上了),會帶來一定的效能損失,但是騰出更多的記憶體空間用於執行任務,減少full gc發生的次數,反而可能改善程式執行的整體效能
spark.streaming.blockinterval
這個引數用來設定spark streaming裡stream receiver生成block的時間間隔,預設為200ms。具體的行為表現是具體的receiver所接收的資料,每隔這裡設定的時間間隔,就從buffer中生成乙個streamblock放進佇列,等待進一步被儲存到blockmanager中供後續計算過程使用。理論上來說,為了每個streamingbatch 間隔裡的資料是均勻的,這個時間間隔當然應該能被batch的間隔時間長度所整除。總體來說,如果記憶體大小夠用,streaming的資料來得及處理,這個blockinterval時間間隔的影響不大,當然,如果資料cache level是memory+ser,即做了序列化處理,那麼blockinterval的大小會影響序列化後資料塊的大小,對於j**a 的gc的行為會有一些影響。
此外spark.streaming.blockqueuesize決定了在streamblock被儲存到blockmananger之前,佇列中最多可以容納多少個streamblock。預設為10,因為這個佇列poll的時間間隔是100ms,所以如果cpu不是特別繁忙的話,基本上應該沒有問題。
Spark引數詳解
spark shell 是spark 自帶的互動式 shell 程式,方便使用者進行互動式程式設計,使用者可以在該命令列下可以用scala編寫spark程式,適合學習測試時使用!示例spark shell可以攜帶引數 spark shell master local n 數字n表示在本地模擬n個執行...
spark 的相關配置
export hadoop home home hadoop hadoop 2.0.0 cdh4.5.0 export hadoop conf dir hadoop home etc hadoop spark executor instances 2 spark executor cores 1 s...
MySQL效能優化 I O相關配置引數
本文介紹innodb和myisam兩種儲存引擎的i o相關引數配置。1.innodb i o相關配置 innodb是一種事務型的儲存引擎,為了減少提交事務時產生的io開銷,innodb採用了寫日誌的方式,也就是在事務提交的時候會先寫入事務日誌中 而不是每次都把修改或者資料重新整理到資料檔案中,這樣做...