Search in sources :

Example 6 with Group

use of edu.snu.mist.core.task.groupaware.Group in project mist by snuspl.

the class FirstFitRebalancerImpl method makeBinsAndItems.

/**
 * Makes bins (event processors with the available size) and items (groups).
 * @param desirableLoad desirable load (size)
 * @param loadTable load table
 * @param eventProcessors event processors
 * @return bins and items
 */
private Tuple<Map<EventProcessor, Double>, List<Group>> makeBinsAndItems(final double desirableLoad, final Map<EventProcessor, Double> loadTable, final List<EventProcessor> eventProcessors) {
    // Make bins
    final Map<EventProcessor, Double> bins = new HashMap<>(groupAllocationTable.size());
    // Make items
    final List<Group> items = new LinkedList<>();
    for (final EventProcessor eventProcessor : eventProcessors) {
        double load = loadTable.get(eventProcessor);
        if (load > desirableLoad) {
            // Add groups until the load is less than the desirable load
            final Iterator<Group> iterator = groupAllocationTable.getValue(eventProcessor).iterator();
            while (load > desirableLoad && iterator.hasNext()) {
                final Group group = iterator.next();
                items.add(group);
                load -= group.getLoad();
            }
        }
        // Put the bin with the size
        bins.put(eventProcessor, desirableLoad - load);
    }
    return new Tuple<>(bins, items);
}
Also used : Group(edu.snu.mist.core.task.groupaware.Group) EventProcessor(edu.snu.mist.core.task.groupaware.eventprocessor.EventProcessor) Tuple(org.apache.reef.io.Tuple)

Example 7 with Group

use of edu.snu.mist.core.task.groupaware.Group in project mist by snuspl.

the class FirstFitRebalancerImpl method triggerRebalancing.

@Override
public void triggerRebalancing() {
    final List<EventProcessor> eventProcessors = groupAllocationTable.getEventProcessorsNotRunningIsolatedGroup();
    // Calculate each load and total load
    final Map<EventProcessor, Double> loadTable = new HashMap<>();
    double totalLoad = 0.0;
    for (final EventProcessor eventProcessor : eventProcessors) {
        final double load = eventProcessor.getLoad();
        totalLoad += load;
        eventProcessor.setLoad(load);
        loadTable.put(eventProcessor, load);
    }
    // Desirable load
    // Each event processor should has the load evenly
    final double desirableLoad = totalLoad * (1.0 / eventProcessors.size());
    // Make bins and items.
    final Tuple<Map<EventProcessor, Double>, List<Group>> binsAndItems = makeBinsAndItems(desirableLoad, loadTable, eventProcessors);
    // First-fit heuristic algorithm
    final Map<Group, EventProcessor> mapping = firstFitHeuristic(eventProcessors, binsAndItems.getKey(), binsAndItems.getValue());
    // Reassign the groups to the event processor
    for (final EventProcessor eventProcessor : eventProcessors) {
        final Iterator<Group> iterator = groupAllocationTable.getValue(eventProcessor).iterator();
        while (iterator.hasNext()) {
            final Group group = iterator.next();
            final EventProcessor destEP = mapping.remove(group);
            if (destEP != null) {
                iterator.remove();
                final Collection<Group> dest = groupAllocationTable.getValue(destEP);
                dest.add(group);
            }
        }
    }
    if (LOG.isLoggable(Level.FINE)) {
        final Map<EventProcessor, Double> afterRebalancingLoadTable = new HashMap<>();
        for (final EventProcessor ep : groupAllocationTable.getKeys()) {
            afterRebalancingLoadTable.put(ep, calculateLoadOfGroupsForLogging(groupAllocationTable.getValue(ep)));
        }
        LOG.log(Level.FINE, "Rebalanacing Groups (Desirable load={0}) \n" + "=========== Before LB ==========\n {1} \n" + "=========== After  LB ==========\n {2} \n", new Object[] { desirableLoad, printMap(loadTable), printMap(afterRebalancingLoadTable) });
    }
}
Also used : Group(edu.snu.mist.core.task.groupaware.Group) EventProcessor(edu.snu.mist.core.task.groupaware.eventprocessor.EventProcessor)

Example 8 with Group

use of edu.snu.mist.core.task.groupaware.Group in project mist by snuspl.

the class UtilizationLoadUpdater method updateGroupAndThreadLoad.

/**
 * Update the load of the event processor and the assigned groups.
 * @param eventProcessor event processor
 * @param groups assigned groups
 */
