Search in sources :

Example 26 with WorkerSlot

use of org.apache.storm.scheduler.WorkerSlot in project storm by apache.

the class ResourceUtils method printScheduling.

/**
     * print scheduling for debug purposes
     * @param cluster
     * @param topologies
     */
public static String printScheduling(Cluster cluster, Topologies topologies) {
    StringBuilder str = new StringBuilder();
    Map<String, Map<String, Map<WorkerSlot, Collection<ExecutorDetails>>>> schedulingMap = new HashMap<String, Map<String, Map<WorkerSlot, Collection<ExecutorDetails>>>>();
    for (TopologyDetails topo : topologies.getTopologies()) {
        if (cluster.getAssignmentById(topo.getId()) != null) {
            for (Map.Entry<ExecutorDetails, WorkerSlot> entry : cluster.getAssignmentById(topo.getId()).getExecutorToSlot().entrySet()) {
                WorkerSlot slot = entry.getValue();
                String nodeId = slot.getNodeId();
                ExecutorDetails exec = entry.getKey();
                if (!schedulingMap.containsKey(nodeId)) {
                    schedulingMap.put(nodeId, new HashMap<String, Map<WorkerSlot, Collection<ExecutorDetails>>>());
                }
                if (schedulingMap.get(nodeId).containsKey(topo.getId()) == false) {
                    schedulingMap.get(nodeId).put(topo.getId(), new HashMap<WorkerSlot, Collection<ExecutorDetails>>());
                }
                if (schedulingMap.get(nodeId).get(topo.getId()).containsKey(slot) == false) {
                    schedulingMap.get(nodeId).get(topo.getId()).put(slot, new LinkedList<ExecutorDetails>());
                }
                schedulingMap.get(nodeId).get(topo.getId()).get(slot).add(exec);
            }
        }
    }
    for (Map.Entry<String, Map<String, Map<WorkerSlot, Collection<ExecutorDetails>>>> entry : schedulingMap.entrySet()) {
        if (cluster.getSupervisorById(entry.getKey()) != null) {
            str.append("/** Node: " + cluster.getSupervisorById(entry.getKey()).getHost() + "-" + entry.getKey() + " **/\n");
        } else {
            str.append("/** Node: Unknown may be dead -" + entry.getKey() + " **/\n");
        }
        for (Map.Entry<String, Map<WorkerSlot, Collection<ExecutorDetails>>> topo_sched : schedulingMap.get(entry.getKey()).entrySet()) {
            str.append("\t-->Topology: " + topo_sched.getKey() + "\n");
            for (Map.Entry<WorkerSlot, Collection<ExecutorDetails>> ws : topo_sched.getValue().entrySet()) {
                str.append("\t\t->Slot [" + ws.getKey().getPort() + "] -> " + ws.getValue() + "\n");
            }
        }
    }
    return str.toString();
}
Also used : ExecutorDetails(org.apache.storm.scheduler.ExecutorDetails) HashMap(java.util.HashMap) TopologyDetails(org.apache.storm.scheduler.TopologyDetails) WorkerSlot(org.apache.storm.scheduler.WorkerSlot) Collection(java.util.Collection) HashMap(java.util.HashMap) Map(java.util.Map)

Example 27 with WorkerSlot

use of org.apache.storm.scheduler.WorkerSlot in project storm by apache.

the class DefaultResourceAwareStrategy method schedule.

