ZStack--級聯框架

 

雲中的資源相互都有關係。操做一個資源一般會引起連鎖反應;例如,當刪除一個集羣的時候,是很是合理地去刪除屬於該集羣的全部主機並中止全部在這些主機上運行的虛擬機。傳統的IaaS軟件要麼硬編碼連鎖反應,要麼簡單地禁止這些操做,例如,禁止用戶刪除有虛擬機運行的集羣。ZStack提供一個級聯框架,用以散佈原本只對一個資源的操做到全部相關的資源。資源能夠經過實現一個簡單的擴展點以加入級聯框架,使得資源的業務邏輯與框架解耦。網絡

 

動機架構

雲中的資源多多少少都彼此依賴;例如,一個主機是一個集羣的子資源,一個主存儲是一個集羣的兄弟資源,L3網絡是一個區域的後裔資源。資源之間的關係能夠被描述爲一個有向圖:框架

http://zstack.org/images/blogs/scalability/cascade1.png

 

上圖,咱們展現了ZStack的主要資源;不一樣的IaaS軟件可能使用不一樣的術語,上圖主要是想讓你有一個粗略的概念。由上圖所暗示的,當對資源進行操做時,不只僅是目標資源,相關資源也將受到影響;例如,當刪除一個區域時,比較理想的是屬於區域的集羣、主機、主存儲、L2網絡等資源也同時被刪除。爲了處理這個問題,IaaS軟件必須知足級聯(cascading)操做的需求。async

 

問題ide

大多數IaaS軟件不多考慮級聯操做。它們要麼硬編碼業務邏輯,例如,你須要顯式刪除一個將要被刪除賬戶的全部資源;要麼直接不容許這種操做,例如,當你試圖刪除一個IP地址範圍時,拋出一個錯誤信息「仍有VM使用在這個IP範圍中的IP」。這兩種方法都會帶來不少麻煩。對硬編碼而言,它使軟件不能靈活的添加新的資源,由於你必須修改現有的代碼來添加級聯操做,例如,修改刪除賬戶的代碼使得帳戶刪除時,新資源也被刪除。對於徹底沒有責任感的錯誤信息,用戶要麼去作無聊的工做,例如,在刪除一個IP範圍以前,手動刪除100個虛擬機;要麼摧毀現有的一切,而後從零開始,例如,從新部署整個雲。工具

避免誤操做不是藉口:有些人可能會聲稱不容許級聯刪除是慎重考慮的結果,由於用戶可能會誤操做,誤操做可能帶來災難性的後果;例如,錯誤地刪除區域會致使損失掉全部虛擬機。然而,這種說法只是一個錯誤的藉口,而且是一種爲用戶作決定的自做聰明。你能想象嗎,當你爲了刪除一個區域必須手動刪除10,000個虛擬機,由於軟件認爲你可能會作錯事,因此迫使你枯燥的重複10,000次任務確認?一個好的軟件應該爲用戶提供選擇,並讓他們作出決定。在咱們的例子中,IaaS軟件應該在進行到最後刪除以前警告用戶,還有10,000臺虛擬機在運行;但一旦用戶認可他們須要這麼作,軟件就應該這麼作。this

 

級聯框架編碼

ZStack經過一個級聯框架解決這一問題;顧名思義,級聯框架容許一個操做能從一個資源級聯到其餘資源。爲了解耦整個架構,這個級聯框架被做爲一個單獨的組件創造出來,資源能夠按意願加入框架。要加入框架,資源所須要作的所有事情就是實現一個擴展點CascadeExtensionPoint(在咱們的例子中AbstractAsyncCascadeExtension是一個實現CascadeExtensionPoint的類):spa

class VmCascadeExtension extends AbstractAsyncCascadeExtension {.net

    @Override

    public void asyncCascade(CascadeAction action, Completion completion) {

        if (/* this is from deleting Primary Storage*/) {

            /* delete VMs that have root volumes on the primary storage*/

        } else if (/*this is from deleting L3 Network*/) {

            /* stop VMs that have nics on the L3 network, and remove those nics */

        } else if (/* this is from deleting IP range*/) {

            /* stop VMs that have nics whose IP is in the IP range */

        } else if (/* this is from deleting host*/) {

            /* stop VMs that run on the host */

        }

 

        completion.success();

    }

 

