Search in sources :

Example 16 with ControllerNode

use of org.onosproject.cluster.ControllerNode in project onos by opennetworkinglab.

the class MastershipManager method distributeOrphanedDevices.

/**
 * Uses the set of orphaned devices to even out the load among the controllers.
 *
 * @param controllerDevices controller nodes to devices map
 * @param orphanedDevices   set of orphaned devices without an active master
 * @param futures           list of completable future to track the progress of the balancing operation
 */
private void distributeOrphanedDevices(Map<ControllerNode, Set<DeviceId>> controllerDevices, Set<DeviceId> orphanedDevices, List<CompletableFuture<Void>> futures) {
    // Now re-distribute the orphaned devices into buckets until they are roughly even.
    while (!orphanedDevices.isEmpty()) {
        // Iterate over the buckets and find the smallest bucket.
        ControllerNode smallest = findBucket(true, controllerDevices);
        changeMastership(smallest, controllerDevices.get(smallest), orphanedDevices, 1, futures);
    }
}
Also used : ControllerNode(org.onosproject.cluster.ControllerNode)

Example 17 with ControllerNode

use of org.onosproject.cluster.ControllerNode in project onos by opennetworkinglab.

the class MastershipManager method balanceRolesInRegion.

/**
 * Balances the nodes in specified region.
 *
 * @param region               region in which nodes are to be balanced
 * @param allControllerDevices controller nodes to devices map
 * @return controller nodes that were balanced
 */
