我們在前幾回又談到了規模可擴充性、談到了雲端計算平臺,也說明了,我們透過雲端計算平臺可以獲得的好處之一,便是規模可擴充性,但這個規模可擴充性和雲端的關係並不是必然的,也就是說,上了「雲端」不意謂著必定具規模可擴充性有關。

想要得到規模可擴充性,可能可以自行在IaaS上建造基礎的設施,或是透過PaaS上提供的機制來達成。有了規模可擴充性,可以隨需要而投入更多的計算資源,使得服務的規模隨之擴大。

以「計算」來說,在過去幾年以來,Hadoop的MapReduce計算平臺獲得了廣泛採用,也便利了許多開發團隊在計算、處理大規模海量資料時的工作。不過,即使如此,MapReduce仍有些許值得改進之處,在前些日子,有個名為Spark的平臺問世,而在最近,Spark也邁進了正式產品的階段,這意謂著在MapReduce之外,開發者多了一個新的選擇,而Spark的出現,也正是瞄準了一些MapReduce在應用上的限制而來的。

在這一回中,就讓我們簡單、概略地介紹一下 Spark。

Hadoop出現勁敵,與之相容,而且執行速度更快

不意外的,Spark也是著名的Apache開放原始碼專案之一,就和Hadoop上的MapReduce一樣,同樣是個具規模可擴充性的分散式計算平臺,而且,試著在一些面向上,提供優於Hadoop MapReduce的方案。

在大規模資料的計算、分析上,排序作業的處理時間,一直是個重要的指標。而在著名的Daytona Gay Sort競賽中,針對102.5 TB的資料量排序,Hadoop MapReduce的記錄是以2,100個計算節點,在72分鐘內完成排序的計算工作。而Spark最近則以十分之一的206計算節點數,在23分鐘內即完成了 100TB 資料量的排序。

這意謂著,Spark可以做到用十分之一的計算節點數量,卻只用三分之一的時間,就完成了相同規模的計算工作。從這個結果,我們可以看出Spark在未來的應用潛力。

Spark是什麼呢?簡單來說,它是一個快速的群集計算系統,它具備了幾個特色,首先,它和Apache Hadoop相容,這意思是說,它支援了Hadoop所支援的儲存系統,包括HDFS、S3、……等等。這些儲存系統,可以說是當前在處理大規模資料時,開發者所慣以使用的儲存系統了,因此,Spark 同樣立足於這些儲存系統之上。

此外,重要的是,Spark在幾個面向上,改進了Hadoop用的傳統MapReduce。

Spark透過一個以分散式記憶體為主的計算模型,來大幅提高計算效率,因此在100TB級的資料排序上,Spark展現了它的計算高效率。另一方面,Spark 提供了豐富而且易用的API,這使得開發者在利用程表述計算邏輯時,得以獲得API層次的支持,如此,一來更容易撰寫程式,二來也能有效降低所需的程式碼行數。

而且,開發者可以利用三種程式語言來開發Spark 之上的應用程式,包括了Scala、Python,以及 Java,這代表著開發者可以視應用的情境,來決定使用何種語言來撰寫Spark程式,更能彈性的符合開發時的需求。

執行時,可在本地端、雲端,或是自身所管理的群集中

目前,運行Spark應用程式的方式,有三種選項,你可以選擇在本地端的機器上執行,這只需要引入 Spark 的程式庫就能辦到。

針對更大型規模的計算工作,本地機器的計算能力恐怕難以滿足,此時,你可以選擇將Spark程式送至AWS的EC2平臺上執行,這使得你可以權衡費用預算,以及需要完成計算工作的時間限制,來決定究竟投入多少EC2上的計算資源,來建立你的Spark 群集。

Spark當中,現在已經附上了將程式送至EC2執行的script,所以,你可以輕易在EC2上運行你所開發的Spark程式。當然,對於某些具有龐大資源的組織來說,他們可能會考慮不送至公開的雲端平臺上來執行他們的程式,因此,Spark也允許你透過諸如Mesos、YARN等來管理自有的群集,並且在自有的群集上運行Spark程式。

所採用的關鍵核心技術RDD,相當獨特

Spark的核心支柱,乃是一個名為RDD(Resilient Distributed Dataset)的分散式計算模型,而其諸多優勢,主要也是源自於RDD本身的特性。

所謂的RDD,乃是由AMPLab實驗室所提出的概念,類似一種分散式的記憶體。而且,RDD是一種可跨群集(cluster)被使用、可儲存於主記憶體中的immutable的物件集合。這裡所謂的immutable物件,乃是指在被產生之後,其狀態便無法被修改的物件。

在RDD之上,可以施加兩類型的操作,一種稱為「轉換(Transformation)」,另一種則為「動作(Action)」。其中,所謂的「轉換」,其操作結果為新的RDD,意即其作用在於將RDD再轉換生成另一個RDD。而所謂的「動作」,則是在RDD之上進行計算之後,將其結果返回 Spark 的驅動程序,或寫至檔案系統。

換句話說,「轉換」的結果,是在RDD的計算世界中,而「動作」的結果,則是輸出至此世界之外。所以,當我們產生RDD物件進到計算世界中之後,可以對其施加多次的「轉換」,當一旦於其上執行「動作」之後,就會從此計算世界中,得到真正可使用的計算結果了。

RDD本身有個Lineage機制,也就是說,它會維持每個RDD與其父代RDD reference之間的關聯,以及究竟是透過什麼操作,才由父代RDD得到該RDD的資訊。

正如你所知的,RDD透過「轉換」操作可以得出新的轉換,但Spark會延遲這個「轉換」動作的發生時間點,它並不會馬上執行,而是等到的確需要得出某個值時,才會基於所有的RDD關係來執行轉換。

也正因為有了Lineage機制,以及RDD本身先天的immutable特性,使得它具備了容錯的特性,即使特定節點損毀,儲存於其上的RDD也能重新計算得出,因而避免了特定節點損毀就無法運作的問題。

不論是「轉換」或是「動作」,基本上,都是以函數式(functional)的形式來表述。因此,正如前一回中所提到的,這種方式很適合「分而治之」的解題方式。

然而,和Hadoop MapReduce不同的是,Spark提供了遠多於map及reduce的操作,這使得開發者有更多的操作可以運用(即更豐富的 API),並且能夠用更簡潔的程式碼來表示計算邏輯。

以RDD這種以儲存在計憶體為主的分散式物件來做計算,避免了Hadoop MapReduce在工作任務間必須透過檔案系統來溝通的效率問題。大家都能輕易的明白,一旦涉及將計算資料儲存在檔案系統,就必須面臨磁碟I/O的緩慢效能,以及將資料做序列化、解序列化的計算負擔。Spark因為以RDD為基礎,得以帶來大幅度的計算效能改善。

從本文的簡單介紹中,不難理解,以RDD為核心的Spark,除了繼續在函數式的計算道路上繼續邁進,讓程式編寫更為容易,也讓運行效能大大提升,而這正是Spark能快速嶄露頭角的重要原因。

專欄作者

熱門新聞

Advertisement