HCE:提升資源利用率的MapReduce框架

發表於2011-08-02

Hadoop系統提供了MapReduce計算框架的開源實現,像Yahoo!、Facebook、淘寶、中移動、百度、騰訊等公司都在藉助 Hadoop進行海量資料處理。Hadoop系統效能不僅取決於任務排程器的分配策略,還受到分配後實際任務執行效率的影響,任務執行常常涉及讀取、排序、歸併、壓縮、寫入等具體階段。

HCE計算框架是一個開源專案,旨在通過優化任務執行的各個階段,提升整個Hadoop系統的效率。與Hadoop Java框架相比,基於HCE框架的MapReduce任務最高可以節省超過30%的CPU資源使用。

Hadoop生態系統中的HCE計算框架

圖1 Hadoop生態系統中的HCE計算框架

 

圖1給出了HCE框架在Hadoop生態系統中所處的位置。對於OLTP系統來說,使用者通過Web前端生成相應請求,請求經過中介軟體處理,作為資料進入資料庫或者K-V儲存系統中,同時會產生日誌。OLTP系統產生的資料和日誌都會作為分析系統的輸入,對於搜尋引擎和廣告系統來說,每天的日誌會輕鬆超過TB。日誌和業務資料一般會存放到海量儲存系統HDFS檔案系統或者K-V儲存系統中,分散式計算框架MapReduce一般會基於儲存系統之上。每天會執行成千上萬的MapReduce作業進行海量資料處理,產生的結果會有三個去處:存放於海量儲存系統以備後續使用;匯入用於產生報表或分析的資料庫;作為OLTP系統的輸入,匯入線上儲存中。MapReduce作業一般由內部使用者通過Hadoop原生客戶端、Pig/DISQL語言客戶端或者 Hive資料倉儲三種方式進行提交,作業執行結果可以通過SQL客戶端查詢。

問題

越來越多的公司開始使用Hadoop及其周邊系統進行海量資料分析,Yahoo!和Facebook的Hadoop叢集節點數已經過萬,並且節點增長的趨勢不減,國內公司如騰訊和百度等也面臨著同樣的問題。不斷增長的業務需求和業務資料導致的叢集資源緊缺是叢集不斷擴容的主要原因,CPU資源(注:儲存資源緊缺的解決方案之一是開啟重量級的壓縮(如Facebook),這涉及CPU資源的使用)又是其中最為緊缺的。為了控制成本,優化叢集資源利用率勢在必行。

對於分散式計算層面,資源優化有兩個途徑:一是通過精細化的資源排程來保證全域性資源的最大化利用,這通常涉及合理的資源排程演算法和輕量級的資源隔離;二是通過優化計算任務和使用者程式來提升原有計算作業的資源使用率。HCE計算框架主要關注後者。

跨平臺、高擴充套件、通用介面的計算框架也帶來了額外開銷

分析Hadoop MapReduce計算框架,已有實現可以再做權衡。

MapReduce框架通過Java語言高效實現,保證了其跨平臺的相容性;不過國內網際網路公司一般都使用Intel x86平臺,相容性的優勢很難得以體現,因此可以選擇優於Java效能但不支援跨平臺的語言來實現MapReduce框架。

為了最大化可擴充套件性(Extensibility),Hadoop實現了多層級的資料處理流封裝,這使得Java框架在大資料處理時存在一些效能損耗,實際上可以實現更加直接的資料處理路徑來提升處理效率。

國內網際網路公司的工程師們大多使用C++進行功能開發或指令碼語言來處理文字,Java介面對於他們而言是比較麻煩的事情。Hadoop提供了 Streaming程式設計介面,允許使用者程式可以通過媒介——標準輸入輸出來和計算框架互動資料,也即繞開了語言的限制,因此很多使用者任務是通過 Streaming介面啟動的。Streaming介面的優勢在於支援多語言開發,而增加通用性帶來的是效能的損耗,即資料拷貝管道和Key切分開銷(大約2%~5%),並且不如原生態的語言介面更加適宜程式設計。

使用者程式在計算框架控制之外

MapReduce任務執行框架示意圖

圖2 MapReduce任務執行框架示意圖

 

除了框架的開銷,計算任務的資源佔用還包括使用者程式。如圖2所示,Hadoop Streaming和Pipes框架支援C++使用者開發MapReduce 應用程式,框架啟動使用者可執行程式,框架和使用者程式分別處於兩個程式,分別佔用資源。簡單的分析程式不會佔用太多的CPU資源,即使用者程式在整個計算任務執行時間中所佔比例不大,此時,優化計算框架會帶來比較可觀的收益;不過,對於複雜的分析程式而言,使用者程式所佔時間遠遠超過計算框架,此時,優化計算框架帶來的收益可能微乎其微。因此,節省叢集CPU資源離不開優化使用者程式。

優化使用者作業可以分為兩個層面,一是通過較高層次的統一入口讓使用者提交作業,例如使用資料倉儲Hive的使用者不會操作 Hadoop MapReduce的API,在Hive內部統一做優化,包括一些靜態或者動態方法,調整使用者作業引數,使任務利用最少資源高效執行;二是優化直接操作MapReduce API的使用者作業,當然Hive也屬於這個範疇。設想使用者作業或者資料倉儲是通過C++語言實現的,編譯由使用者實施,平臺僅僅通過介面呼叫使用者的可執行程式,那麼此時想要優化使用者程式會比較困難。有動態和靜態兩種優化方式:動態優化方式(注:詳情參見 Starfish: A Selftuning System for Big Data Analytics (CIDR’11))是在 MapReduce上新增一層,通過profiler和sampler等技術動態調整作業引數;靜態優化方式是讓使用者用編譯時依賴框架提供的標頭檔案和庫檔案,通過編譯優化技術提升使用者程式效能。

