ODL(ODL-beryllium))中OwnerShip相关逻辑梳理

本文深入探讨了Netconf集群中Ownership机制的工作原理,详细解释了如何通过controller的ownership功能增强业务灵活性,以及Netconf设备节点如何根据连接状态动态调整候选者列表。
摘要由CSDN通过智能技术生成

Netconf集群最近故障爆发,其根源利用了controller的ownership功能,急需梳理逻辑,所以有了这篇文章。

针对Netconf任一节点,其candidate和owner信息都存储在ODL DataStore 操作库中的ownership分片中。

简单介绍下candidate和owner的含义,如图,A、B、C为三个控制器,都与设备进行了连接,无ownership功能,任何针对设置的操作,可以通过任一控制器进行下发,而如果有了ownership功能,比如认为A控制器与设备的连接中,设备标记A为owner,则在进行处理请求时,则可以根据节点是否为指定节点的owner区别处理,增加了业务的灵活性。

owner信息,可以通过URL http://localhost:8181/restconf/operational/entity-owners:entity-owners/ 获取:

{
    "entity-owners": {
        "entity-type": [
            {
                "type": "netconf-node/NSQdNGQB72wyDGHiR4NQ",
                "entity": [
                    {
                        "id": "/general-entity:entity[general-entity:name='NSQdNGQB72wyDGHiR4NQ']",
                        "owner": ""
                    }
                ]
            },
            {
                "type": "netconf-node/nww3XwdYZpeyfn7mC4hZ",
                "entity": [
                    {
                        "id": "/general-entity:entity[general-entity:name='nww3XwdYZpeyfn7mC4hZ']",
                        "candidate": [
                            {
                                "name": "member-1"
                            },
                            {
                                "name": "member-256"
                            },
                            {
                                "name": "member-2"
                            }
                        ],
                        "owner": "member-1"
                    }
                ]
            },
            {
                "type": "topology-netconf",
                "entity": [
                    {
                        "id": "/general-entity:entity[general-entity:name='topology-manager']",
                        "candidate": [
                            {
                                "name": "member-2"
                            }
                        ],
                        "owner": "member-2"
                    }
                ]
            }
        ]
    }
}

其中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,

而TopologyRoleChangeStrategy#registerRoleCandidate

则使用到了上面介绍EntityOwnershipService的两个主要接口

entityOwnershipService#registerCandidate

DistributedEntityOwnershipService#registerCandidate

在注册真正逻辑中:

RegisterCandidateLocal registerCandidate = new RegisterCandidateLocal(entity);

查询分片Actor

Future<ActorRef> future = context.findLocalShardAsync(ENTITY_OWNERSHIP_SHARD_NAME);

将RegisterCandidateLocal发送给enitty-ownership

 

至此代码逻辑来到EntityOwnershipShard中

    private void onRegisterCandidateLocal(RegisterCandidateLocal registerCandidate) {
        LOG.debug("{}: onRegisterCandidateLocal: {}", persistenceId(), registerCandidate);

        listenerSupport.setHasCandidateForEntity(registerCandidate.getEntity());

        NormalizedNode<?, ?> entityOwners = entityOwnersWithCandidate(registerCandidate.getEntity().getType(),
                registerCandidate.getEntity().getId(), localMemberName);
        commitCoordinator.commitModification(new MergeModification(ENTITY_OWNERS_PATH, entityOwners), this);

        getSender().tell(SuccessReply.INSTANCE, getSelf());
    }

构建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中

实现了注册与注销动作

 

而通过netconf节点的连接状态信息,维护的一个重要参数即是isMaster,应该Netconf节点的状态更新只在master节点是进行聚合更新入库,其它节点只作内存状态的更新。该master对应的即是topology-manager中的owner,那何时会进行该owner的通知(即ownershipchaged)

TopologyRoleChangeStrategy#ownershipChanged监听后修改isMaster的值

 

附:节点上线流程

NetconfTopologyManagerCallback#onNodeCreate流程

此处会创建NodeManager,注意在创建NodeManger的时候,在其构造方法中

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

使用NodeRoleChangeStrategy#regiserRoleCandidate,实现了Node的Candidate的注册

    @Override
    public void registerRoleCandidate(NodeListener electionCandidate) {
        LOG.debug("Registering role candidate type: {} , name: {}", entityType, entityName);
        this.ownershipCandidate = electionCandidate;
        try {
            if (candidateRegistration != null) {
                unregisterRoleCandidate();
            }
            candidateRegistration = entityOwnershipService.registerCandidate(entity);
            ownershipListenerRegistration = entityOwnershipService.registerListener(entityType, this);
        } catch (CandidateAlreadyRegisteredException e) {
            LOG.error("Candidate already registered for election", e);
            throw new IllegalStateException("Candidate already registered for election", e);
        }
    }

程序继续进行:

BaseNodeManager#onNodeCreated

NetconfNodeManagerCallback#onNodeCreate

注意由于本节点不是Master,所以并不会进行真正的写库,所以信息只会缓存,等待Master的触发处理

 

而beryllium版本,不论是Netconf还是Controller中EntityOwnership都存在不小的问题,针对商用支持明显不够。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值