天天看點

Dryad 微軟的分布式運算架構

作者:劉旭晖 Raymond 轉載請注明出處

Email:colorant at 163.com

BLOG:http://blog.csdn.net/colorant/

Dryad的論文是微軟早在2007年就釋出的,Tez的核心思想來源于Dryad,差不多可以算是Dryad的開源實作吧。最近正好看到幾個有趣的項目是基于Tez實作的,于是順便追本溯源,學習了一下Dryad的理論基礎

== 目标問題 ==

Dryad的設計目标和當時先後出現的各種分布式運算架構一樣,是為了簡化大規模分布式程式設計的難度,提供給使用者一個簡單通用的分布式運算架構。和其它分布式運算架構解決的問題類似,不外乎就是使用者不需要考慮分布式運算所涉及的衆多繁瑣的問題,例如資源配置設定,并發排程,系統容錯等等,而隻需要關注核心運算邏輯。

== 核心思想 ==

按照官方定義,Dryad是一個通用的粗顆粒度的分布式計算和資源排程引擎,這裡所說的粗顆粒度,自然指的是針對批量資料進行處理的這種應用模式,當然批處理的粒度可大可小。

Dryad的核心資料模型由Vertex計算節點和Channel資料通道兩部分組成,使用者通過實作自定義的Vertex節點來執行定制的運算邏輯,而節點之間通過各種形式的資料通道傳輸資料,使用者的運算邏輯本身通常是順序執行的,而與分布式相關的邏輯則由Dryad架構來實作。

Dryad 微軟的分布式運算架構

如圖所示的是Dryad的系統架構框圖。Dryad的作業管理子產品JM在應用程式内部維護了一個基于DAG圖模型的計算節點依賴關系圖,作業管理子產品通過命名伺服器NS來擷取可用的伺服器清單,而後通過在這些伺服器上運作的守護程序Daemon來排程和執行計算節點Vertex。各個計算節點之間通過例如檔案,管道,網絡等形式的資料通道交換資料。

表面上看,從整體的概念來說,Dryad和MapReduce十分相似,所不同的就是MapReduce的使用者邏輯分為Map和Reduce兩個階段,在Dryad裡就隻有不分階段的Vertex一個概念。不過這一點恰恰就是它與MapReduce差別的關鍵。

從使用者使用的角度來說,MapReduce強制定義了Map和Reduce兩個階段,以及兩階段之間的資料輸入輸出格式。使用者程式通過套用這種模型來抽象自身的運算邏輯,帶來的好處是,簡化了使用者程式設計接口,降低程式設計難度,同時在這種模型的基礎上MapReduce架構可以自動完成各種排程優化和容錯處理工作。但是固定的程式設計模型自然也就在一定程度上限制了它的通用性,比如MR模型中所有的計算節點隻能接受統一格式的一組輸入資料,也隻能輸出一組資料,無論是否需要,使用者邏輯都必須由比對的Map和Reduce階段組成等等。

為了具備更大的通用性,Dryad從模型上不區分運算階段,從架構的角度上也不定義各個計算節點之間的資料交換格式,而是由具體的需要互相通訊的計算節點自己處理資料的格式相容問題。這樣做在一定程度上當然增加了使用者的程式設計難度,例如就可能需要針對具體計算節點的實作,編寫各種Channel資料通道的實作(當然可以通過實作一些通用的資料通道供使用者比對使用來解決部分問題)但是帶來的好處也是顯而易見的,就是更加靈活的程式設計模型。

使用者自定義排程拓撲圖

Dryad的核心特性之一,是允許使用者自己建構DAG排程拓撲圖,這個特性正是基于上述的原因而具備了實作的可能性和價值。MapReduce通過隐藏排程邏輯,簡化使用者程式設計。與之相反,Dryad期望通過适當增加的程式設計複雜度,暴露給使用者更加靈活的排程程式設計接口,讓使用者能夠更有效的優化運作邏輯,進而達到提升程式性能的目的。

Dryad運作庫實作了一個簡單的圖形描述語言(graph description language)用來建構排程拓撲圖,基本的操作原語和例子如下圖所示:

Dryad 微軟的分布式運算架構

建構一個具體的DAG的例子:

GraphBuilder XSet =moduleX^N;

GraphBuilder DSet =moduleD^N;

GraphBuilder MSet =moduleM^(N*4);

GraphBuilder SSet =moduleS^(N*4);

GraphBuilder YSet =moduleY^N;

GraphBuilder HSet =moduleH^1;

GraphBuilder XInputs= (ugriz1 >= XSet) || (neighbor >= XSet);