public SchedulingResult schedule(TopologyDetails td) {
    if (_nodes.getNodes().size() <= 0) {
        LOG.warn("No available nodes to schedule tasks on!");
        return SchedulingResult.failure(SchedulingStatus.FAIL_NOT_ENOUGH_RESOURCES, "No available nodes to schedule tasks on!");
    }
    Collection<ExecutorDetails> unassignedExecutors = new HashSet<ExecutorDetails>(_cluster.getUnassignedExecutors(td));
    Map<WorkerSlot, Collection<ExecutorDetails>> schedulerAssignmentMap = new HashMap<>();
    LOG.debug("ExecutorsNeedScheduling: {}", unassignedExecutors);
    Collection<ExecutorDetails> scheduledTasks = new ArrayList<>();
    List<Component> spouts = this.getSpouts(td);
    if (spouts.size() == 0) {
        LOG.error("Cannot find a Spout!");
        return SchedulingResult.failure(SchedulingStatus.FAIL_INVALID_TOPOLOGY, "Cannot find a Spout!");
    }
    //order executors to be scheduled
    List<ExecutorDetails> orderedExecutors = orderExecutors(td, unassignedExecutors);
    Collection<ExecutorDetails> executorsNotScheduled = new HashSet<>(unassignedExecutors);
    for (ExecutorDetails exec : orderedExecutors) {
        LOG.debug("\n\nAttempting to schedule: {} of component {}[ REQ {} ]", exec, td.getExecutorToComponent().get(exec), td.getTaskResourceReqList(exec));
        scheduleExecutor(exec, td, schedulerAssignmentMap, scheduledTasks);
    }
    executorsNotScheduled.removeAll(scheduledTasks);
    LOG.debug("/* Scheduling left over task (most likely sys tasks) */");
    // schedule left over system tasks
    for (ExecutorDetails exec : executorsNotScheduled) {
        scheduleExecutor(exec, td, schedulerAssignmentMap, scheduledTasks);
    }
    SchedulingResult result;
    executorsNotScheduled.removeAll(scheduledTasks);
    if (executorsNotScheduled.size() > 0) {
        LOG.error("Not all executors successfully scheduled: {}", executorsNotScheduled);
        schedulerAssignmentMap = null;
        result = SchedulingResult.failure(SchedulingStatus.FAIL_NOT_ENOUGH_RESOURCES, (td.getExecutors().size() - unassignedExecutors.size()) + "/" + td.getExecutors().size() + " executors scheduled");
    } else {
        LOG.debug("All resources successfully scheduled!");
        result = SchedulingResult.successWithMsg(schedulerAssignmentMap, "Fully Scheduled by DefaultResourceAwareStrategy");
    }
    if (schedulerAssignmentMap == null) {
        LOG.error("Topology {} not successfully scheduled!", td.getId());
    }
    return result;
}
Also used : ExecutorDetails(org.apache.storm.scheduler.ExecutorDetails) HashMap(java.util.HashMap) WorkerSlot(org.apache.storm.scheduler.WorkerSlot) ArrayList(java.util.ArrayList) Collection(java.util.Collection) Component(org.apache.storm.scheduler.resource.Component) SchedulingResult(org.apache.storm.scheduler.resource.SchedulingResult) HashSet(java.util.HashSet)

Example 28 with WorkerSlot

use of org.apache.storm.scheduler.WorkerSlot in project storm by apache.

the class DefaultResourceAwareStrategy method getBestWorker.

/**
     * Get the best worker to assign executor exec on a rack
     *
     * @param exec the executor to schedule
     * @param td the topology that the executor is a part of
     * @param rackId the rack id of the rack to find a worker on
     * @param scheduleAssignmentMap already calculated assignments
     * @return a worker to assign executor exec to. Returns null if a worker cannot be successfully found on rack with rackId
     */
private WorkerSlot getBestWorker(ExecutorDetails exec, TopologyDetails td, String rackId, Map<WorkerSlot, Collection<ExecutorDetails>> scheduleAssignmentMap) {
    if (!_rackIdToSortedNodes.containsKey(rackId)) {
        _rackIdToSortedNodes.put(rackId, sortNodes(this.getAvailableNodesFromRack(rackId), rackId, td.getId(), scheduleAssignmentMap));
    }
    TreeSet<ObjectResources> sortedNodes = _rackIdToSortedNodes.get(rackId);
    double taskMem = td.getTotalMemReqTask(exec);
    double taskCPU = td.getTotalCpuReqTask(exec);
    for (ObjectResources nodeResources : sortedNodes) {
        RAS_Node n = _nodes.getNodeById(nodeResources.id);
        if (n.getAvailableCpuResources() >= taskCPU && n.getAvailableMemoryResources() >= taskMem && n.getFreeSlots().size() > 0) {
            for (WorkerSlot ws : n.getFreeSlots()) {
                if (checkWorkerConstraints(exec, ws, td, scheduleAssignmentMap)) {
                    return ws;
                }
            }
        }
    }
    return null;
}
Also used : WorkerSlot(org.apache.storm.scheduler.WorkerSlot) RAS_Node(org.apache.storm.scheduler.resource.RAS_Node)

Example 29 with WorkerSlot

use of org.apache.storm.scheduler.WorkerSlot in project storm by apache.

the class DefaultResourceAwareStrategy method sortNodes.

/**
     * Sorted Nodes
     *
     * @param availNodes            a list of all the nodes we want to sort
     * @param rackId                the rack id availNodes are a part of
     * @param topoId                the topology that we are trying to schedule
     * @param scheduleAssignmentMap calculated assignments so far
     * @return a sorted list of nodes
     * <p>
     * Nodes are sorted by two criteria. 1) the number executors of the topology that needs to be scheduled is already on the node in descending order.
     * The reasoning to sort based on criterion 1 is so we schedule the rest of a topology on the same node as the existing executors of the topology.
     * 2) the subordinate/subservient resource availability percentage of a node in descending order
     * We calculate the resource availability percentage by dividing the resource availability on the node by the resource availability of the entire rack
     * By doing this calculation, nodes that have exhausted or little of one of the resources mentioned above will be ranked after nodes that have more balanced resource availability.
     * So we will be less likely to pick a node that have a lot of one resource but a low amount of another.
     */
private TreeSet<ObjectResources> sortNodes(List<RAS_Node> availNodes, String rackId, final String topoId, final Map<WorkerSlot, Collection<ExecutorDetails>> scheduleAssignmentMap) {
    AllResources allResources = new AllResources("RACK");
    List<ObjectResources> nodes = allResources.objectResources;
    final Map<String, String> nodeIdToRackId = new HashMap<String, String>();
    for (RAS_Node ras_node : availNodes) {
        String nodeId = ras_node.getId();
        ObjectResources node = new ObjectResources(nodeId);
        double availMem = ras_node.getAvailableMemoryResources();
        double availCpu = ras_node.getAvailableCpuResources();
        int freeSlots = ras_node.totalSlotsFree();
        double totalMem = ras_node.getTotalMemoryResources();
        double totalCpu = ras_node.getTotalCpuResources();
        int totalSlots = ras_node.totalSlots();
        node.availMem = availMem;
        node.totalMem = totalMem;
        node.availCpu = availCpu;
        node.totalCpu = totalCpu;
        nodes.add(node);
        allResources.availMemResourcesOverall += availMem;
        allResources.availCpuResourcesOverall += availCpu;
        allResources.totalMemResourcesOverall += totalMem;
        allResources.totalCpuResourcesOverall += totalCpu;
    }
    LOG.debug("Rack {}: Overall Avail [ CPU {} MEM {} ] Total [ CPU {} MEM {} ]", rackId, allResources.availCpuResourcesOverall, allResources.availMemResourcesOverall, allResources.totalCpuResourcesOverall, allResources.totalMemResourcesOverall);
    return sortObjectResources(allResources, new ExistingScheduleFunc() {

        @Override
        public int getNumExistingSchedule(String objectId) {
            //Get execs already assigned in rack
            Collection<ExecutorDetails> execs = new LinkedList<ExecutorDetails>();
            if (_cluster.getAssignmentById(topoId) != null) {
                for (Map.Entry<ExecutorDetails, WorkerSlot> entry : _cluster.getAssignmentById(topoId).getExecutorToSlot().entrySet()) {
                    WorkerSlot workerSlot = entry.getValue();
                    ExecutorDetails exec = entry.getKey();
                    if (workerSlot.getNodeId().equals(objectId)) {
                        execs.add(exec);
                    }
                }
            }
            // get execs already scheduled in the current scheduling
            for (Map.Entry<WorkerSlot, Collection<ExecutorDetails>> entry : scheduleAssignmentMap.entrySet()) {
                WorkerSlot workerSlot = entry.getKey();
                if (workerSlot.getNodeId().equals(objectId)) {
                    execs.addAll(entry.getValue());
                }
            }
            return execs.size();
        }
    });
}
Also used : ExecutorDetails(org.apache.storm.scheduler.ExecutorDetails) HashMap(java.util.HashMap) RAS_Node(org.apache.storm.scheduler.resource.RAS_Node) WorkerSlot(org.apache.storm.scheduler.WorkerSlot) Collection(java.util.Collection)