private void updateGroupAndThreadLoad(final EventProcessor eventProcessor, final Collection<Group> groups) {
    // boolean isOverloaded = false;
    double eventProcessorLoad = 0.0;
    final long elapsedTime = startTime - previousUpdateTime;
    final List<Group> skipGroups = new LinkedList<>();
    for (final Group group : groups) {
        double load = 0.0;
        final List<Query> queries = group.getQueries();
        final long processingEvent = group.getProcessingEvent().get();
        group.getProcessingEvent().addAndGet(-processingEvent);
        final long incomingEvent = processingEvent + group.numberOfRemainingEvents();
        final long processingEventTime = group.getProcessingTime().get();
        group.getProcessingTime().addAndGet(-processingEventTime);
        if (LOG.isLoggable(Level.FINE)) {
            LOG.log(Level.FINE, "Group {0}, ProcessingEvent: {1}, IncomingEvent: {2}, ProcessingTime: {3}", new Object[] { group.getGroupId(), processingEvent, incomingEvent, processingEventTime });
        }
        // Just use the previous load
        if (processingEventTime == 0 && incomingEvent != 0) {
            // isOverloaded = true;
            load = group.getLoad();
        } else if (incomingEvent == 0) {
            // No incoming event
            load = defaultGroupLoad;
        } else {
            // processed event, incoming event
            final double inputRate = (incomingEvent * 1000) / (double) elapsedTime;
            final double processingRate = (processingEvent * NS_UNIT) / (double) processingEventTime;
            if (processingEvent == 0 || processingRate == 0) {
                load = (1 * NS_UNIT) / (double) processingEventTime;
            } else {
                final double groupLoad = Math.min(1.5, inputRate / processingRate);
                load = groupLoad;
            }
            if (LOG.isLoggable(Level.FINE)) {
                LOG.log(Level.FINE, "Group {0}, InputRate: {1}, ProcessingRate: {2}, GroupLoad: {3}", new Object[] { group.getGroupId(), inputRate, processingRate, load });
            }
        }
        eventProcessorLoad += load;
        group.setLoad(load);
        // Calculate query load based on the group load!
        for (final Query query : queries) {
            // Number of processed events
            final long queryProcessingEvent = query.getProcessingEvent().get();
            query.getProcessingEvent().getAndAdd(-queryProcessingEvent);
            final long incomingE = query.numberOfRemainingEvents();
            final long queryIncomingEvent = incomingE + queryProcessingEvent;
            if (incomingEvent == 0) {
                query.setLoad(0);
            } else {
                query.setLoad(load * (queryIncomingEvent / (double) incomingEvent));
            }
        }
    }
    eventProcessor.setLoad(eventProcessorLoad);
// Overloaded!
/*
    if (isOverloaded) {
      eventProcessor.setLoad(1.0);
      // distribute the load
      final int size = groups.size();
      final double balancedLoad = 1.0 / size;

      for (final Group group : groups) {
        group.setLoad(balancedLoad);
        final int querySize = group.getQueries().size();
        final double queryLoad = balancedLoad / querySize;
        for (final Query query : group.getQueries()) {
          query.setLoad(queryLoad);
        }
      }
    } else {
      eventProcessor.setLoad(eventProcessorLoad);
    }
    */
}
Also used : Group(edu.snu.mist.core.task.groupaware.Group) Query(edu.snu.mist.core.task.Query) LinkedList(java.util.LinkedList)

Example 9 with Group

use of edu.snu.mist.core.task.groupaware.Group in project mist by snuspl.

the class DefaultGroupMergerImpl method logging.

private void logging(final List<EventProcessor> eventProcessors, final Map<EventProcessor, Double> loadTable) {
    final StringBuilder sb = new StringBuilder();
    sb.append("-------------- TABLE ----------------\n");
    for (final EventProcessor ep : eventProcessors) {
        final Collection<Group> groups = groupAllocationTable.getValue(ep);
        sb.append(ep);
        sb.append(" -> [");
        sb.append(loadTable.get(ep));
        sb.append("], [");
        sb.append(groups.size());
        sb.append("], ");
        sb.append(groups);
        sb.append("\n");
    }
    LOG.info(sb.toString());
}
Also used : Group(edu.snu.mist.core.task.groupaware.Group) EventProcessor(edu.snu.mist.core.task.groupaware.eventprocessor.EventProcessor)

Example 10 with Group

use of edu.snu.mist.core.task.groupaware.Group in project mist by snuspl.

the class DefaultGroupRebalancerImpl method triggerRebalancing.