GraphBuilder YInputs= ugriz2 >= YSet;

GraphBuilder XToY =XSet >= DSet >> MSet >= SSet;

for (i = 0; i <N*4; ++i)

{ XToY = XToY || (SSet.GetVertex(i) >=YSet.GetVertex(i/4));}

GraphBuilder YToH =YSet >= HSet;

GraphBuilderHOutputs = HSet >= output;

GraphBuilder final =XInputs || YInputs || XToY || YToH || HOutputs;

上述代碼建構的DAG圖如下所示

Dryad 微軟的分布式運算架構

動态優化排程邏輯

Dryad的另一個特點是允許使用者動态的改變DAG排程拓撲圖,這是通過在計算節點中回報實際所處理的資料的相關資訊給作業管理子產品來實作的。之是以需要這麼做,是因為在很多情況下,最優的排程拓撲結構往往取決于實際的輸入資料,中間計算結果或者當時的運作環境,是以無法在程式設計的時候或者程式啟動的時候提前給出最優結構。

Dryad 微軟的分布式運算架構

例如圖示的一個Aggregation類型的操作,在實際執行的時候,我們通過資料的本地性資訊,可以動态的在原有的拓撲圖中(A->B)添加一層額外的計算節點(A->Z->B),比如将同一個機架上的資料彙總到同一個中間節點上作一次Aggregation,然後再送出給原拓撲圖中的後續節點處理。此外,也可以通過擷取實際的資料規模資訊,動态調整各個計算節點的并發度來适配程式實際運作情況等等。

當然,這些動态調整的代碼邏輯本身需要使用者根據自己的業務邏輯來實作,是以在一定程度上對使用者來說也是需要付出額外的努力的

== 實作 ==

Dryad的具體實作是否優化合理,實際性能如何,一方面由于它不是開源項目,另一方面我個人也不了解微軟的整套軟體體系,所有也就無從談起了,不過有空可以結合Tez這個開源版本的實作來具體分析一下。

== 思考 ==

Dryad的程式設計模型相對于MapReduce來說固然更加靈活,但是同時也帶來了更高的程式設計門檻。此外,因為資料流程和互動過程更加靈活多變,大概會有很多在MapReduce裡适用的各種架構級的優化工作或者通用的處理方法無法在Dryad的架構中應用,是以在易用性上勢必受到影響,而如果使用者代碼不能自己完成這些優化工作的話,應該也會對應用程式的實際性能産生一定的影響。這好比Hadoop2采用Yarn架構來支援更加通用的程式設計模型,但是要和MapReduce一樣,在Yarn的基礎上建構自己的模型相關的排程子產品,依然需要付出很大的努力,當然不能把Dryad的模型與Yarn簡單的資源排程模型直接對比,畢竟Dryad的程式設計模型還是與MapReduce一樣,屬于更高層次的概念。

在易用性友善,Dryad的DAG圖描述語言固然靈活,但在許多常用case的場合下也顯得瑣碎,比如并發度的設定等問題,許多情況下應該可以自動決定,各種常用處理流程的DAG拓撲圖也相對固定,是以也就需要一些高層封裝來簡化程式設計,比如建構在Dryad上的Nebula,使用者使用腳本語言的形式程式設計,Dryad的衆多使用細節和動态優化邏輯都被封裝在Nebula的方法操作中(例如Filter/Aggregate等),這點思想和Spark中RDD的方法封裝調用DAGScheduler作業排程相關操作的思想很接近,即暴露給使用者的接口是要做什麼,而不是要怎麼做。

另外微軟的DryadLINQ是LINQ在Dryad上的實作,這裡暴露給使用者的也是更高層的應用接口,前面提到的各種需要解決的問題同樣交給DryadLINQ的架構來處理。

從Paper的描述來看,當時的Dryad在并發,負載,HA等等大規模叢集需要考慮的問題方面的處理方式還很簡陋,當然經過這麼多年的發展,應該在這些方面會有改善和發展,目前的具體情況就不得而知了

Dryad的開源實作Tez所面臨的問題大概也是類似,Tez提供了各種通用的channel的實作(如針對MapReduce的應用模式的通道)來簡化使用者程式設計難度,但使用Tez依然比使用MapReduce要困難,Tez的穩定性和性能優化方面顯然也還有很長的路要走。而Stinger等基于Tez的上層架構顯然是希望在借助Tez在排程邏輯上提供的優化空間來提高性能的同時,通過更加進階的程式設計接口來保證易用性。

上一篇: CRAQ論文筆記

繼續閱讀