Hadoop和Spark的處理模型比較
概述
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進程中,可帶來以下好處:
- 任務啟動速度快,與之相反的是MapReduce Task進程的慢啟動速度,通常需要1s左右;
- 同節點上所有任務運行在一個進程中,有利于共享內存。這非常適合內存密集型任務,尤其對于那些需要加載大量詞典的應用程序,可大大節省內存。
- 同節點上所有任務可運行在一個JVM進程(Executor)中,且Executor所占資源可連續被多批任務使用,不會在運行部分任務后釋放掉,這避免了每個任務重復申請資源帶來的時間開銷,對于任務數目非常多的應用,可大大降低運行時間。與之對比的是MapReduce中的Task:每個Task單獨申請資源,用完后馬上釋放,不能被其他任務重用,盡管1.0支持JVM重用在一定程度上彌補了該問題,但2.0尚未支持該功能。
盡管Spark的過線程模型帶來了很多好處,但同樣存在不足,主要有:
-
由于同節點上所有任務運行在一個進程中,因此,會出現嚴重的資源爭用,難以細粒度控制每個任務占用資源。與之相反的是MapReduce,它允許用戶單獨為Map Task和Reduce Task設置不同的資源,進而細粒度控制任務占用資源量,有利于大作業的正常平穩運行。
下面簡要介紹MapReduce的多進程模型和Spark的多線程模型。
MapReduce多進程模型
- 每個Task運行在一個獨立的JVM進程中;
- 可單獨為不同類型的Task設置不同的資源量,目前支持內存和CPU兩種資源;
- 每個Task運行完后,將釋放所占用的資源,這些資源不能被其他Task復用,即使是同一個作業相同類型的Task。也就是說,每個Task都要經歷“申請資源—> 運行Task –> 釋放資源”的過程。
Spark多線程模型
- 每個節點上可以運行一個或多個Executor服務;
- 每個Executor配有一定數量的slot,表示該Executor中可以同時運行多少個ShuffleMapTask或者ResultTask;
- 每個Executor單獨運行在一個JVM進程中,每個Task則是運行在Executor中的一個線程;
- 同一個Executor內部的Task可共享內存,比如通過函數SparkContext#broadcast廣播的文件或者數據結構只會在每個Executor中加載一次,而不會像MapReduce那樣,每個Task加載一次;
- Executor一旦啟動后,將一直運行,且它的資源可以一直被Task復用,直到Spark程序運行完成后才釋放退出。
總結
總體上看,Spark采用的是經典的scheduler/workers模式,每個Spark應用程序運行的第一步是構建一個可重用的資源池,然后在這個資源池里運行所有的ShuffleMapTask和ResultTask(注意,盡管Spark編程方式十分靈活,不再局限于編寫Mapper和Reducer,但是在Spark引擎內部只用兩類Task便可表示出一個復雜的應用程序,即ShuffleMapTask和ResultTask),而MapReduce應用程序則不同,它不會構建一個可重用的資源池,而是讓每個Task動態申請資源,且運行完后馬上釋放資源。
聲明
本文轉載自董的博客: http://dongxicheng.org/framework-on-yarn/apache-spark-multi-threads-model/
作者:Dong,作者介紹: http://dongxicheng.org/about/