    @Override

    public List<String> getEdgeNames() {

        return Arrays.asList(

                PrimaryStorageVO.class.getSimpleName(),

                L3NetworkVO.class.getSimpleName(),

                IpRangeVO.class.getSimpleName(),

                HostVO.class.getSimpleName()

        );

    }

 

    @Override

    public String getCascadeResourceName() {

        return VmInstanceVO.class.getSimpleName();

    }

 

    @Override

    public CascadeAction createActionForChildResource(CascadeAction action) {

        return convertContextToVmRelatedContext(action);

    }

}

getCascadeResourceName()方法返回該資源的名稱(VmInstance);getEdgeNames()方法返回一個和資源直接關聯的資源名列表,在咱們的例子中返回主存儲、L3網絡、IpRange和主機;因此若是刪除操做在這些edge resources或其上游資源(如區域)上發生時,該操做將被級聯至在getEdgeNames()方法中聲明瞭這些資源的擴展。級聯擴展能夠在asyncCascade() 中採起行動,並獲取必須的信息好比操做碼(如刪除),根發起者(如區域,下文將很快給出解釋),做爲操做來源的父發起者(如主機,將很快給出解釋)和操做上下文(例如,哪臺主機正在被刪除)。因爲資源的關係是一個可能有環路的有向圖,級聯框架將把圖壓扁成一棵樹,並把環路變爲分支。例如,刪除區域的操做將最終建立如下樹(一部分):

 

http://zstack.org/images/blogs/scalability/cascade2.png

注:如你所見,刪除區域操做將屢次級聯到虛擬機的級聯擴展;這是刻意的,由於級聯擴展一般依賴於父發起者去決定該採起什麼行動;在這個例子中,虛擬機的父發起者爲主存儲、主機、L3網絡和IP範圍;然而,對於不一樣的父發起者,擴展可能會採起不一樣的行動;例如,若是父發起者爲主存儲而且操做碼爲delete,該擴展將摧毀全部根雲盤在該主存儲的虛擬機;但若是父發起者是主機,擴展將會只中止在那臺主機上的虛擬機,由於這些虛擬機稍後就能夠在其餘主機上啓動。考慮到ZStack沒有產生衝突的級聯操做,例如,不會有一個操做致使虛擬機在路徑A啓動而在路徑B中止,因此級聯操做從不一樣路徑進行屢次延伸是沒有問題的。

當級聯一個操做時,該框架從該操做被應用的root issuer開始;在上述刪除區域的示例中,zone是根發起者;那麼框架將從根發起者遍歷樹,並調用擴展的createActionForChildResource()方法爲每一條路徑上的每個擴展建立上下文;一旦全部上下文建立成功,該框架將再次遍歷樹,不過是從葉子節點到根,並調用每一個擴展的asyncCascade()方法;一個擴展能夠依靠父發起者去決定應該作哪些操做,父發起者在getEdgeNames()方法中以資源名的方式聲明;例如,若是父發行者是主機,則中止虛擬機;若是父發行者是主存儲,則刪除虛擬機。

http://zstack.org/images/blogs/scalability/cascade3.png

這兩個階段的遍歷保證,一個操做(例如刪除)將只會被應用到根發起者,在全部下游資源都作完一些合適的操做後。例如,一個區域只在全部子孫資源都被刪除後才能被刪除。

因爲並非全部的操做都須要級聯,一個資源能夠在它須要的時候直接調用CascadeFacade.asyncCascade()

 

總結

在這篇文章中,咱們演示了ZStack的級聯框架,這是一個強大的工具,用於擴散操做而不須要硬編碼。ZStack用不少方式使用了它,除了咱們在文中提到的之外,一些操做,如卸載主存儲(這將中止將被卸載的集羣中的全部虛擬機),卸載L2網絡(這將中止將被卸載的集羣中的全部虛擬機)都是以這種方式實現的。有了它的幫助,管理員能夠快速嘗試不一樣的雲部署而無需擔憂不方便;你能夠只刪除你的部署的一部分並從新建立一個新的,而不須要僅由於你在一個設計錯誤的L2網絡上建立了許多虛擬機,就從新部署整個雲(舉個例子)。

相關文章
相關標籤/搜索