? ? ? ? ? ?上一篇文章《ONOS高可用性和可擴展性實現初探》講到了ONOS系統架構在高可用、可擴展方面技術概況,提到了系統在分布式集群中怎樣保證數據的一致性。在數據終于一致性方面,ONOS採用了Gossip協議。這一部分的變化不大,而在強一致性方案的選擇方面則在不斷進行調整,其主要原因是分布式系統中強一致性對系統性能影響較大,并且現有的支持Paxos算法的實現不多。
本文承接上一篇提出的一個問題:ONOS為什么從開始使用ZooKeeper轉到Hazelcast,而終于選擇了Raft?是不是之前的選擇導致系統缺陷?亦或是在某些條件下無法滿足性能需求?且看下文為你慢慢道來。
在開始之前,先簡單的介紹一下ZooKeeper、Hazelcast和Raft,提供一些資料方便大家閱讀。?
????ZooKeeper,Hadoop生態系統中知名的分布式協作系統,?是Google的Chubby一個開源的實現,以C/S方式提供服務。應用場景包含配置維護、名字服務、分布式同步、組服務等?。client?與server(Follower/Leader)以Watch/Callback的方式進行交互,如圖1所看到的流程,可參考相關實例代碼。
?
??Hazelcast是一種內存數據網格(IMDG:?In-Memory?Data?Grid),網格中全部的節點是以Peer-to-Peer的方式組建集群,而且全部數據置于內存中以提高訪問性能[?Hadelcast架構介紹文檔]。Hazelcast提供了通用的數據結構(如Map,?List,?Queue等)和簡單的API進行數據操作,能夠直接引入jar包進行實現。能夠參考下文提供的相關實例代碼。
????Raft是為了解決Paxos算法的可讀性以及實現中拋棄一些細節形成的等價于Multi-Paxos算法。
它依賴于復制狀態機(Replicated?State?Machine),通過Replicated?Log將操作指令拷貝到各個節點,然后各節點在本地按同樣的順序運行同樣的命令,產生一致的狀態,圖2展示的是Raft狀態機。
?
依據上面的介紹,我們對這些方案有了初步的了解。如今如果我們是該系統的設計者,面臨對這三個方案技術方案進行選型。我們首先須要對這些方案進行對照,詳細如表1所看到的:
? ??從解決這個問題的角度來說,這三個方案都能夠解決ONOS在分布式一致性協作方面的問題,由于算法證明了這些方案都是“正確”的,除非實現上有Bug。
就算法的性能來說,差異不是非常大。Paxos算法(一種基于消息傳遞模型的一致性算法),它能保證在一個分布式數據庫系統中,假設各節點的初始狀態一致,每一個節點都運行同樣的操作序列,那么他們最后能得到一個一致的狀態。而Raft算法是等價于Multi-Paxos的算法,它主要解決的是Paxos晦澀的描寫敘述。以及Paxos的實現不能真正意義上的全然正確(實現上無法用公式證明)。這兩個算法盡管在實現上區別非常大,比方一致性實現中角色的定義,比方ZooKeeper中定義了Leader/Follower,Raft定義了Candidate/Leader/Follower角色,但其最核心的兩個關鍵活動。一個是選舉,其目的就是從分布的節點中選出Leader節點作為一致性的參考標桿,其他的Follower就成為“鏡像”。選舉僅僅有在初始化或有Leader退出/失效時才發生,在分布式系統中,節點失效出現的頻次非常低。并且選舉動作都是能夠在秒級別能完畢的。對系統的性能影響不大,不明顯,實際情況中與系統節點數的奇/偶性更相關。比方4個節點或6個節點選舉時間可能比13個節點選舉時間更長。另外一個是同步,其目的是通過復制數據/操作來達到全部的Follower都能產生一致的結果,僅僅要狀態有更新(比方寫操作)。那么就會觸發同步動作。同步意味著數據的復制以及消息的傳遞,從分布式架構來說,在讀寫IO方面這三種實現方式都相差點兒相同。
從這個角度來說,算法不是決定因素。
????大家可能會問:既然算法都差點兒相同了,就沒有必要在ONOS實現上大動手腳了。事實上。從上表我們能夠知道,當初選擇ZooKeeper作為Prototype?1的首選,主要是由于ZooKeeper成熟穩定,它在Hadoop生態圈是鼎鼎有名的高性能、分布式的應用協調服務的首選。
從ONOS的Prototype?1的實現來看,ZooKeeper確實滿足了分布式集中控制的需求,另外一方面,在事實上驗過程中,驗證系統的性能時,非常多數據是全局靜態的。比方Flow?Rule在實際的應用中是通過控制器以Lazy的方式下發到交換設備中,那么這些數據能夠提前在ZooKeeper中準備好,僅僅要實驗中不進行交換設備的動態添加或者移除,不會影響到總體性能。
也就是說,在Prototype?1中主要關注SDN的概念在ONOS上能發揮到何種程度。而不關心交換設備動態添加、刪除等場景。
????也就是說當有數據大量更新時。ZooKeeper則會出現性能問題,這主要由于ZooKeeper是以服務的形式來保障數據的一致性的。相對于ONOS來說,ZooKeeper是它的一個依賴子系統,因此在部署ONOS之外還要單獨部署ZooKeeper服務,如圖3所看到的的Client與Server之間的讀寫模型。
由于ZooKeeper中全部的數據都以ZNode表示,這些ZNode存儲在ZooKeeper的Server上,Client要讀的數據須要跨JVM訪問Server。
這樣ONOS?Instance就變成了zClient,那么當ONOS不同實例間須要同步數據時,須要通過TCP的方式從zServer上請求數據,這就導致了ONOS的性能會急劇下降,另外,ZooKeeper的zNode對數據大小有限制(zNode數據大小不能超過1M)。所以說ZooKeeper以服務的模式提供分布式一致性,對于ONOS有太多限制,而這時Hazelcast攻克了這些問題。
? ?Hazelcast是peer-to-peer的模式,直接應用其library以embedded的方式來實現,也就是每一個ONOS?Instance能夠作為一個peer,ONOS的業務數據就在同一個JVM中,如圖4所看到的(Hazelcast也能提供C/S模式的服務)。
更重要的是,Hazelcast是一個IMDG(In-Memory?Data?Grid),提供了非常方便的接口進行數據操作。在性能上得到了非常大的提升。可是,Hazelcast有個致命的問題,它還非常不成熟,在版本號升級中可能會不兼容。比方在ONOS1.1.0中依舊有非常多Hazelcast相關的Bug,這就意味著ONOS依賴于一個不成熟的庫,風險會非常大。實際上關鍵的因素是:Hazelcast能否正確地實現Paxos算法還是一個未知數。包含ZooKeeper的實現也不能被證明在算法上正確的。由于Paxos實在是太復雜了,能正確理解算法的人不多。更別談實現了。
有人會認為。無論如何Hazelcast會不斷改進的,假設有問題直接提交Bug給Hazelcast不就攻克了?或者說咱們也是做開源的,幫Hazelcast改進為什么不行?原因是當ONOS有了Hazelcast的Bug后就成了ONOS的Bug,解決這種Bug一方面是存在時間上的風險,另外一方面也取決于Hazelcast是否會由于支持ONOS而進行升級。萬一版本號升級,出現不兼容現象,那么已經部署的ONOS風險就更大了。把風險控制在自己能掌控的范圍之中才是ONOS社區首先考慮的。在這種情況下。Raft就成了不二之選了。
? ?Raft是Multi-Paxos的一種等價算法,事實上現能夠通過狀態機(一種容錯機制)、日志副本和一致性模塊(Raft協議)之間的協同完畢,這樣的簡單的模型抽象easy實現client和數據在同一個JVM上。以實現Embedded的方案,詳細架構如圖5所看到的。由于眼下在ONOS代碼中還沒有與Raft相關的實現,但我們能夠從ONOS項目的Sprint能夠看出,在ONOS中首先須要解決的是替換掉Hazelcast。而且保留可擴展的強一致性的存儲。另外,在維護設備的主從關系上。也須要Raft來實現,由于選舉服務是Raft必備的功能。上篇文章也提到過Intent須要強一致性來保障,Intent數據是通過分布式隊列發送,因此也須要支持基于Raft的數據庫服務。
到眼下為止。我們了解到了ONOS系統架構中的高可用方案演進的整個過程。
在系統POC初期,ONOS關注的是SDN概念上的驗證,選擇了ZooKeeper滿足了主要的需求。接下來發如今HA方面存在性能問題,為了保證與ZooKeeper有相同功能,并且性能優先的原則,選擇了Hazelcast,并且它確實做到了。而Hazelcast的問題在于它是一個沒有被廣泛驗證過、不成熟的、還在不斷改進的方案。ONOS不能依賴于這種一個方案,因此終于選擇了Raft。
盡管要在ONOS中全面實現Raft還須要時日,但在這個時候選擇Raft是正確的、合理的。
????ONOS已經將Raft的實現提上日程,請參考官方的任務列表,我們共同期待ONOS中的Raft實現吧!
個人覺得。ONOS在項目管理上做得很優秀,這也是ONOS脫穎而出的原因。
?假設您有興趣,也增加到ONOS的開源社區吧,關注ONOS的成長。一起推動SDN的發展!
參考資料
ZooKeeper官方站點:http://zookeeper.apache.org/
?ZooKeeper相關介紹:http://www.oschina.net/p/zookeeper
?ZooKeeper的clientKazoo:http://openinx.github.io/2014/06/07/learning-from-kazoo/
?ZooKeeper分布式鎖實例代碼:http://ifeve.com/zookeeper-lock/
?Hazelcast官方站點:http://hazelcast.org/
?Hadelcast架構介紹文檔:http://docs.hazelcast.org/docs/latest/manual/html/overview.html
版權聲明:本文博客原創文章,博客,未經同意,不得轉載。