開發與維運

利用Flash閃存優化在Cosco基礎上的Spark Shuffle

Cosco是Facebook開發的一種服務,主要用於優化Spark Shuffle的性能,下文主要介紹用Flash閃存進一步優化Cosco。

一、Cosco

Cosco作為一種服務主要優化Spark Shuffle的性能,其優勢有:

  • 相較於原生的Spark Shuffle,能夠提升大約3倍的I/O性能,能夠有效降低磁盤的讀寫時間;
  • 引入Flash閃存以後Cosco能夠以更少的資源支撐更多的場景;
  • 引入Flash閃存之後有更大的可能降低Query的延遲;
  • 利用閃存優化Cosco的過程中用到的技術也可以用於Cosco之外的領域。

(一)Cosco產生背景

在Spark Shuffle中有Map Task和Reduce Task兩種Task,每個Map Task都會生成Output Files,然後根據Partition進行分組,決定將文件寫入本地磁盤還是分佈式文件系統中;所有Map Task執行完畢之後,Reduce Task就會去讀取Map Output Files中某個分區的數據,將其合併成某個大的Partition,在必要的時候還會進行排序。在上面的過程中,主要會存在兩個與I/O性能相關的問題:

(1)Write amplification problem

如下圖,這個問題也就說在最壞的情況下,同一個shuffle產生的文件會被寫入三次:

  • 第一次是在Map Task產生shuffle data的過程中如果內存不足,會先把Shuffle Data Spill到磁盤;
  • 第二次是寫入Map Output Files的過程;
  • 第三次是在Reduce Task中,如果進行sort的時候內存不夠,也會先Spill到磁盤。

image.png

(2)small IOs problem

在Spark Shuffle模型中,其I/O請求總數會有M x R個,而在生產中觀察到的I/O請求的size平均為200kb,相對於磁盤來說是非常小的,當整個作業的並行度提升之後會產生大量的小I/O請求,會急劇增加磁盤開銷,比如尋址時間等,從而導致Shuffle的性能變差。

image.png

基於上述問題,Cosco應運而生,其工作原理如下圖所示。相較於原生的Spark每個Task生成一個自己的Map Output Files,Cosco允許不同的Map Task將同一個Partition寫入到同一個內存緩存中,緩存到達一個閾值後,會將這部分數據Flush到分佈式文件系統的文件中。這種情況下,同一個Partition可能產生多個對應的Flush文件,等到Reduce Task執行的時候,只需要讀取HDFS系統中的文件即可,且文件的數據量在十幾M的級別,且文件數量遠小於之前的M x R數量級。因此,也就解決了小I/O的問題。

image.png

(二)用Flash替換內存緩衝

使用Flash來作為緩衝的話是通過追加寫的方式將Shuffle的數據寫入緩存中,之所以這麼做是因為閃存的可擦寫次數是有限的,追加寫可以延長閃存的壽命。閃存相對於內存存在著一定的延遲,但是總體而言這個延遲相對於整個Buffering是可以忽略不計的。

image.png

現在存在一個如何選擇的問題,比如在1GB的內存和每天能夠寫100GB的閃存之間讓我們用來部署集群,我們如何抉擇呢?這裡有一條經驗:1GB的內存和每天能夠寫100GB的閃存這兩種選擇的效果是一樣的,也就是說能夠支撐同樣的場景,但是內存比閃存需要更多的能耗。大家在部署集群的時候可以根據這條經驗來實際操作,選擇最優的配置。

(三)基於內存和閃存混合的緩存優化

基於內存和閃存混合的緩存優化技術主要有兩種:

  • 第一種是優先緩存內存,當內存達到一定閾值之後再Flush到閃存;
  • 第二種是利用partition加載速度不一樣的特性,對於加載速度快的partition用內存緩存,對於加載速度慢的partition用閃存緩存。

(1)第一種

