Search in sources :

Example 11 with NodeRepository

use of com.yahoo.vespa.hosted.provision.NodeRepository in project vespa by vespa-engine.

the class OperatorChangeApplicationMaintainer method nodesNeedingMaintenance.

@Override
protected List<Node> nodesNeedingMaintenance() {
    Instant windowEnd = clock.instant();
    Instant windowStart = previousRun;
    previousRun = windowEnd;
    return nodeRepository().getNodes().stream().filter(node -> node.allocation().isPresent()).filter(node -> hasManualStateChangeSince(windowStart, node)).collect(Collectors.toList());
}
Also used : Deployer(com.yahoo.config.provision.Deployer) NodeRepository(com.yahoo.vespa.hosted.provision.NodeRepository) List(java.util.List) Agent(com.yahoo.vespa.hosted.provision.node.Agent) ApplicationId(com.yahoo.config.provision.ApplicationId) Duration(java.time.Duration) Clock(java.time.Clock) Node(com.yahoo.vespa.hosted.provision.Node) Instant(java.time.Instant) Collectors(java.util.stream.Collectors) Instant(java.time.Instant)

Example 12 with NodeRepository

use of com.yahoo.vespa.hosted.provision.NodeRepository in project vespa by vespa-engine.

the class MetricsReporter method updateDockerMetrics.

private void updateDockerMetrics(List<Node> nodes) {
    // Capacity flavors for docker
    DockerHostCapacity capacity = new DockerHostCapacity(nodes);
    metric.set("hostedVespa.docker.totalCapacityCpu", capacity.getCapacityTotal().getCpu(), null);
    metric.set("hostedVespa.docker.totalCapacityMem", capacity.getCapacityTotal().getMemory(), null);
    metric.set("hostedVespa.docker.totalCapacityDisk", capacity.getCapacityTotal().getDisk(), null);
    metric.set("hostedVespa.docker.freeCapacityCpu", capacity.getFreeCapacityTotal().getCpu(), null);
    metric.set("hostedVespa.docker.freeCapacityMem", capacity.getFreeCapacityTotal().getMemory(), null);
    metric.set("hostedVespa.docker.freeCapacityDisk", capacity.getFreeCapacityTotal().getDisk(), null);
    List<Flavor> dockerFlavors = nodeRepository().getAvailableFlavors().getFlavors().stream().filter(f -> f.getType().equals(Flavor.Type.DOCKER_CONTAINER)).collect(Collectors.toList());
    for (Flavor flavor : dockerFlavors) {
        Metric.Context context = getContextAt("flavor", flavor.name());
        metric.set("hostedVespa.docker.freeCapacityFlavor", capacity.freeCapacityInFlavorEquivalence(flavor), context);
        metric.set("hostedVespa.docker.idealHeadroomFlavor", flavor.getIdealHeadroom(), context);
        metric.set("hostedVespa.docker.hostsAvailableFlavor", capacity.getNofHostsAvailableFor(flavor), context);
    }
}
Also used : Metric(com.yahoo.jdisc.Metric) HostNameNotFoundException(com.yahoo.vespa.orchestrator.HostNameNotFoundException) ServiceInstance(com.yahoo.vespa.applicationmodel.ServiceInstance) ServiceMonitor(com.yahoo.vespa.service.monitor.ServiceMonitor) Version(com.yahoo.component.Version) ApplicationId(com.yahoo.config.provision.ApplicationId) NodeType(com.yahoo.config.provision.NodeType) HashMap(java.util.HashMap) Orchestrator(com.yahoo.vespa.orchestrator.Orchestrator) ServiceStatus(com.yahoo.vespa.applicationmodel.ServiceStatus) Node(com.yahoo.vespa.hosted.provision.Node) Collectors(java.util.stream.Collectors) Allocation(com.yahoo.vespa.hosted.provision.node.Allocation) ArrayList(java.util.ArrayList) NodeRepository(com.yahoo.vespa.hosted.provision.NodeRepository) DockerHostCapacity(com.yahoo.vespa.hosted.provision.provisioning.DockerHostCapacity) List(java.util.List) History(com.yahoo.vespa.hosted.provision.node.History) Flavor(com.yahoo.config.provision.Flavor) HostName(com.yahoo.vespa.applicationmodel.HostName) Duration(java.time.Duration) Map(java.util.Map) Optional(java.util.Optional) HostStatus(com.yahoo.vespa.orchestrator.status.HostStatus) Metric(com.yahoo.jdisc.Metric) DockerHostCapacity(com.yahoo.vespa.hosted.provision.provisioning.DockerHostCapacity) Flavor(com.yahoo.config.provision.Flavor)

Example 13 with NodeRepository

use of com.yahoo.vespa.hosted.provision.NodeRepository in project vespa by vespa-engine.

the class NodeRetirer method retireAllocated.

