Spark: Spark和Hadoop的區別--關於資源使用

Apache Spark的高性能一定程度上取決於它採用的異步併發模型(這裏指server/driver端採用的模型),這與Hadoop 2.0(包括YARN和MapReduce)是一致的。Hadoop 2.0自己實現了類似Actor的異步併發模型,實現方式是epoll+狀態機,而Apache Spark則直接採用了開源軟件Akka,該軟件實現了Actor模型,性能非常高。儘管二者在server端採用了一致的併發模型,但在任務級別(特指Spark任務和MapReduce任務)上卻採用了不同的並行機制:Hadoop MapReduce採用了多進程模型,而Spark採用了多線程模型。

注意,本文的多進程和多線程,指的是同一個節點上多個任務的運行模式。無論是MapReduce和Spark,整體上看,都是多進程:MapReduce應用程序是由多個獨立的Task進程組成的;Spark應用程序的運行環境是由多個獨立的Executor進程構建的臨時資源池構成的。

多進程模型便於細粒度控制每個任務佔用的資源,但會消耗較多的啓動時間,不適合運行低延遲類型的作業,這是MapReduce廣爲詬病的原因之一。而多線程模型則相反,該模型使得Spark很適合運行低延遲類型的作業。總之,Spark同節點上的任務以多線程的方式運行在一個JVM進程中,可帶來以下好處:

1)任務啓動速度快,與之相反的是MapReduce Task進程的慢啓動速度,通常需要1s左右;

2)同節點上所有任務運行在一個進程中,有利於共享內存。這非常適合內存密集型任務,尤其對於那些需要加載大量詞典的應用程序,可大大節省內存。

3)同節點上所有任務可運行在一個JVM進程(Executor)中,且Executor所佔資源可連續被多批任務使用,不會在運行部分任務後釋放掉,這避免了每個任務重複申請資源帶來的時間開銷,對於任務數目非常多的應用,可大大降低運行時間。與之對比的是MapReduce中的Task:每個Task單獨申請資源,用完後馬上釋放,不能被其他任務重用,儘管1.0支持JVM重用在一定程度上彌補了該問題,但2.0尚未支持該功能。

儘管Spark的過線程模型帶來了很多好處,但同樣存在不足,主要有:

1)由於同節點上所有任務運行在一個進程中,因此,會出現嚴重的資源爭用,難以細粒度控制每個任務佔用資源。與之相反的是MapReduce,它允許用戶單獨爲Map Task和Reduce Task設置不同的資源,進而細粒度控制任務佔用資源量,有利於大作業的正常平穩運行。

下面簡要介紹MapReduce的多進程模型和Spark的多線程模型。

(1) MapReduce多進程模型

1) 每個Task運行在一個獨立的JVM進程中;

2)  可單獨爲不同類型的Task設置不同的資源量,目前支持內存和CPU兩種資源;

3)   每個Task運行完後,將釋放所佔用的資源,這些資源不能被其他Task複用,即使是同一個作業相同類型的Task。也就是說,每個Task都要經歷“申請資源—> 運行Task –> 釋放資源”的過程。

(2) Spark多線程模型

1)  每個節點上可以運行一個或多個Executor服務;

2)  每個Executor配有一定數量的slot,表示該Executor中可以同時運行多少個ShuffleMapTask或者ReduceTask;

3)  每個Executor單獨運行在一個JVM進程中,每個Task則是運行在Executor中的一個線程;

4)  同一個Executor內部的Task可共享內存,比如通過函數SparkContext#broadcast廣播的文件或者數據結構只會在每個Executor中加載一次,而不會像MapReduce那樣,每個Task加載一次;

5)  Executor一旦啓動後,將一直運行,且它的資源可以一直被Task複用,直到Spark程序運行完成後才釋放退出。

總體上看,Spark採用的是經典的scheduler/workers模式,每個Spark應用程序運行的第一步是構建一個可重用的資源池,然後在這個資源池裏運行所有的ShuffleMapTask和ReduceTask(注意,儘管Spark編程方式十分靈活,不再侷限於編寫Mapper和Reducer,但是在Spark引擎內部只用兩類Task便可表示出一個複雜的應用程序,即ShuffleMapTask和ReduceTask),而MapReduce應用程序則不同,它不會構建一個可重用的資源池,而是讓每個Task動態申請資源,且運行完後馬上釋放資源。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章