spark性能優化----緩存清除


spark是一款優秀的框架,計算性能相當優異,已經發展成大數據主流計算引擎,在spark開發過程中有很多優化的點。其中去除重復計算是非常重要的。一般操作調用cache/persist,來緩存中間結果,避免重復計算。其中cache是persist的一個特列(cache相當於persist())。persist擁以下幾個級別的緩存:

NONE  默認配置(不緩存)
DISK_ONLY  數據緩存到磁盤,特點讀寫特別慢,內存占用比較少
DISK_ONLY_2 數據緩存到磁盤兩份,特點讀寫比較慢(比DISK_ONLY讀寫快,穩定性好)
MEMORY_ONLY 數據緩存到內存和cache()功能之一,讀寫最快但是內存消耗比較大
MEMORY_ONLY_2 數據緩存到內存,並且緩存兩份,特點讀寫速度快內存消耗很大,穩定性比較好,適用於集群不穩定,緩存的數據計算過程比較復雜的情況
MEMORY_ONLY_SER 數據緩存到內存並序列化,一般可以配合kyro一起使用,讀寫過程需要序列化和反序列化,讀寫速度比Memory_only慢,但是數列化后的數據占用內存比較少
MEMORY_ONLY_SER_2 數據序列化后存兩份到內存,讀寫過程同上,特點內存占用量較大,適用於不太穩定的集群
MEMORY_AND_DISK 數據緩存到內存,內存不夠溢寫到磁盤,一般情況這個使用的比較多一點,是讀寫性能和數據空間的平衡點
MEMORY_AND_DISK_2 數據緩存兩份到內存,內存不夠溢寫到磁盤,一般情況這個使用的比較多一點,是讀寫性能和數據空間的平衡點
MEMORY_AND_DISK_SER 數據序列化后緩存到內存,內存不夠溢寫到磁盤
MEMORY_AND_DISK_SER_2數據序列化后緩存2份到內存,內存不夠溢寫到磁盤
 
OFF_HEAP 使用堆外內存緩存數據可以配合tachyon一起使用

這些緩存各有特點,視具體情況使用不同級別。
可能有很多初學者都在困惑一個問題,到底什么時候該釋放這些內存。比較官方的說法是在action之后釋放這些緩存比較科學。但是更加具體一點是在shuffle之后就可以釋放掉,或者在數據又一次被序列化以后,上一個cache可以釋放掉。這個實驗可以在單機版自行測試。

在很多場景下,程序員自己緩存的數據可以通過unpersist手動去除。但是在有些場景可能會忘掉去除緩存,或者引用在shuffle/action之后丟失了,就沒法調用unpersist方法。在一些框架內部(比如graphx)為達到優化目的會調用persist卻沒有釋放(因為提前釋放cache將無效)。這些情況緩存的數據無法釋放,內存空間不足時系統按照最久最近未使用算法去除掉一部分緩存,后續有在用到再重新計算。遇到這種情況性能就會直線下降。

其實spark框架還提供另外一個api供開發者調sc.getPersistentRDDs,這個方法返回所有這在被緩存的RDD數據,開發者可以根據自己需求去除掉不需要的緩存,以下是實現方法:

def unpersistUnuse(rddString: Set[String], sc: SparkContext) = { var persistRdds = sc.getPersistentRDDs persistRdds.foreach(truple => { val xx = truple._2.toString() val ddd = rddString if (!rddString.contains(truple._2.toString())) { truple._2.unpersist() } }) }

入參rddString是不能清除緩存的RDD.toString之后的字符串集合。調用完之后不需要的緩存就被清除掉。 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM