Search in sources :

Example 6 with Offer

use of org.apache.mesos.v1.Protos.Offer in project Singularity by HubSpot.

the class SingularityMesosSchedulerClient method decline.

/**
 * Sent by the scheduler to explicitly decline offer(s) received. Note that this is same as sending an
 * ACCEPT call with no operations.
 *
 * @param offerIds
 */
public void decline(List<OfferID> offerIds) {
    Builder decline = build().setDecline(Decline.newBuilder().addAllOfferIds(offerIds));
    sendCall(decline, Type.DECLINE);
}
Also used : MesosClientBuilder(com.mesosphere.mesos.rx.java.MesosClientBuilder) ProtobufMesosClientBuilder(com.mesosphere.mesos.rx.java.protobuf.ProtobufMesosClientBuilder) Builder(org.apache.mesos.v1.scheduler.Protos.Call.Builder)

Example 7 with Offer

use of org.apache.mesos.v1.Protos.Offer in project Singularity by HubSpot.

the class SingularityMesosSchedulerClient method accept.

/**
 * Sent by the scheduler when it accepts offer(s) sent by the master. The ACCEPT request includes the type of
 * operations (e.g., launch task, launch task group, reserve resources, create volumes) that the scheduler wants to
 * perform on the offers. Note that until the scheduler replies (accepts or declines) to an offer, the offer’s
 * resources are considered allocated to the offer’s role and to the framework.
 *
 * @param offerIds
 * @param offerOperations
 */
public void accept(List<OfferID> offerIds, List<Offer.Operation> offerOperations) {
    Builder accept = build().setAccept(Accept.newBuilder().addAllOfferIds(offerIds).addAllOperations(offerOperations));
    sendCall(accept, Type.ACCEPT);
}
Also used : MesosClientBuilder(com.mesosphere.mesos.rx.java.MesosClientBuilder) ProtobufMesosClientBuilder(com.mesosphere.mesos.rx.java.protobuf.ProtobufMesosClientBuilder) Builder(org.apache.mesos.v1.scheduler.Protos.Call.Builder)

Example 8 with Offer

use of org.apache.mesos.v1.Protos.Offer in project Singularity by HubSpot.

the class SingularityMesosSchedulerImpl method resourceOffers.