private Map<ControllerNode, Set<DeviceId>> balanceRolesInRegion(Region region, Map<ControllerNode, Set<DeviceId>> allControllerDevices) {
    // Retrieve all devices associated with specified region
    Set<DeviceId> devicesInRegion = regionService.getRegionDevices(region.id());
    log.info("Region {} has {} devices.", region.id(), devicesInRegion.size());
    if (devicesInRegion.isEmpty()) {
        // no devices in this region, so nothing to balance.
        return new HashMap<>();
    }
    List<Set<NodeId>> mastersList = region.masters();
    log.info("Region {} has {} sets of masters.", region.id(), mastersList.size());
    if (mastersList.isEmpty()) {
        // for now just leave devices alone
        return new HashMap<>();
    }
    // Get the region's preferred set of masters
    Set<DeviceId> devicesInMasters = Sets.newHashSet();
    Map<ControllerNode, Set<DeviceId>> regionalControllerDevices = getRegionsPreferredMasters(region, devicesInMasters, allControllerDevices);
    // Now re-balance the buckets until they are roughly even.
    List<CompletableFuture<Void>> balanceBucketsFutures = Lists.newArrayList();
    balanceControllerNodes(regionalControllerDevices, devicesInMasters.size(), balanceBucketsFutures);
    // Handle devices that are not currently mastered by the master node set
    Set<DeviceId> devicesNotMasteredWithControllers = Sets.difference(devicesInRegion, devicesInMasters);
    if (!devicesNotMasteredWithControllers.isEmpty()) {
        // active controllers in master node set are already balanced, just
        // assign device mastership in sequence
        List<ControllerNode> sorted = new ArrayList<>(regionalControllerDevices.keySet());
        Collections.sort(sorted, Comparator.comparingInt(o -> (regionalControllerDevices.get(o)).size()));
        int deviceIndex = 0;
        for (DeviceId deviceId : devicesNotMasteredWithControllers) {
            ControllerNode cnode = sorted.get(deviceIndex % sorted.size());
            balanceBucketsFutures.add(setRole(cnode.id(), deviceId, MASTER));
            regionalControllerDevices.get(cnode).add(deviceId);
            deviceIndex++;
        }
    }
    CompletableFuture<Void> balanceRolesFuture = allOf(balanceBucketsFutures.toArray(new CompletableFuture[balanceBucketsFutures.size()]));
    Futures.getUnchecked(balanceRolesFuture);
    // Update the map before returning
    regionalControllerDevices.forEach((controllerNode, deviceIds) -> {
        regionalControllerDevices.put(controllerNode, new HashSet<>(getDevicesOf(controllerNode.id())));
    });
    return regionalControllerDevices;
}
Also used : CLUSTER_READ(org.onosproject.security.AppPermission.Type.CLUSTER_READ) RegionService(org.onosproject.net.region.RegionService) MASTER(org.onosproject.net.MastershipRole.MASTER) OsgiPropertyConstants(org.onosproject.net.OsgiPropertyConstants) Map(java.util.Map) MastershipService(org.onosproject.mastership.MastershipService) NodeId(org.onosproject.cluster.NodeId) Region(org.onosproject.net.region.Region) UpgradeService(org.onosproject.upgrade.UpgradeService) AbstractListenerManager(org.onosproject.event.AbstractListenerManager) Deactivate(org.osgi.service.component.annotations.Deactivate) Collection(java.util.Collection) MastershipTermService(org.onosproject.mastership.MastershipTermService) MastershipInfo(org.onosproject.mastership.MastershipInfo) Set(java.util.Set) Sets(com.google.common.collect.Sets) List(java.util.List) Lists.newArrayList(com.google.common.collect.Lists.newArrayList) MastershipStore(org.onosproject.mastership.MastershipStore) Timer(com.codahale.metrics.Timer) ClusterService(org.onosproject.cluster.ClusterService) DeviceId(org.onosproject.net.DeviceId) MastershipStoreDelegate(org.onosproject.mastership.MastershipStoreDelegate) MetricsUtil.stopTimer(org.onlab.metrics.MetricsUtil.stopTimer) AppGuard.checkPermission(org.onosproject.security.AppGuard.checkPermission) MetricsService(org.onlab.metrics.MetricsService) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) ControllerNode(org.onosproject.cluster.ControllerNode) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) MetricsHelper(org.onosproject.core.MetricsHelper) MastershipEvent(org.onosproject.mastership.MastershipEvent) Component(org.osgi.service.component.annotations.Component) Lists(com.google.common.collect.Lists) CompletableFuture.allOf(java.util.concurrent.CompletableFuture.allOf) Context(com.codahale.metrics.Timer.Context) Activate(org.osgi.service.component.annotations.Activate) ComponentConfigService(org.onosproject.cfg.ComponentConfigService) UpgradeEventListener(org.onosproject.upgrade.UpgradeEventListener) Logger(org.slf4j.Logger) Iterator(java.util.Iterator) MetricsUtil.startTimer(org.onlab.metrics.MetricsUtil.startTimer) MastershipRole(org.onosproject.net.MastershipRole) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) CLUSTER_WRITE(org.onosproject.security.AppPermission.Type.CLUSTER_WRITE) MastershipTerm(org.onosproject.mastership.MastershipTerm) ReferenceCardinality(org.osgi.service.component.annotations.ReferenceCardinality) UpgradeEvent(org.onosproject.upgrade.UpgradeEvent) Futures(com.google.common.util.concurrent.Futures) ConfigProperty(org.onosproject.cfg.ConfigProperty) Modified(org.osgi.service.component.annotations.Modified) LoggerFactory.getLogger(org.slf4j.LoggerFactory.getLogger) RoleInfo(org.onosproject.cluster.RoleInfo) MastershipListener(org.onosproject.mastership.MastershipListener) Reference(org.osgi.service.component.annotations.Reference) Comparator(java.util.Comparator) MastershipAdminService(org.onosproject.mastership.MastershipAdminService) Collections(java.util.Collections) Set(java.util.Set) HashSet(java.util.HashSet) HashMap(java.util.HashMap) DeviceId(org.onosproject.net.DeviceId) Lists.newArrayList(com.google.common.collect.Lists.newArrayList) ArrayList(java.util.ArrayList) ControllerNode(org.onosproject.cluster.ControllerNode) CompletableFuture(java.util.concurrent.CompletableFuture)

