存儲模塊
存儲級別 | 意義 |
NONE | 不會保存任何的數據 |
DISK_ONLY | 直接將RDD的Partition保存在該節點的Disk上 |
MEMORY_ONLY | 將RDD的Partition對應的原生的java object對象保存在JVM中。如果RDD太大,導致部分Partition無法保存在內存中的話,那么這些Partition將不會被緩存,在需要的時候,會被重新計算。這是默認的存儲級別。 |
MEMORY_ONLY_SER | 將RDD的Partition序列化后的對象(每一個Partition占用一個字節數組)存儲在JVM中。通常來說,這將比直接保存原始對象來說空間利用率更高。尤其是在使用fast serializer(快速序列化)時。但是在讀取的時候,由於需要進行反序列化,所以會占用一定量的CPU |
MEMORY_AND_DISK | 將RDD的partition反序列化后存儲在JVM中,如果它的RDD太大,導致它的部分Partition不能存儲在內存中,超出的Partition將會被保存在DISK上,需要的時候進行讀取。 |
MEMORY_AND_DISK_SER | 與MEMORY_ONLY_SER類似,但是會把超出內存的Partition保存在Disk上,而不是每次需要的時候重新計算。 |
DISK_ONLY_2 MEMORY_ONLY_2 MEMORY_ONLY_SER_2 MEMORY_AND_DISK_2 MEMORY_AND_DISK_SER_2 |
同上述的存儲級別,不同的是在其他節點上會保存一個相同的備份。也就是說,從集群角度來看的話,會有兩個備份。 |
OFF_HEAP(experimental) | 堆外內存。 將RDD的Partition序列化后存儲在堆外內存中(Tachyon),相比於MEMEORY_ONLY_SER,OFF_HEAP有以下幾個優勢:
|
存儲級別的選擇
spark不同的存儲級別是內存使用和CPU效率的折中。根據spark的官網建議,按照以下步驟來選擇合適的存儲級別:
- 如果RDD和默認的存儲級別有很好的契合,那么就無需任何的特殊設定。默認的存儲級別是CPU使用率最高的選項,也是運算能夠最快完成的選項。
- 如果需要減少內存的使用,可以使用MEMORY_ONLY_SER。但是這個時候需要選擇一個合適的序列化方式,具體的序列化方式可以參考http://spark.apache.org/docs/latest/tuning.html#data-serialization。需要在空間使用和反序列化時所需要的CPU中做一個合適的選擇。
- 盡量不要落到硬盤上,除非是計算邏輯非常的復雜,或者說是要從一個超大規模的數據集中過濾出一小繽紛數據。否則重新計算一個partition的速度可能和從硬盤上讀取的性能差不多(這里考慮到出錯的概率和寫硬盤的開銷,因此采用失敗重算要比讀硬盤持久化的數據要好)。
- 如果需要故障的快速恢復能力(比如使用spark來處理Web請求),那么可以考慮使用存儲級別的多副本機制。實際上所有的存儲級別都提供了Partition數據丟失時的重算機制,只不過有備份的話可以讓Application直接使用副本而無需等待重新計算丟失的Partition數據。
- 如果集群中有大量的內存或者有很多的運行任務,則選擇OFF_HEAP。OFF_HEAP具有以下的優勢
- 它是的多個Executor可以共享一個內存池
- 它顯著的減少了GC的開銷
- 緩存在內存中的數據即使是產生它的Executor異常退出了也不會丟失。