@Timed
@Override
public void resourceOffers(List<Offer> offers) {
    if (!isRunning()) {
        LOG.info("Scheduler is in state {}, declining {} offer(s)", state.name(), offers.size());
        mesosSchedulerClient.decline(offers.stream().map(Offer::getId).collect(Collectors.toList()));
        return;
    }
    callWithOffersLock(() -> {
        final long start = System.currentTimeMillis();
        lastOfferTimestamp = Optional.of(start);
        LOG.info("Received {} offer(s)", offers.size());
        boolean delclineImmediately = false;
        if (disasterManager.isDisabled(SingularityAction.PROCESS_OFFERS)) {
            LOG.info("Processing offers is currently disabled, declining {} offers", offers.size());
            delclineImmediately = true;
        }
        if (delayWhenStatusUpdateDeltaTooLarge && statusUpdateDeltaAvg.get() > delayWhenDeltaOverMs) {
            LOG.info("Status update delta is too large ({}), declining offers while status updates catch up", statusUpdateDeltaAvg.get());
            delclineImmediately = true;
        }
        if (delclineImmediately) {
            mesosSchedulerClient.decline(offers.stream().map(Offer::getId).collect(Collectors.toList()));
            return;
        }
        if (offerCacheEnabled) {
            if (disasterManager.isDisabled(SingularityAction.CACHE_OFFERS)) {
                offerCache.disableOfferCache();
            } else {
                offerCache.enableOfferCache();
            }
        }
        List<Offer> offersToCheck = new ArrayList<>(offers);
        List<CachedOffer> cachedOfferList = offerCache.checkoutOffers();
        Map<String, CachedOffer> cachedOffers = new HashMap<>();
        for (CachedOffer cachedOffer : cachedOfferList) {
            cachedOffers.put(cachedOffer.getOfferId(), cachedOffer);
            offersToCheck.add(cachedOffer.getOffer());
        }
        offers.parallelStream().forEach((offer) -> {
            String rolesInfo = MesosUtils.getRoles(offer).toString();
            LOG.debug("Received offer ID {} with roles {} from {} ({}) for {} cpu(s), {} memory, {} ports, and {} disk", offer.getId().getValue(), rolesInfo, offer.getHostname(), offer.getAgentId().getValue(), MesosUtils.getNumCpus(offer), MesosUtils.getMemory(offer), MesosUtils.getNumPorts(offer), MesosUtils.getDisk(offer));
            CheckResult checkResult = slaveAndRackManager.checkOffer(offer);
            if (checkResult == CheckResult.NOT_ACCEPTING_TASKS) {
                mesosSchedulerClient.decline(Collections.singletonList(offer.getId()));
                offersToCheck.remove(offer);
                LOG.debug("Will decline offer {}, slave {} is not currently in a state to launch tasks", offer.getId().getValue(), offer.getHostname());
            }
        });
        final Set<OfferID> acceptedOffers = Sets.newHashSetWithExpectedSize(offersToCheck.size());
        try {
            Collection<SingularityOfferHolder> offerHolders = offerScheduler.checkOffers(offersToCheck);
            for (SingularityOfferHolder offerHolder : offerHolders) {
                if (!offerHolder.getAcceptedTasks().isEmpty()) {
                    List<Offer> leftoverOffers = offerHolder.launchTasksAndGetUnusedOffers(mesosSchedulerClient);
                    leftoverOffers.forEach((o) -> {
                        if (cachedOffers.containsKey(o.getId().getValue())) {
                            offerCache.returnOffer(cachedOffers.remove(o.getId().getValue()));
                        } else {
                            offerCache.cacheOffer(start, o);
                        }
                    });
                    List<Offer> offersAcceptedFromSlave = offerHolder.getOffers();
                    offersAcceptedFromSlave.removeAll(leftoverOffers);
                    offersAcceptedFromSlave.stream().filter((offer) -> cachedOffers.containsKey(offer.getId().getValue())).map((o) -> cachedOffers.remove(o.getId().getValue())).forEach(offerCache::useOffer);
                    acceptedOffers.addAll(offersAcceptedFromSlave.stream().map(Offer::getId).collect(Collectors.toList()));
                } else {
                    offerHolder.getOffers().forEach((o) -> {
                        if (cachedOffers.containsKey(o.getId().getValue())) {
                            offerCache.returnOffer(cachedOffers.remove(o.getId().getValue()));
                        } else {
                            offerCache.cacheOffer(start, o);
                        }
                    });
                }
            }
            LOG.info("{} remaining offers not accounted for in offer check", cachedOffers.size());
            cachedOffers.values().forEach(offerCache::returnOffer);
        } catch (Throwable t) {
            LOG.error("Received fatal error while handling offers - will decline all available offers", t);
            mesosSchedulerClient.decline(offersToCheck.stream().filter((o) -> !acceptedOffers.contains(o.getId()) && !cachedOffers.containsKey(o.getId().getValue())).map(Offer::getId).collect(Collectors.toList()));
            offersToCheck.forEach((o) -> {
                if (cachedOffers.containsKey(o.getId().getValue())) {
                    offerCache.returnOffer(cachedOffers.get(o.getId().getValue()));
                }
            });
            throw t;
        }
        LOG.info("Finished handling {} new offer(s) ({}), {} accepted, {} declined/cached", offers.size(), JavaUtils.duration(start), acceptedOffers.size(), offers.size() - acceptedOffers.size());
    }, "resourceOffers");
}
Also used : CachedOffer(com.hubspot.singularity.mesos.SingularityOfferCache.CachedOffer) SingularityTask(com.hubspot.singularity.SingularityTask) Arrays(java.util.Arrays) Subscribed(org.apache.mesos.v1.scheduler.Protos.Event.Subscribed) Inject(com.google.inject.Inject) PrematureChannelClosureException(io.netty.handler.codec.PrematureChannelClosureException) LoggerFactory(org.slf4j.LoggerFactory) Random(java.util.Random) Offer(org.apache.mesos.v1.Protos.Offer) Optional(com.google.common.base.Optional) Map(java.util.Map) MesosProtosUtils(com.hubspot.singularity.helpers.MesosProtosUtils) CheckResult(com.hubspot.singularity.mesos.SingularitySlaveAndRackManager.CheckResult) TaskManager(com.hubspot.singularity.data.TaskManager) SingularityTaskId(com.hubspot.singularity.SingularityTaskId) AbortReason(com.hubspot.singularity.SingularityAbort.AbortReason) Collection(java.util.Collection) SingularityKilledTaskIdRecord(com.hubspot.singularity.SingularityKilledTaskIdRecord) Failure(org.apache.mesos.v1.scheduler.Protos.Event.Failure) Set(java.util.Set) Transcoder(com.hubspot.singularity.data.transcoders.Transcoder) Protos(org.apache.mesos.v1.Protos) Collectors(java.util.stream.Collectors) ExecutorID(org.apache.mesos.v1.Protos.ExecutorID) Sets(com.google.common.collect.Sets) Timed(com.codahale.metrics.annotation.Timed) List(java.util.List) JavaUtils(com.hubspot.mesos.JavaUtils) MesosUtils(com.hubspot.singularity.helpers.MesosUtils) SingularityLeaderCacheCoordinator(com.hubspot.singularity.scheduler.SingularityLeaderCacheCoordinator) RequestCleanupType(com.hubspot.singularity.RequestCleanupType) DisasterManager(com.hubspot.singularity.data.DisasterManager) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) Event(org.apache.mesos.v1.scheduler.Protos.Event) Singleton(javax.inject.Singleton) AtomicReference(java.util.concurrent.atomic.AtomicReference) ArrayList(java.util.ArrayList) Lists(com.google.common.collect.Lists) InverseOffer(org.apache.mesos.v1.Protos.InverseOffer) SingularityExceptionNotifier(com.hubspot.singularity.sentry.SingularityExceptionNotifier) SingularityConfiguration(com.hubspot.singularity.config.SingularityConfiguration) TaskStatus(org.apache.mesos.v1.Protos.TaskStatus) SingularityAction(com.hubspot.singularity.SingularityAction) Logger(org.slf4j.Logger) SingularityTaskDestroyFrameworkMessage(com.hubspot.singularity.SingularityTaskDestroyFrameworkMessage) AgentID(org.apache.mesos.v1.Protos.AgentID) OfferID(org.apache.mesos.v1.Protos.OfferID) AtomicLong(java.util.concurrent.atomic.AtomicLong) TaskCleanupType(com.hubspot.singularity.TaskCleanupType) MasterInfo(org.apache.mesos.v1.Protos.MasterInfo) TaskID(org.apache.mesos.v1.Protos.TaskID) SingularityAbort(com.hubspot.singularity.SingularityAbort) Message(org.apache.mesos.v1.scheduler.Protos.Event.Message) Preconditions(com.google.common.base.Preconditions) Named(com.google.inject.name.Named) Collections(java.util.Collections) MesosConfiguration(com.hubspot.singularity.config.MesosConfiguration) SingularityMainModule(com.hubspot.singularity.SingularityMainModule) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) OfferID(org.apache.mesos.v1.Protos.OfferID) CachedOffer(com.hubspot.singularity.mesos.SingularityOfferCache.CachedOffer) Offer(org.apache.mesos.v1.Protos.Offer) InverseOffer(org.apache.mesos.v1.Protos.InverseOffer) CheckResult(com.hubspot.singularity.mesos.SingularitySlaveAndRackManager.CheckResult) CachedOffer(com.hubspot.singularity.mesos.SingularityOfferCache.CachedOffer) Timed(com.codahale.metrics.annotation.Timed)

