對多次使用的rdd進行持久化
當你在spark**中多次對乙個rdd做了運算元操作後,恭喜,你已經實現spark作業第一步的優化了,也就是盡可能復用rdd。此時就該在這個基礎之上,進行第二步優化了,也就是要保證對乙個rdd執行多次運算元操作時,這個rdd本身僅僅被計算一次。
spark中對於乙個rdd執行多次運算元的預設原理是這樣的:每次你對乙個rdd執行乙個運算元操作時,都會重新從源頭處計算一遍,計算出那個rdd來,然後再對這個rdd執行你的運算元操作。
這種方式的效能是很差的。
因此對於這種情況,我們的建議是:對多次使用的rdd進行持久化。此時spark就會根據你的持久化策略,將rdd中的資料儲存到記憶體或者磁碟中。以後每次對這個rdd進行運算元操作時,都會直接從記憶體或磁碟中提取持久化的rdd資料,然後執行運算元,而不會從源頭處重新計算一遍這個rdd,再執行運算元操作。
對多次使用的rdd進行持久化的**示例
// 如果要對乙個rdd進行持久化,只要對這個rdd呼叫cache()和persist()即可。
// 正確的做法。
// cache()方法表示:使用非序列化的方式將rdd中的資料全部嘗試持久化到記憶體中。
// 此時再對rdd1執行兩次運算元操作時,只有在第一次執行map運算元時,才會將這個rdd1從源頭處計算一次。
// 第二次執行reduce運算元時,就會直接從記憶體中提取資料進行計算,不會重複計算乙個rdd。
val rdd1 = sc.textfile("hdfs:").cache()
rdd1.map(...)
rdd1.reduce(...)
// persist()方法表示:手動選擇持久化級別,並使用指定的方式進行持久化。
// 比如說,storagelevel.memory_and_disk_ser表示,記憶體充足時優先持久化到記憶體中,記憶體不充足時持久化到磁碟檔案中。
// 而且其中的_ser字尾表示,使用序列化的方式來儲存rdd資料,此時rdd中的每個partition都會序列化成乙個大的位元組陣列,然後再持久化到記憶體或磁碟中。
// 序列化的方式可以減少持久化的資料對記憶體/磁碟的佔用量,進而避免記憶體被持久化資料占用過多,從而發生頻繁gc。
val rdd1 = sc.textfile("hdfs:").persist(storagelevel.memory_and_disk_ser)
rdd1.map(...)
rdd1.reduce(...)
對於persist()方法而言,我們可以根據不同的業務場景選擇不同的持久化級別。
spark的持久化級別
如何選擇一種最合適的持久化策略:
Linux curses 總結三(對鍵盤的操作)
cbreak cooked 預處理模式 curses程式的控制模式函式 curses程式的鍵盤操作函式 小栗子curses程式的鍵盤操作是對底層的簡單封裝介面 cooked 標準輸入模式,處理的是一行資料,每次遇到 r 換行符 才會把輸入到快取的資料傳遞給程式,這種情況下鍵盤輸入特殊字元可以被處理 ...
朝花夕拾《精通CSS》三 對一些標籤元素的使用
翻出我4年前看的 精通css 一書,可惜當初沒有整理讀書筆記的習慣,最近又很少寫前端,遂很多東西 知識點遺忘了,恰且現在 css 也有些變化和進步,遂一起打包整理,輸出成幾篇 blog 系列,以犒自己。1 字型 字型分serif 有襯線 和sans serif 無襯線 sans serif 被認為是...
QTP關鍵技術(三) 對同步點的理解
1 qtp的指令碼語言是vbscript,指令碼在執行的時候,執行語句之間的時間間隔是固定的,也就是說指令碼在執行完當前的語句之後,等待固定的時間間隔後開始執行下一條語句 2 問題 假設後一條語句的輸入是前一條語句的輸出,如果前一條語句還沒有執行完,這時候將要導致錯誤的發生!3 措施 加入同步點 加...