第一種優化技術利用了Shuffle數據隨時間變化的特性,如下圖所示,我們發現Shuffle數據隨時間變化的統計中,峰值情況是佔據小部分的,於是我們用閃存來處理峰值情況,最終只用250GB的內存和讀寫25TB的閃存就能達到和原來一樣的效果,這樣就實現了Cosco的優勢,用更少的硬件資源來支撐了同樣的場景。這種混合存儲的優化技術比之純用內存有著更強的伸縮性,不會在某些特殊情況下造成系統崩潰。比如單純用內存的時候,如果出現內存不足就會崩潰,但是混合使用的時候就可以用閃存來處理異常情況,避免造成嚴重後果。

image.png

原來的Cosco集群有負載均衡的邏輯,更了獲得更好的效果,我們使用插件的方式將閃存的優化集成到負載均衡邏輯中,如下圖所示,引入一個閾值,當Shuffle Service內存不夠的時候,就會利用閾值來進行判斷是否將數據Flush到閃存中,這樣有兩個好處:

  • 實現簡單;
  • 便於對集群的性能做評估。

image.png

總的來說,第一種優化技術有如下特點:

  • 利用了Shuffle Data的分佈隨時間變化而變化的特性;
  • 採用了優先在內存內進行緩存的策略;
  • 巧妙的適配了原來的負載均衡邏輯。

(2)第二種

第二種是利用partition加載速度不一樣的特性,對於加載速度快的partition用內存緩存,對於加載速度慢的partition用閃存緩存。其策略主要是週期性的檢測Partition的加載速率,當速率小於某個閾值的時候,就使用閃存來緩存,當速率大於某個閾值的時候就使用內存來緩存。從下圖中可以看出,在實際生產中大多數Partition的加載速度是比較慢的,少部分加載速度比較快,加載速度比較慢的Partition佔用了少部分內存,造成內存的低使用率,因此我們用閃存來承載這些Partition,達到優化的目的。

image.png

二、未來工作

(一)低延遲查詢

引入閃存之後,我們可以讓Reduce Task直接從閃存中讀取緩存的數據,而不是從HDFS中的文件讀取數據,這樣子提高了數據的讀取速率。另外,在引入閃存之後,Shuffle的數據塊會變得更大,在Reduce端合併數據塊的次數會變少,讓整個查詢變得更快。

(二)性能提升

當前,Cosco為了保證容錯性,每一份Shuffle數據在寫入持久化的文件之前,會在不同節點的Shuffle Service保存兩份數據。如果我們引入閃存之後,因為閃存具有不易失性,這樣子在Shuffle Service在恢復之後可以從閃存恢復數據,減少了拷貝的副本。另外,在引入閃存之後,數據塊變得更大,在整個DFS上的讀寫也會更加高效。

三、性能評估技術

在上述的優化過程中,主要有如下四種類型的評估技術:

  • Discrete event simulation
  • Synthetic load generation on a test cluster
  • Shadow testing on a test cluster
  • Special canary in a production cluster

(1)Discrete event simulation

Discrete event simulation,也就是離散時間模擬的方法,是一種比較通用的評估方法。我們把每個Shuffle Data到達閃存的行為作為一個離散事件,記錄其到達的時間、此時閃存中寫入的數據總量以及最後閃存被Flush到DFS文件的數據總量。最終我們會得到如下圖所示統計表,包含了最終數據塊的大小和緩存的時間,由此我們就可以推算出數據塊的加載速率,也就是對應Partition的加載速率,並且把這個速率應用於上文中講到的第二種優化技術來進行決策。

image.png

(2)Special canary in a production cluster

如果我們要在一個生產環境中來驗證我們所進行的優化是否有效是比較困難的,因為在Cosco中一個Task可以與多個Shuffle Service進行通信,所以很難確定是因為加入了閃存提升了性能還是因為其他原因而提升。因此,我們將整個生產集群分成兩個互不干擾的子集群,然後進行對比試驗,比如對子集群A增加閃存優化,而子集群B保持原來的部署模式。之後,我們再對兩個子集群進行評估,就可以得知增加閃存優化是否起到了優化效果。


**關鍵詞:Cosco、Shuffle、FLash閃存、Spark、緩存優化、負載均衡
**

Leave a Reply

Your email address will not be published. Required fields are marked *