Example 18 with ControllerNode

use of org.onosproject.cluster.ControllerNode in project onos by opennetworkinglab.

the class MastershipManager method balanceRoles.

@Override
public void balanceRoles() {
    List<ControllerNode> nodes = newArrayList(clusterService.getNodes());
    Map<ControllerNode, Set<DeviceId>> controllerDevices = new HashMap<>();
    Set<DeviceId> orphanedDevices = Sets.newHashSet();
    int deviceCount = 0;
    // whether the node is active.
    for (ControllerNode node : nodes) {
        Set<DeviceId> devicesOf = new HashSet<>(getDevicesOf(node.id()));
        if (clusterService.getState(node.id()).isActive()) {
            log.info("Node {} has {} devices.", node.id(), devicesOf.size());
            deviceCount += devicesOf.size();
            controllerDevices.put(node, devicesOf);
        } else if (!devicesOf.isEmpty()) {
            log.warn("Inactive node {} has {} orphaned devices.", node.id(), devicesOf.size());
            orphanedDevices.addAll(getDevicesOf(node.id()));
        }
    }
    if (useRegionForBalanceRoles && balanceRolesUsingRegions(controllerDevices)) {
        return;
    }
    List<CompletableFuture<Void>> balanceBucketsFutures = Lists.newLinkedList();
    // First re-balance the buckets until they are roughly even.
    balanceControllerNodes(controllerDevices, deviceCount, balanceBucketsFutures);
    // Then attempt to distribute any orphaned devices among the buckets.
    distributeOrphanedDevices(controllerDevices, orphanedDevices, balanceBucketsFutures);
    CompletableFuture<Void> balanceRolesFuture = allOf(balanceBucketsFutures.toArray(new CompletableFuture[balanceBucketsFutures.size()]));
    Futures.getUnchecked(balanceRolesFuture);
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) HashMap(java.util.HashMap) DeviceId(org.onosproject.net.DeviceId) ControllerNode(org.onosproject.cluster.ControllerNode) CompletableFuture(java.util.concurrent.CompletableFuture) HashSet(java.util.HashSet)

Example 19 with ControllerNode

use of org.onosproject.cluster.ControllerNode in project onos by opennetworkinglab.

the class MastershipManager method getRegionsPreferredMasters.

/**
 * Get region's preferred set of master nodes - the first master node set that has at
 * least one active node.
 *
 * @param region               region for which preferred set of master nodes is requested
 * @param devicesInMasters     device set to track devices in preferred set of master nodes
 * @param allControllerDevices controller nodes to devices map
 * @return region's preferred master nodes (and devices that use them as masters)
 */
private Map<ControllerNode, Set<DeviceId>> getRegionsPreferredMasters(Region region, Set<DeviceId> devicesInMasters, Map<ControllerNode, Set<DeviceId>> allControllerDevices) {
    Map<ControllerNode, Set<DeviceId>> regionalControllerDevices = new HashMap<>();
    int listIndex = 0;
    for (Set<NodeId> masterSet : region.masters()) {
        log.info("Region {} masters set {} has {} nodes.", region.id(), listIndex, masterSet.size());
        if (masterSet.isEmpty()) {
            // nothing on this level
            listIndex++;
            continue;
        }
        // Create buckets reflecting current ownership.
        for (NodeId nodeId : masterSet) {
            if (clusterService.getState(nodeId).isActive()) {
                ControllerNode controllerNode = clusterService.getNode(nodeId);
                Set<DeviceId> devicesOf = new HashSet<>(allControllerDevices.get(controllerNode));
                regionalControllerDevices.put(controllerNode, devicesOf);
                devicesInMasters.addAll(devicesOf);
                log.info("Active Node {} has {} devices.", nodeId, devicesOf.size());
            }
        }
        if (!regionalControllerDevices.isEmpty()) {
            // now have a set of >0 active controllers
            break;
        }
        // keep on looking
        listIndex++;
    }
    return regionalControllerDevices;
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) HashMap(java.util.HashMap) DeviceId(org.onosproject.net.DeviceId) NodeId(org.onosproject.cluster.NodeId) ControllerNode(org.onosproject.cluster.ControllerNode) HashSet(java.util.HashSet)