void retireAllocated() {
    List<Node> allNodes = nodeRepository().getNodes(NodeType.tenant);
    List<ApplicationId> activeApplications = getActiveApplicationIds(allNodes);
    Map<Flavor, Map<Node.State, Long>> numSpareNodesByFlavorByState = getNumberOfNodesByFlavorByNodeState(allNodes);
    flavorSpareChecker.updateReadyAndActiveCountsByFlavor(numSpareNodesByFlavorByState);
    // Get all the nodes that we could retire along with their deployments
    Map<Deployment, Set<Node>> nodesToRetireByDeployment = new HashMap<>();
    for (ApplicationId applicationId : activeApplications) {
        Map<ClusterSpec.Id, Set<Node>> nodesByCluster = getNodesBelongingToApplication(allNodes, applicationId).stream().collect(Collectors.groupingBy(node -> node.allocation().get().membership().cluster().id(), Collectors.toSet()));
        Map<ClusterSpec.Id, Set<Node>> retireableNodesByCluster = nodesByCluster.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> filterRetireableNodes(entry.getValue())));
        if (retireableNodesByCluster.values().stream().mapToInt(Set::size).sum() == 0)
            continue;
        Optional<Deployment> deployment = deployer.deployFromLocalActive(applicationId);
        // this will be done at another config server
        if (!deployment.isPresent())
            continue;
        Set<Node> replaceableNodes = retireableNodesByCluster.entrySet().stream().flatMap(entry -> entry.getValue().stream().filter(node -> flavorSpareChecker.canRetireAllocatedNodeWithFlavor(node.flavor())).limit(getNumberNodesAllowToRetireForCluster(nodesByCluster.get(entry.getKey()), MAX_SIMULTANEOUS_RETIRES_PER_CLUSTER))).collect(Collectors.toSet());
        if (!replaceableNodes.isEmpty())
            nodesToRetireByDeployment.put(deployment.get(), replaceableNodes);
    }
    nodesToRetireByDeployment.forEach(((deployment, nodes) -> {
        ApplicationId app = nodes.iterator().next().allocation().get().owner();
        Set<Node> nodesToRetire;
        // that may have changed) with wantToRetire and wantToDeprovision.
        try (Mutex lock = nodeRepository().lock(app)) {
            nodesToRetire = nodes.stream().map(node -> nodeRepository().getNode(node.hostname()).filter(upToDateNode -> node.state() == Node.State.active).filter(upToDateNode -> node.allocation().get().owner().equals(upToDateNode.allocation().get().owner()))).flatMap(node -> node.map(Stream::of).orElseGet(Stream::empty)).collect(Collectors.toSet());
            nodesToRetire.forEach(node -> retirementPolicy.shouldRetire(node).ifPresent(reason -> {
                log.info("Setting wantToRetire and wantToDeprovision for host " + node.hostname() + " with flavor " + node.flavor().name() + " allocated to " + node.allocation().get().owner() + ". Reason: " + reason);
                Node updatedNode = node.with(node.status().withWantToRetire(true).withWantToDeprovision(true));
                nodeRepository().write(updatedNode);
            }));
        }
        // This takes a while, so do it outside of the application lock
        if (!nodesToRetire.isEmpty()) {
            try {
                deployment.activate();
            } catch (Exception e) {
                log.log(LogLevel.INFO, "Failed to redeploy " + app.serializedForm() + ", will be redeployed later by application maintainer", e);
            }
        }
    }));
}
Also used : Deployer(com.yahoo.config.provision.Deployer) FlavorSpareChecker(com.yahoo.vespa.hosted.provision.provisioning.FlavorSpareChecker) RetirementPolicy(com.yahoo.vespa.hosted.provision.maintenance.retire.RetirementPolicy) Iterator(java.util.Iterator) ApplicationId(com.yahoo.config.provision.ApplicationId) Deployment(com.yahoo.config.provision.Deployment) NodeType(com.yahoo.config.provision.NodeType) Collection(java.util.Collection) ClusterSpec(com.yahoo.config.provision.ClusterSpec) Set(java.util.Set) HashMap(java.util.HashMap) Node(com.yahoo.vespa.hosted.provision.Node) Logger(java.util.logging.Logger) Collectors(java.util.stream.Collectors) NodeRepository(com.yahoo.vespa.hosted.provision.NodeRepository) Mutex(com.yahoo.transaction.Mutex) List(java.util.List) Stream(java.util.stream.Stream) Agent(com.yahoo.vespa.hosted.provision.node.Agent) Flavor(com.yahoo.config.provision.Flavor) Duration(java.time.Duration) Map(java.util.Map) LogLevel(com.yahoo.log.LogLevel) Optional(java.util.Optional) Set(java.util.Set) HashMap(java.util.HashMap) Node(com.yahoo.vespa.hosted.provision.Node) Deployment(com.yahoo.config.provision.Deployment) Mutex(com.yahoo.transaction.Mutex) Flavor(com.yahoo.config.provision.Flavor) Stream(java.util.stream.Stream) ApplicationId(com.yahoo.config.provision.ApplicationId) ApplicationId(com.yahoo.config.provision.ApplicationId) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

NodeRepository (com.yahoo.vespa.hosted.provision.NodeRepository)13 Node (com.yahoo.vespa.hosted.provision.Node)11 ApplicationId (com.yahoo.config.provision.ApplicationId)8 Duration (java.time.Duration)7 List (java.util.List)7 Collectors (java.util.stream.Collectors)7 Deployer (com.yahoo.config.provision.Deployer)6 NodeType (com.yahoo.config.provision.NodeType)6 Orchestrator (com.yahoo.vespa.orchestrator.Orchestrator)6 Map (java.util.Map)6 Optional (java.util.Optional)6 Deployment (com.yahoo.config.provision.Deployment)5 DockerImage (com.yahoo.config.provision.DockerImage)5 MockNameResolver (com.yahoo.vespa.hosted.provision.testutils.MockNameResolver)5 HashMap (java.util.HashMap)5 Curator (com.yahoo.vespa.curator.Curator)4 MockCurator (com.yahoo.vespa.curator.mock.MockCurator)4 Agent (com.yahoo.vespa.hosted.provision.node.Agent)4 ServiceMonitor (com.yahoo.vespa.service.monitor.ServiceMonitor)4 Test (org.junit.Test)4