Example 9 with Offer

use of org.apache.mesos.v1.Protos.Offer in project Singularity by HubSpot.

the class SingularityMesosOfferSchedulerTest method itAccountsForExpectedTaskUsage.

@Test
public void itAccountsForExpectedTaskUsage() {
    initRequest();
    double cpuReserved = 2;
    double memMbReserved = 1000;
    initFirstDeployWithResources(cpuReserved, memMbReserved);
    saveAndSchedule(requestManager.getRequest(requestId).get().getRequest().toBuilder().setInstances(Optional.of(1)));
    resourceOffers(3);
    SingularityTaskId taskId = taskManager.getActiveTaskIds().get(0);
    String t1 = taskId.getId();
    // 2 cpus used
    MesosTaskMonitorObject t1u1 = getTaskMonitor(t1, 10, TimeUnit.MILLISECONDS.toSeconds(taskId.getStartedAt()) + 5, 1000);
    mesosClient.setSlaveResourceUsage("host1", Collections.singletonList(t1u1));
    usagePoller.runActionOnPoll();
    Map<ResourceUsageType, Number> longRunningTasksUsage = new HashMap<>();
    longRunningTasksUsage.put(ResourceUsageType.CPU_USED, 0.1);
    longRunningTasksUsage.put(ResourceUsageType.MEMORY_BYTES_USED, 0.1);
    longRunningTasksUsage.put(ResourceUsageType.DISK_BYTES_USED, 0.1);
    SingularitySlaveUsage smallUsage = new SingularitySlaveUsage(0.1, 0.1, Optional.of(10.0), 1, 1, Optional.of(30L), 1, 1, Optional.of(1024L), longRunningTasksUsage, 1, System.currentTimeMillis(), 1, 30000, 10, 0, 0, 0, 0, 107374182);
    usageManager.saveSpecificSlaveUsageAndSetCurrent("host1", smallUsage);
    usageManager.saveSpecificSlaveUsageAndSetCurrent("host2", smallUsage);
    usageManager.saveSpecificSlaveUsageAndSetCurrent("host3", smallUsage);
    requestResource.scale(requestId, new SingularityScaleRequest(Optional.of(3), Optional.absent(), Optional.absent(), Optional.absent(), Optional.absent(), Optional.absent(), Optional.absent(), Optional.absent()), SingularityUser.DEFAULT_USER);
    Assert.assertEquals(2.0, usageManager.getRequestUtilizations().get(requestId).getCpuUsed(), 0.001);
    Offer host2Offer = createOffer(6, 30000, 107374182, "host2", "host2");
    slaveAndRackManager.checkOffer(host2Offer);
    Offer host3Offer = createOffer(6, 30000, 107374182, "host3", "host3");
    slaveAndRackManager.checkOffer(host3Offer);
    Collection<SingularityOfferHolder> offerHolders = offerScheduler.checkOffers(Arrays.asList(host2Offer, host3Offer));
    Assert.assertEquals(2, offerHolders.size());
    // A single offer should only ever get a single task even though both have room for both tasks here. Adding a task should reduce the score for the next check
    for (SingularityOfferHolder offerHolder : offerHolders) {
        Assert.assertEquals(1, offerHolder.getAcceptedTasks().size());
    }
}
Also used : SingularitySlaveUsage(com.hubspot.singularity.SingularitySlaveUsage) HashMap(java.util.HashMap) MesosTaskMonitorObject(com.hubspot.mesos.json.MesosTaskMonitorObject) Offer(org.apache.mesos.v1.Protos.Offer) SingularityScaleRequest(com.hubspot.singularity.api.SingularityScaleRequest) SingularityTaskId(com.hubspot.singularity.SingularityTaskId) ResourceUsageType(com.hubspot.singularity.SingularitySlaveUsage.ResourceUsageType) Test(org.junit.Test)