解決

HCE計算框架通過靜態優化計算框架和使用者程式來提升計算任務的CPU使用率。如圖2所示,將框架和使用者程式整合到一個程式,可以通過同一套編譯機制同時優化框架和使用者程式,Key-Values處理也處於同一個程式空間,不用藉助媒介(管道或套接字)來傳遞。HCE和Hadoop提供的使用者程式設計介面如表1所示。

MapReduce框架各使用者介面對比

表1 MapReduce框架各使用者介面對比

 

計算框架高效C++實現

HCE框架通過C++語言實現了MapReduce的資料處理邏輯,依託比Java效能更優的C++語言,可以在資料處理操作上獲得更佳的CPU利用率,同時也可以更加直接地呼叫Native Lib而非通過JNI(注:壓縮庫是Native實現,Hadoop通過JNI來呼叫壓縮方法,HCE壓縮在一個程式空間執行);此外,通過高效的編譯優化方法,例如ICC編譯器等,可以進一步挖掘框架的效能優勢。

HCE框架通過精簡的方式實現了MapReduce的資料處理流程,比較多層次的Java流式封裝,HCE的處理流程更加高效。

HCE框架提供了多種語言介面C++、Python等,方便了使用者程式設計,也節省了Streaming介面的額外開銷;同時HCE也提供完全相容原有Java Streaming的介面,即原有作業可以無縫遷移到HCE框架。

使用者程式靜態編譯優化

HCE框架採用的是靜態優化使用者程式的方式,動態優化交給上層的資料倉儲去做。對於那些CPU負載較重的使用者程式,HCE提供C++程式設計介面給使用者,使用者編譯本地程式需要依賴框架的標頭檔案和庫檔案,標頭檔案中內建瞭如SSE等優化程式碼,可以使得使用者程式在編譯時被優化。這種簡單的方式能夠使得使用者程式的執行效率大幅提升。

框架

HCE框架實現了Hadoop支援的功能元件,例如在C++空間中支援Text或者SequenceFile格式的RecordReader和 RecordWriter,也支援Gzip、Lzo、QuickLz、Lzma等4種壓縮格式。由於輸入檔案切分是在Hadoop Client實施的,所以Split方法還是在Java空間執行的;當然,使用者定義的Mapper和Reducer必須在C++空間實現,例如Hive想要基於HCE框架執行,那麼就必須實現C++版本的Mapper、Reducer等功能元件。

HCE框架資料處理流程圖

圖3 HCE框架資料處理流程圖

 

圖3展示了HCE框架的資料處理流程,可以看出HCE框架在C++空間高效實現了多個可擴充套件的功能模組,如RecordReader、 OutputCollector、Shuffle、ReduceInputReader、RecordWriter、Committer、 Partitioner、Mapper、Reducer、Combiner等,處理邏輯比Hadoop MapReduce更加緊湊高效。處於 Hadoop Java空間的MapRunner和ReduceRunner只是起到收集狀態資訊的作用。

HCE框架的效能提升主要集中在Map階段,大約超過40%。對於一般的MapReduce程式,相比Shuffle和Reduce階段,Map階段也是其資源佔用最多的階段,因為最終作業的輸出一般僅僅是輸入的10%,大量的資料處理是在Map階段完成的。

擴充

僅有基本的HCE框架是不夠的,因為大量已有作業是通過Streaming介面執行的,而且除C++開發介面之外,指令碼開發者也想使用對應語言的開發介面。幸運的是,所有指令碼語言都基於C開發,因此可以實現簡單的直譯器,將指令碼語言翻譯成C語言,最終執行的仍是HCE框架,而這個解釋開銷很小。當然,Streaming作業的額外開銷是不可避免了,不過基於HCE框架的Streaming作業可以利用框架的效能優勢獲得CPU利用率的提升,這對於輕量級作業收益仍然可觀。

圖4展示了Java Streaming、HCE、Streaming Over HCE和Python Over HCE四個框架的資料處理途徑。Java Streaming框架的資料處理仍然是在Java空間完成的,而HCE、Streaming Over HCE、 Python Over HCE框架的資料處理都在C++空間完成,Child JVM僅從HCE程式收集任務狀態資訊。

Streaming Over HCE和Python Over HCE框架示意圖

圖4 Streaming Over HCE和Python Over HCE框架示意圖

未來

MapReduce計算框架並不僅僅依賴於HDFS儲存系統,也可以基於其他儲存系統,例如Hypertable或者是其他的K-V系統。目前很多塊儲存系統或K-V系統都是C++語言實現的,想要在其上使用原生態的Hadoop MapReduce,就必須通過儲存系統的語言轉換介面(例如 Hypertable的Thrift)或者計算系統的轉換介面(例如Hadoop的AvroRPC等),問題是資料的序列化和反序列化難免帶來額外開銷。因此,基於HCE框架、非Java語言實現的儲存系統可以更加高效地支援Hadoop MapReduce計算,當然它們需要實現對應的Split、 RecordReader、RecordWriter和Committer等元件。

小結

HCE框架是Hadoop MapReduce框架的一個衍生品。依託HCE框架的高效本地處理機制,Hadoop作業可以最多節省30%的CPU 資源使用。此外,HCE提供了C++、Python等多種程式設計介面,並且保證了已有介面的向前相容;多種編譯優化技術也可以方便地應用到 MapReduce框架;最後,HCE通過編譯優化和內建直譯器等方式優化了使用者程式的執行。

相關文章