Example 30 with WorkerSlot

use of org.apache.storm.scheduler.WorkerSlot in project storm by apache.

the class DefaultResourceAwareStrategy method scheduleExecutor.

/**
     * Schedule executor exec from topology td
     *
     * @param exec the executor to schedule
     * @param td the topology executor exec is a part of
     * @param schedulerAssignmentMap the assignments already calculated
     * @param scheduledTasks executors that have been scheduled
     */
private void scheduleExecutor(ExecutorDetails exec, TopologyDetails td, Map<WorkerSlot, Collection<ExecutorDetails>> schedulerAssignmentMap, Collection<ExecutorDetails> scheduledTasks) {
    WorkerSlot targetSlot = this.findWorkerForExec(exec, td, schedulerAssignmentMap);
    if (targetSlot != null) {
        RAS_Node targetNode = this.idToNode(targetSlot.getNodeId());
        if (!schedulerAssignmentMap.containsKey(targetSlot)) {
            schedulerAssignmentMap.put(targetSlot, new LinkedList<ExecutorDetails>());
        }
        schedulerAssignmentMap.get(targetSlot).add(exec);
        targetNode.consumeResourcesforTask(exec, td);
        scheduledTasks.add(exec);
        LOG.debug("TASK {} assigned to Node: {} avail [ mem: {} cpu: {} ] total [ mem: {} cpu: {} ] on slot: {} on Rack: {}", exec, targetNode.getHostname(), targetNode.getAvailableMemoryResources(), targetNode.getAvailableCpuResources(), targetNode.getTotalMemoryResources(), targetNode.getTotalCpuResources(), targetSlot, nodeToRack(targetNode));
    } else {
        LOG.error("Not Enough Resources to schedule Task {}", exec);
    }
}
Also used : ExecutorDetails(org.apache.storm.scheduler.ExecutorDetails) WorkerSlot(org.apache.storm.scheduler.WorkerSlot) RAS_Node(org.apache.storm.scheduler.resource.RAS_Node)

Aggregations

WorkerSlot (org.apache.storm.scheduler.WorkerSlot)45 HashMap (java.util.HashMap)33 ExecutorDetails (org.apache.storm.scheduler.ExecutorDetails)23 SchedulerAssignment (org.apache.storm.scheduler.SchedulerAssignment)23 ArrayList (java.util.ArrayList)22 Map (java.util.Map)22 List (java.util.List)17 SupervisorDetails (org.apache.storm.scheduler.SupervisorDetails)16 TopologyDetails (org.apache.storm.scheduler.TopologyDetails)15 HashSet (java.util.HashSet)13 SchedulerAssignmentImpl (org.apache.storm.scheduler.SchedulerAssignmentImpl)11 Topologies (org.apache.storm.scheduler.Topologies)11 Cluster (org.apache.storm.scheduler.Cluster)10 LinkedList (java.util.LinkedList)9 Config (org.apache.storm.Config)9 INimbus (org.apache.storm.scheduler.INimbus)9 Test (org.junit.Test)9 Collection (java.util.Collection)8 WorkerResources (org.apache.storm.generated.WorkerResources)8 ImmutableMap (com.google.common.collect.ImmutableMap)6