Example 10 with Offer

use of org.apache.mesos.v1.Protos.Offer in project Singularity by HubSpot.

the class SingularitySchedulerPoller method runActionOnPoll.

@Override
public void runActionOnPoll() {
    if (disasterManager.isDisabled(SingularityAction.RUN_SCHEDULER_POLLER)) {
        LOG.warn("Scheduler poller is disabled");
        return;
    }
    lock.runWithOffersLock(() -> {
        List<CachedOffer> cachedOffers = offerCache.checkoutOffers();
        Map<String, CachedOffer> offerIdToCachedOffer = new HashMap<>(cachedOffers.size());
        List<Offer> offers = new ArrayList<>(cachedOffers.size());
        for (CachedOffer cachedOffer : cachedOffers) {
            offerIdToCachedOffer.put(cachedOffer.getOfferId(), cachedOffer);
            offers.add(cachedOffer.getOffer());
        }
        Collection<SingularityOfferHolder> offerHolders = offerScheduler.checkOffers(offers);
        if (offerHolders.isEmpty()) {
            return;
        }
        int acceptedOffers = 0;
        int launchedTasks = 0;
        for (SingularityOfferHolder offerHolder : offerHolders) {
            List<CachedOffer> cachedOffersFromHolder = offerHolder.getOffers().stream().map((o) -> offerIdToCachedOffer.get(o.getId().getValue())).collect(Collectors.toList());
            if (!offerHolder.getAcceptedTasks().isEmpty()) {
                List<Offer> unusedOffers = offerHolder.launchTasksAndGetUnusedOffers(schedulerClient);
                launchedTasks += offerHolder.getAcceptedTasks().size();
                acceptedOffers += cachedOffersFromHolder.size() - unusedOffers.size();
                // Return to the cache those offers which we checked out of the cache, but didn't end up using.
                List<CachedOffer> unusedCachedOffers = unusedOffers.stream().map((o) -> offerIdToCachedOffer.get(o.getId().getValue())).collect(Collectors.toList());
                unusedCachedOffers.forEach((cachedOffer) -> {
                    offerIdToCachedOffer.remove(cachedOffer.getOfferId());
                    offerCache.returnOffer(cachedOffer);
                });
                // Notify the cache of the cached offers that we did use.
                cachedOffersFromHolder.removeAll(unusedCachedOffers);
                cachedOffersFromHolder.forEach((cachedOffer) -> {
                    offerIdToCachedOffer.remove(cachedOffer.getOfferId());
                    offerCache.useOffer(cachedOffer);
                });
            } else {
                cachedOffersFromHolder.forEach((cachedOffer) -> {
                    offerIdToCachedOffer.remove(cachedOffer.getOfferId());
                    offerCache.returnOffer(cachedOffer);
                });
            }
        }
        LOG.info("{} remaining offers not accounted for in offer check", offerIdToCachedOffer.size());
        offerIdToCachedOffer.values().forEach(offerCache::returnOffer);
        LOG.info("Launched {} tasks on {} cached offers (returned {})", launchedTasks, acceptedOffers, offerHolders.size() - acceptedOffers);
    }, getClass().getSimpleName());
}
Also used : SingularityOfferHolder(com.hubspot.singularity.mesos.SingularityOfferHolder) SingularityAction(com.hubspot.singularity.SingularityAction) DisasterManager(com.hubspot.singularity.data.DisasterManager) CachedOffer(com.hubspot.singularity.mesos.SingularityOfferCache.CachedOffer) SingularityMesosOfferScheduler(com.hubspot.singularity.mesos.SingularityMesosOfferScheduler) Logger(org.slf4j.Logger) Collection(java.util.Collection) Inject(com.google.inject.Inject) LoggerFactory(org.slf4j.LoggerFactory) HashMap(java.util.HashMap) Offer(org.apache.mesos.v1.Protos.Offer) Singleton(javax.inject.Singleton) Collectors(java.util.stream.Collectors) ArrayList(java.util.ArrayList) OfferCache(com.hubspot.singularity.mesos.OfferCache) TimeUnit(java.util.concurrent.TimeUnit) List(java.util.List) SingularityMesosSchedulerClient(com.hubspot.singularity.mesos.SingularityMesosSchedulerClient) Map(java.util.Map) SingularityOfferHolder(com.hubspot.singularity.mesos.SingularityOfferHolder) SingularitySchedulerLock(com.hubspot.singularity.mesos.SingularitySchedulerLock) SingularityConfiguration(com.hubspot.singularity.config.SingularityConfiguration) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) CachedOffer(com.hubspot.singularity.mesos.SingularityOfferCache.CachedOffer) Offer(org.apache.mesos.v1.Protos.Offer) CachedOffer(com.hubspot.singularity.mesos.SingularityOfferCache.CachedOffer)

Aggregations

Offer (org.apache.mesos.v1.Protos.Offer)13 SingularityTaskId (com.hubspot.singularity.SingularityTaskId)7 Test (org.junit.Test)6 ArrayList (java.util.ArrayList)5 Map (java.util.Map)5 HashMap (java.util.HashMap)4 List (java.util.List)4 Collectors (java.util.stream.Collectors)4 Logger (org.slf4j.Logger)4 LoggerFactory (org.slf4j.LoggerFactory)4 Optional (com.google.common.base.Optional)3 Inject (com.google.inject.Inject)3 SingularityPendingRequest (com.hubspot.singularity.SingularityPendingRequest)3 SingularitySlaveUsage (com.hubspot.singularity.SingularitySlaveUsage)3 ResourceUsageType (com.hubspot.singularity.SingularitySlaveUsage.ResourceUsageType)3 SingularityTask (com.hubspot.singularity.SingularityTask)3 SingularityConfiguration (com.hubspot.singularity.config.SingularityConfiguration)3 MesosUtils (com.hubspot.singularity.helpers.MesosUtils)3 CompletableFuture (java.util.concurrent.CompletableFuture)3 Lists (com.google.common.collect.Lists)2