Example 20 with ControllerNode

use of org.onosproject.cluster.ControllerNode in project onos by opennetworkinglab.

the class SimpleMastershipStore method activate.

@Activate
public void activate() {
    if (clusterService == null) {
        // just for ease of unit test
        final ControllerNode instance = new DefaultControllerNode(new NodeId("local"), IpAddress.valueOf("127.0.0.1"));
        clusterService = new ClusterService() {

            private final Instant creationTime = Instant.now();

            @Override
            public ControllerNode getLocalNode() {
                return instance;
            }

            @Override
            public Set<ControllerNode> getNodes() {
                return ImmutableSet.of(instance);
            }

            @Override
            public Set<Node> getConsensusNodes() {
                return ImmutableSet.of();
            }

            @Override
            public ControllerNode getNode(NodeId nodeId) {
                if (instance.id().equals(nodeId)) {
                    return instance;
                }
                return null;
            }

            @Override
            public State getState(NodeId nodeId) {
                if (instance.id().equals(nodeId)) {
                    return State.ACTIVE;
                } else {
                    return State.INACTIVE;
                }
            }

            @Override
            public Version getVersion(NodeId nodeId) {
                if (instance.id().equals(nodeId)) {
                    return versionService.version();
                }
                return null;
            }

            @Override
            public Instant getLastUpdatedInstant(NodeId nodeId) {
                return creationTime;
            }

            @Override
            public void addListener(ClusterEventListener listener) {
            }

            @Override
            public void removeListener(ClusterEventListener listener) {
            }
        };
    }
    log.info("Started");
}
Also used : ClusterService(org.onosproject.cluster.ClusterService) HashSet(java.util.HashSet) ImmutableSet(com.google.common.collect.ImmutableSet) Set(java.util.Set) Version(org.onosproject.core.Version) State(org.onosproject.cluster.ControllerNode.State) Instant(java.time.Instant) NodeId(org.onosproject.cluster.NodeId) ControllerNode(org.onosproject.cluster.ControllerNode) DefaultControllerNode(org.onosproject.cluster.DefaultControllerNode) DefaultControllerNode(org.onosproject.cluster.DefaultControllerNode) ClusterEventListener(org.onosproject.cluster.ClusterEventListener) Activate(org.osgi.service.component.annotations.Activate)

Aggregations

ControllerNode (org.onosproject.cluster.ControllerNode)42 NodeId (org.onosproject.cluster.NodeId)17 ClusterService (org.onosproject.cluster.ClusterService)14 Activate (org.osgi.service.component.annotations.Activate)11 Set (java.util.Set)10 DefaultControllerNode (org.onosproject.cluster.DefaultControllerNode)10 List (java.util.List)8 Collectors (java.util.stream.Collectors)8 Logger (org.slf4j.Logger)8 LoggerFactory.getLogger (org.slf4j.LoggerFactory.getLogger)8 DeviceId (org.onosproject.net.DeviceId)7 IpAddress (org.onlab.packet.IpAddress)6 Version (org.onosproject.core.Version)6 Component (org.osgi.service.component.annotations.Component)5 Deactivate (org.osgi.service.component.annotations.Deactivate)5 Reference (org.osgi.service.component.annotations.Reference)5 ReferenceCardinality (org.osgi.service.component.annotations.ReferenceCardinality)5 Preconditions.checkNotNull (com.google.common.base.Preconditions.checkNotNull)4 Collection (java.util.Collection)4 HashSet (java.util.HashSet)4