許多機構將Spark與Alluxio一同創建,以提高工作效率和數據可管理性。

去哪兒最近在生產中部署了Alluxio,他們的Spark流媒體工作平均加速了15倍,在高峯時段加速了300倍。一些Spark工作會減速或無法完成,但是有了Alluxio,就可以很快完成這些工作。


計算速度提高10倍!Alluxio使Spark更高效



在這篇文章中,我們將研究Alluxio如何使Spark變得更加高效。Alluxio提高了Spark的工作效率,使Spark工作更具可預測性,並使多個Spark任務能夠共享來自內存的相同數據。


計算速度提高10倍!Alluxio使Spark更高效


Alluxio 和Spark Cache


在Alluxio內存中存儲Spark 數據幀非常簡單,只需要將數據幀作爲文件保存到Alluxio中。用Spark 數據幀編寫API將會使這個過程更簡單。數據幀通常用df.write.parquet()寫成parquet文件。將parquet寫入Alluxio後,可以通過執行sqlContext.read.parquet()從內存中讀取它。

爲了理解使用Spark Cache將數據幀儲存在Alluxio中的差異,我們進行了一些簡單的實驗。

我們選擇了一個Amazon EC2 r3.2xlarge系統(內存61 GB,8核)作爲實驗對象,並且使用了處於默認配置狀態的Spark 2.0.0和Alluxio 1.2.0。在節點上以獨立模式運行Spark和Alluxio。

實驗時,我們嘗試了不同的方法來緩存Spark 數據幀,並將數據幀保存在Alluxio中,測量了各種方法對實驗結果的影響。我們還改變了數據的大小,以得出數據大小如何影響實驗結果。

計算速度提高10倍!Alluxio使Spark更高效


保存數據幀

可以使用persist()API將Spark 數據幀“保存”或“緩存”在Spark內存中。persist()API可以將數據幀保存到不同的存儲介質。爲了達到實驗目的,我們使用了以下Spark存儲級別:

· MEMORY_ONLY:將Java對象存儲在Spark JVM內存中。

· MEMORY_ONLY_SER:將序列化的Java對象存儲在Spark JVM內存中。

· DISK_ONLY:將數據存儲在本地磁盤上。

下面是如何使用persist()API緩存數據幀的一個示例:

df.persist(MEMORY_ONLY)


另一種將數據幀保存到內存的方法是在Alluxio中將數據幀作爲文件寫入。Spark支持將數據幀寫爲幾種不同的文件格式,但在這些實驗中,我們將數據幀寫爲parquet文件。以下是如何將數據幀寫入Alluxio內存的示例:

df.write.parquet(alluxioFile)


計算速度提高10倍!Alluxio使Spark更高效


在Alluxio中查詢“已保存”的數據幀


在Spark或Alluxio中保存數據幀後,應用程序可以將其讀取到計算中。在實驗中,我們創建了一個帶有兩個浮動列的樣本數據幀,計算結果是兩個列的和。

當數據幀存儲在Alluxio中後,在Spark中讀取數據就像從Alluxio中讀取文件一樣簡單。下面是一個從Alluxio中讀取樣本數據幀的示例:

df = sqlContext.read.parquet(alluxioFile)

df.agg(sum("s1"), sum("s2")).show()


我們在Alluxio parquet文件的數據幀上以及不同的Spark持久存儲級別上執行了這個聚合操作,並測量了聚合所花的時間。下圖顯示了聚合時間。


計算速度提高10倍!Alluxio使Spark更高效



該圖顯示,對從Alluxio parquet文件中讀取的數據幀執行聚合操作可以極大地增加其可預測性和穩定性。然而,從Spark Cache中讀取數據幀時,小數據的聚合情況較好,但較大的數據嚴重影響了聚合速度。對於不同的Spark存儲級別,在輸入大約20GB的數據之後,聚合速度會顯著降低或增加。

對於較小的數據,使用Alluxio內存時數據幀聚合速度比使用Spark內存略慢,但隨着數據大小的增加,使用Alluxio讀取時效果明顯更好,因爲Alluxio會隨着數據大小線性擴展。由於Alluxio讀取數據時可以線性擴展,因此應用程序可以使用Alluxio以內存速度處理更大的數據。

計算速度提高10倍!Alluxio使Spark更高效


與Alluxio共享“已保存”的數據幀


Alluxio還能夠在內存中、甚至是不同的Spark任務中共享數據。將一個文件寫入Alluxio後,可以通過Alluxio的內存在不同的任務、背景甚至是框架之間共享此文件。因此,如果Alluxio中的數據幀經常被許多應用程序訪問,則所有應用程序都可以從內存中的Alluxio文件中讀取數據,而不必重新計算或從外部源獲取數據。

爲了演示Alluxio內存中共享功能的優勢,我們在與上述相同的環境中計算了相同的數據幀聚合時間。我們使用的數據大小爲50GB,在單獨的Spark應用程序中執行聚合操作,並測量執行計算所花費的時間。

在沒有Alluxio的情況下,Spark應用程序必須從數據源中讀取數據,在本實驗中數據源指的是本地SSD。但是,當把Spark和Alluxio一起使用時,意味着能直接從Alluxio內存中讀取數據。以下是聚合完成時間的實驗結果圖。


計算速度提高10倍!Alluxio使Spark更高效



如果沒有Alluxio,Spark必須再次從數據源讀取數據(本地SSD)。從Alluxio讀取數據更快,因爲數據是從內存中讀取的。使用Alluxio時的聚合速度是沒使用Alluxio時的2.5倍多。

在上述實驗中,數據源是本地SSD。但是,當數據幀的數據源較慢或不可預測時,那麼Alluxio的好處就更爲顯著了。例如,Amazon S3是一種用來存儲大量數據的當下非常流行的系統。以下是當數據幀的數據源來自Amazon S3時的實驗結果。


計算速度提高10倍!Alluxio使Spark更高效



該圖顯示了經過7次實驗的平均聚合完成時間。圖中的誤差線表示完成時間的最小和最大範圍。結果清楚地表明,Alluxio顯著提高了計算的平均速度。這是因爲使用Alluxio時,Spark可以直接從Alluxio內存中讀取數據幀,而不是再次從S3獲取數據。平均而言,Alluxio將數據幀的計算速度提高了10倍。

由於數據源來自Amazon S3,因此沒有Alluxio的Spark必須通過網絡獲取數據,這需要花的時間是無法預測的。從圖中的誤差條可以看出這種不確定性。沒有Alluxio,Spark完成工作的時間差異超過1100秒。使用Alluxio時,完成工作的時間差僅爲10秒。Alluxio將不可預測性降低了100倍以上!

由於S3網絡的不可預測性,沒有Alluxio 時,Spark的最長運行時間可能超過1700秒,幾乎是平均值的兩倍。另一方面,使用Alluxio時,Spark的最慢運行速度比平均時間約長6秒。從最慢運行速度來看,Alluxio將數據幀聚合速度提高了17倍以上。

相关文章