3C科技 娛樂遊戲 美食旅遊 時尚美妝 親子育兒 生活休閒 金融理財 健康運動 寰宇綜合

Zi 字媒體

2017-07-25T20:27:27+00:00
加入好友
作者簡介:陳曉帆,畢業於中山大學,博士,目前是深信服的技術專家,主要負責SDN/NFV,雲計算相關的預研工作。這份文檔主要是依據我和另外兩位小夥伴(hgl,zll)最近對ONOS的原理和代碼流程的分析整理而成。本文所有觀點僅代表作者個人觀點,與作者目前所在的公司無關。一、ONOS集群原理簡介ONOS是一個分散式的控制器,為了提高數據的讀寫效率,採用自實現的基於In-Memory的Key-Value數據存儲系統。針對實際的需要,不同的數據模型採用不同的數據一致性方法,即強一致性(strong consistency)和最終一致性(eventually consistency)。ONOS使用raft協議實現強一致性,使用Gossip協議實現最終一致性。ONOS在後面的版本中使用自研的基於raft協議的分散式存儲系統,ONOS使用的是基於Java實現的CopyCat版本,採用基於raft協議的分散式協同框架Atomix。為了提高數據的訪問效率,ONOS數據採用了分片存儲,在ONOS形成集群后,會在$ONOS_ROOT/下生產一個config文件夾,文件夾裡面有個cluster.json文件,裡面就是該ONOS的分片信息。ONOS啟動后,PartitionManager會根據分片信息來創建相應的目錄和文件,如$KARAF_ROOT/data/partitions/目錄下的文件夾及文件。二、Partition形成ONOS開啟后,PartitionManager會作為服務而被載入,載入時就會調用它的activate方法,它會根據分片信息(也就是本機存儲的Metadata)來創建partitions目錄下的信息,該文件夾會作為參數傳入StoragePartition的構造函數。StoragePartition是ONOS自實現的Key-Value存儲系統中Value的一種類型。PartitionManager接下來會調用第三方的框架去實現集群的管理。首先是創建相應的StoragePartitionClient,StoragePartitionServer來為集群的運行和管理做準備。程序會根據每個Partition的members的組成來決定相應的Server和Client的開啟。開啟Server:在開啟Server的過程中會在該Server的文件夾下創建幾個文件來輔助集群的運行,這幾個文件可以在$KARAF_ROOT/data/partitions/1(示例實驗是單個節點,所以只有一個partition)中看到,分別是該raft集群的:meta;log;snapshot。(ONOS的raft是實現是用了第三方的框架,該三個文件夾的具體作用,以及存儲了哪些東西,或是自己想要開發新的東西,都可以去Coptcat的官網查看具體說明)。下圖是CopycatServer相關文件,管理等的創建,具體可以參考CopycatServer的builder方法(可以單步調試看看ServerContext的創建過程):以上是進入ServerContext的創建過程,紅色框框即是Partition中存儲的文件,Copycat中都有對應的類對應。Raft的存儲和一致性就是通過日誌來實現的。Snapshot只要是輔助Log Compaction。開啟Client:DistributedClusterStore中沒有用到分散式原語,所以它只是保存單機的數據,不會被同步到其他機器上面。三、集群形成使用onos-form-cluter命令形成集群時,會調用ClusterManager的formCluster方法。這個方法會調用buildDefaultPartitions來創建Partitions。首先對node進行排序,設置框大小為partitionSize,每次在框裡面的node就是該Partition的member,框每次向右移動一個node,partition的命名從1開始依次遞增至n(n為集群中onos的總數)。formCluster方法會創建形成集群后的Metadata,並設置該數據,該數據會寫到硬碟的$ONOS_ROOT/config/cluster.json文件裡面,然後onos會刪除partitions文件夾和它裡面的內容,重新啟動后,onos會按照cluster.json文件裡面的信息來啟動onos,PartitionManager會根據Metadata裡面的partitions信息來創建partition。onos原始的形成集群流程如下:四、copycat日誌分析Java8提供了一種函數風格的非同步和事件驅動編程模型CompletableFuture。日誌是raft一致性演算法的核心,當命令提交到群集時,表示狀態更改的條目被寫入磁碟上的有序日誌中。日誌提供了實現持久性和一致性的機制。但是日誌在管理磁碟消費方面有特殊的挑戰。隨著命令逐漸寫入每個伺服器上的日誌中,日誌文件會消耗越來越多的磁碟空間。最終,每個伺服器上的磁碟空間會被日誌文件耗盡。raft一致性演算法的典型實現使用基於快照的方法來壓縮伺服器日誌。但是為了尋找更一致的性能,並且由於Copycat會話事件演算法的獨特需求,Copycat選擇了一種增量日誌壓縮演算法。Copycat的日誌被分成若干段,日誌的每個段都由磁碟上的一個文件(或內存塊)表示,每個段都包含一系列條目。一旦某個段變得完整,要麼取決於它的大小,要麼取決於條目的數量——日誌會滾到一個新的段中。每個段都有一個64位元組的標題,用來描述段的起始索引、時間戳、版本以及與日誌壓縮和恢復相關的其他信息。日誌中的每個條目都是用16位無符號長度、32位無符號偏移量和可選的64位術語編寫的。因為raft保證日誌中的術語是單調遞增的,所以這個術語只寫在某個給定段中的第一個條目中,所有後面的條目都繼承這個術語。當附加一個新項的條目時,該條目用新術語編寫,後面的條目繼承這個術語。五、強弱一致性分析ONOS提供了一些分散式數據結構(distributed primitive)來實現數據的強一致性和最終一致性存儲。應用開發者可以運用它們來開發相應的應用。強一致性是通過raft來實現,而弱一致性是通過事件樂觀非同步複製和anti-entropy(gossip)協議實現最終一致性。弱一致性如EventuallyConsistentMap用來存貯一個最終一致性map,當有節點的map值發生更新時,ONOS會廣播更新時間,其它的節點會通過比較時間戳來更新map的值。另外,當有新節點加入或有節點的數據突然丟失時,ONOS使用anti-entropy(gossip)協議來確保數據的最終一致性。這些狀態都是存儲在ONOS的內存裡面,所以當整個集群重新啟動時,數據會丟失。5.1 強一致性分散式存儲實例分析強一致性分散式存儲實例主要通過Network/config的API介面下發配置。配置信息保存在DistributedNetworkConfigStore中,該配置信息的保存使用了強一致性的分散式原語ConsistentMap。上圖第一個紅框是存儲配置信息ConsistentMap的聲明,第二個紅框是ConsistentMap的創建初始化,這個過程是在DistributedNetworkConfigStore的acvivate方法中進行的。這個過程調用storageService來創建我們的分散式數據結構。onos調用storageService服務來創建ConsistentMap,DefaultConsistentMapBuilder會提供一些方法來設置ConsistentMap的屬性,設置完了屬性之後,調用build方法來創建符合要求的ConsistentMap。數據如何映射到分片信息,Hasher是系統寫的對象映射PartitionId的介面,他的實現具體如下:具體的調用過程如下:Hasher是系統寫的對象映射PartitionId的介面,該介面決定了配置數據是如何映射到分片信息。5.2 弱一致性分析ONOS提供了一些分散式數據結構(distributed primitive)來實現數據的強一致性和最終一致性存儲。下面來討論一下ONOS的弱一致性。EventuallyConsistentMap是ONOS提供的用來實現弱一致性的分散式原語,它的實現類中提供了一系列參數來設置它的屬性,其中就有一個是設置該Map的值是否存儲在硬碟上,下面就流程做一個簡單的說明。以下例子是以網路拓撲為例。在DistributedTopologyStore的activate方法中,我們在創建存儲網路拓撲EventuallyConsistentMap的地方打上斷點。上圖第一個紅框是DistributedTopologyStore中EventuallyConsistentMap的聲明,第二個紅框是它的創建初始化。初始化時,會調用StorageService去創建,上圖紅框是要傳遞的參數persistentService,弱一致性的數據想要存儲在硬碟上面,必須通過該服務來創建相應的persistentMap或者persistentSet,該項服務會把數據存儲在由PersistenceManager提供的localDB中。上圖是EventuallyConsistentMap的創建過程。這個過程通過EventuallyConsistentMapbuilderImpl來控制,上面兩個紅框是我們今天重點關注的兩個屬性,一個就是我們的persistentService,還有一個就是設置是否將弱一致性數據保存在硬碟上面。EventuallyConsistentMapbuilderImpl提供了一些方法來設置屬性。屬性等設置完畢后,要調用build方法來創建EventuallyConsistentMap。最後通過EventuallyConsistentMapImpl去創建EventuallyConsistentMap,過程中會根據persistent(boolean)的值來決定是否調用persistentService這個服務。微信ID:S

本文由yidianzixun提供 原文連結

寫了 5860316篇文章,獲得 23313次喜歡
精彩推薦