@Override
public void triggerRebalancing() {
    LOG.info("REBALANCING START");
    long rebalanceStart = System.currentTimeMillis();
    try {
        // Skip if it is an isolated processor that runs an isolated group
        final List<EventProcessor> eventProcessors = groupAllocationTable.getEventProcessorsNotRunningIsolatedGroup();
        // Overloaded threads
        final List<EventProcessor> overloadedThreads = new LinkedList<>();
        // Underloaded threads
        final PriorityQueue<EventProcessor> underloadedThreads = new PriorityQueue<>(new Comparator<EventProcessor>() {

            @Override
            public int compare(final EventProcessor o1, final EventProcessor o2) {
                final Double load1 = o1.getLoad();
                final Double load2 = o2.getLoad();
                return load1.compareTo(load2);
            }
        });
        // Calculate each load and total load
        for (final EventProcessor eventProcessor : eventProcessors) {
            final double load = eventProcessor.getLoad();
            if (load > beta) {
                overloadedThreads.add(eventProcessor);
            } else if (load < alpha) {
                underloadedThreads.add(eventProcessor);
            }
        }
        // LOGGING
        // logging(eventProcessors, loadTable);
        double targetLoad = (alpha + beta) / 2;
        int rebNum = 0;
        Collections.sort(overloadedThreads, new Comparator<EventProcessor>() {

            @Override
            public int compare(final EventProcessor o1, final EventProcessor o2) {
                return o1.getLoad() < o2.getLoad() ? 1 : -1;
            }
        });
        if (!overloadedThreads.isEmpty() && !underloadedThreads.isEmpty()) {
            for (final EventProcessor highLoadThread : overloadedThreads) {
                final Collection<Group> highLoadGroups = groupAllocationTable.getValue(highLoadThread);
                final List<Group> sortedHighLoadGroups = new LinkedList<>(highLoadGroups);
                Collections.sort(sortedHighLoadGroups, new Comparator<Group>() {

                    @Override
                    public int compare(final Group o1, final Group o2) {
                        if (o1.isSplited() && !o2.isSplited()) {
                            return -1;
                        } else if (!o1.isSplited() && o2.isSplited()) {
                            return 1;
                        } else {
                            if (o1.getLoad() < o2.getLoad()) {
                                return -1;
                            } else {
                                return 1;
                            }
                        }
                    }
                });
                for (final Group highLoadGroup : sortedHighLoadGroups) {
                    // do not move a group if it is already moved before GROUP_PINNING_TIME
                    if (System.currentTimeMillis() - highLoadGroup.getLatestMovedTime() >= TimeUnit.SECONDS.toMillis(groupPinningTime)) {
                        final double groupLoad = highLoadGroup.getLoad();
                        if (!highLoadGroup.isSplited()) {
                            // Rebalance!!!
                            if (highLoadThread.getLoad() - groupLoad >= targetLoad) {
                                final EventProcessor peek = underloadedThreads.peek();
                                if (peek.getLoad() + groupLoad <= targetLoad) {
                                    final EventProcessor lowLoadThread = underloadedThreads.poll();
                                    moveGroup(highLoadGroup, highLoadGroups, highLoadThread, lowLoadThread, underloadedThreads);
                                    rebNum += 1;
                                    highLoadGroup.setLatestMovedTime(System.currentTimeMillis());
                                    // Prevent lots of groups from being reassigned
                                    if (rebNum >= TimeUnit.MILLISECONDS.toSeconds(rebalancingPeriod)) {
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
                // Prevent lots of groups from being reassigned
                if (rebNum >= TimeUnit.MILLISECONDS.toSeconds(rebalancingPeriod)) {
                    break;
                }
            }
        }
        long rebalanceEnd = System.currentTimeMillis();
        LOG.log(Level.INFO, "Rebalancing number: {0}, elapsed time: {1}", new Object[] { rebNum, rebalanceEnd - rebalanceStart });
    // LOG.log(Level.INFO, "-------------TABLE-------------\n{0}",
    // new Object[]{groupAllocationTable.toString()});
    } catch (final Exception e) {
        LOG.log(Level.WARNING, "Exception " + e);
        e.printStackTrace();
        throw new RuntimeException(e);
    }
}
Also used : Group(edu.snu.mist.core.task.groupaware.Group) EventProcessor(edu.snu.mist.core.task.groupaware.eventprocessor.EventProcessor)

Aggregations

Group (edu.snu.mist.core.task.groupaware.Group)15 EventProcessor (edu.snu.mist.core.task.groupaware.eventprocessor.EventProcessor)9 Query (edu.snu.mist.core.task.Query)2 Operator (edu.snu.mist.core.operators.Operator)1 StateHandler (edu.snu.mist.core.operators.StateHandler)1 DefaultPhysicalOperatorImpl (edu.snu.mist.core.task.DefaultPhysicalOperatorImpl)1 ExecutionDag (edu.snu.mist.core.task.ExecutionDag)1 ExecutionVertex (edu.snu.mist.core.task.ExecutionVertex)1 GroupCheckpoint (edu.snu.mist.formats.avro.GroupCheckpoint)1 File (java.io.File)1 IOException (java.io.IOException)1 LinkedList (java.util.LinkedList)1 DataFileWriter (org.apache.avro.file.DataFileWriter)1 Tuple (org.apache.reef.io.Tuple)1 Injector (org.apache.reef.tang.Injector)1 JavaConfigurationBuilder (org.apache.reef.tang.JavaConfigurationBuilder)1