ODL(beryllium)控制器中OwnerShip與Netconf愛恨情仇

首先熟悉ODL的同學對於分片Leader應該很熟悉,而本節所講的OwnerShip不同於Raft選舉產生的Leader,Follower,Candidate。他提供了一個選舉的框架為任何應用提供了選舉功能(雖然目前的支援的選舉演算法很簡單)。這樣任何應用,都有應用的Owner角色,最常用的即OpenFlow1。3協議中所描述的。

Netconf叢集最近故障爆發,其根源利用了controller的ownership功用,急需梳理邏輯,所以有了這篇文章。

針對Netconf任一節點,其candidate和owner資訊都儲存在ODL DataStore 操作庫中的ownership分片中。

簡單介紹下candidate和owner的含義,如圖,A、B、C為三個控制器,都與裝置進行了連線,無ownership功能,任何針對設定的操作,可以透過任一控制器進行下發,而如果有了ownership功能,比如認為A控制器與裝置的連線中,裝置標記A為owner,則在進行處理請求時,則可以根據節點是否為指定節點的owner區別處理,增加了業務的靈活性。

ODL(beryllium)控制器中OwnerShip與Netconf愛恨情仇

owner資訊,可以透過URL http://localhost:8181/restconf/operational/entity-owners:entity-owners/ 獲取:

ODL(beryllium)控制器中OwnerShip與Netconf愛恨情仇

其中一個最關鍵的topology-nanager:

ODL(beryllium)控制器中OwnerShip與Netconf愛恨情仇

其中type和entity欄位透過程式碼中建立的Entity例項

new Entity(entityType, entityName)

ODL針對OwnerShip的使用,提供了兩個方便的介面,分別是註冊Candidate和ownershipChanged監聽事件

candidateRegistration = entityOwnershipService。registerCandidate(entity);

ownershipListenerRegistration = entityOwnershipService。registerListener(entityType, this);

以Netconf叢集為例,以topology-netcon為例介紹,介紹其ownership的邏輯?

觸發源為TopologyRoleChangeStrategy#onDataTreeChange

datastoreListenerRegistration = dataBroker。registerDataTreeChangeListener(

new DataTreeIdentifier<>(LogicalDatastoreType。CONFIGURATION, createTopologyId(entityType)。child(Node。class)), this);

ClusteredNetconfTopology#onSessionInitiated方法中建立了BaseTopologyManager(Actor),該Actor的preStart方法中

使用傳入的TopologyRoleChangeStrategy的註冊Candidate,

ODL(beryllium)控制器中OwnerShip與Netconf愛恨情仇

而TopologyRoleChangeStrategy#registerRoleCandidate

ODL(beryllium)控制器中OwnerShip與Netconf愛恨情仇

則使用到了上面介紹EntityOwnershipService的兩個主要介面

entityOwnershipService#registerCandidate

DistributedEntityOwnershipService#registerCandidate

在註冊真正邏輯中:

RegisterCandidateLocal registerCandidate = new RegisterCandidateLocal(entity);

查詢分片Actor

Future future = context。findLocalShardAsync(ENTITY_OWNERSHIP_SHARD_NAME);

將RegisterCandidateLocal傳送給enitty-ownership

至此程式碼邏輯來到EntityOwnershipShard中

ODL(beryllium)控制器中OwnerShip與Netconf愛恨情仇

構建MergeModification進行資料寫入,完成Entity與Candidate資料的寫入,注意寫入資料庫,會產生變更通知,會CandidateListChangeListener捕獲,傳送訊息(CandidateAdd)回EntityOwnershipShard(繞一圈),這裡則會進行選主判斷。

社群關於EntityOwnershipShard相關的內容,在後序Cardon版本改動較多,有幾點需要注意的是:

1。何時可能進行選主(有Candidate加入且entity無主時,或有Candidate移除且移除的正好是原主)

2。針對topology-manager這個entity,candidate社群後面版本是採用不刪除策略(原因是其將Akka的MemberRemoved和MemberExited以及MemberUnreachable都作為peerDown處理,這樣就無法區別節點是真的down了還是暫時的unreachable。考慮到這,採用一律不刪除策略。但member的資訊全部在記憶體中進行維護。所以peerDown的那個節點是無法選成主的。

選ownership時,預設提供2種策略:

LeastLooadedCandidateSelectionStrategy

FirstCandidateSelectionStrategy(預設)

Netconf的裝置節點的策略是根據節點連線狀態進行candidate隨時增刪:

在NetconfNodeManagerCallbac中

ODL(beryllium)控制器中OwnerShip與Netconf愛恨情仇

實現了註冊與登出動作

而透過netconf節點的連線狀態資訊,維護的一個重要引數即是isMaster,應該Netconf節點的狀態更新只在master節點是進行聚合更新入庫,其它節點只作記憶體狀態的更新。該master對應的即是topology-manager中的owner,那何時會進行該owner的通知(即ownershipchaged)

TopologyRoleChangeStrategy#ownershipChanged監聽後修改isMaster的值

附:節點上線流程

NetconfTopologyManagerCallback#onNodeCreate流程

ODL(beryllium)控制器中OwnerShip與Netconf愛恨情仇

此處會建立NodeManager,注意在建立NodeManger的時候,在其構造方法中

roleChangeStrategy。registerRoleCandidate((NodeManager) TypedActor。self());

使用NodeRoleChangeStrategy#regiserRoleCandidate,實現了Node的Candidate的註冊

ODL(beryllium)控制器中OwnerShip與Netconf愛恨情仇

程式繼續進行:

BaseNodeManager#onNodeCreated

NetconfNodeManagerCallback#onNodeCreate

注意由於本節點不是Master,所以並不會進行真正的寫庫,所以資訊只會快取,等待Master的觸發處理

而beryllium版本,不論是Netconf還是Controller中EntityOwnership都存在不小的問題,針對商用支援明顯不夠。