Search in sources :

Example 11 with EventProcessor

use of edu.snu.mist.core.task.groupaware.eventprocessor.EventProcessor 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 12 with EventProcessor

use of edu.snu.mist.core.task.groupaware.eventprocessor.EventProcessor 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 13 with EventProcessor

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

the class DefaultTaskStatsUpdater method updateTaskStatsToMaster.

@Override
public void updateTaskStatsToMaster(final GroupAllocationTable groupAllocationTable) throws AvroRemoteException {
    final List<EventProcessor> epList = new ArrayList<>(groupAllocationTable.getKeys());
    final int numEventProcessors = epList.size();
    final List<Group> groupList = new ArrayList<>();
    // Get the whole group list.
    for (final EventProcessor ep : epList) {
        groupList.addAll(groupAllocationTable.getValue(ep));
    }
    double totalLoad = 0.0;
    final Map<String, GroupStats> groupStatsMap = new HashMap<>();
    for (final Group group : groupList) {
        groupStatsMap.put(group.getGroupId(), GroupStats.newBuilder().setGroupLoad(group.getLoad()).setAppId(group.getApplicationInfo().getApplicationId()).setGroupQueryNum(group.getQueries().size()).setGroupId(group.getGroupId()).build());
        totalLoad += group.getLoad();
    }
    final double taskCpuLoad = totalLoad / numEventProcessors;
    proxyToMaster.updateTaskStats(taskId, TaskStats.newBuilder().setTaskLoad(taskCpuLoad).setGroupStatsMap(groupStatsMap).build());
}
Also used : HashMap(java.util.HashMap) EventProcessor(edu.snu.mist.core.task.groupaware.eventprocessor.EventProcessor) ArrayList(java.util.ArrayList) GroupStats(edu.snu.mist.formats.avro.GroupStats)

Example 14 with EventProcessor

use of edu.snu.mist.core.task.groupaware.eventprocessor.EventProcessor 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.getLoad() < o2.getLoad()) {
                            return -1;
                        } else if (o1.getLoad() > o2.getLoad()) {
                            return 1;
                        } else {
                            return 0;
                        }
                    }
                });
                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();
                        // Just rebalance
                        if (!highLoadGroup.isSplited()) {
                            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;
                                    }
                                }
                            }
                        } else {
                            // Merge splitted group
                            // 1. find the thread that has the lowest load among threads that hold the splitted groups
                            final Group lowLoadGroup = findLowestLoadThreadSplittedGroup(highLoadGroup);
                            // 2. Check we can move the high load group to the low load thread group
                            if (lowLoadGroup != null && lowLoadGroup != highLoadGroup && highLoadGroup.getEventProcessor().getLoad() - groupLoad >= targetLoad && lowLoadGroup.getEventProcessor().getLoad() + groupLoad <= targetLoad) {
                                // 3. merge!
                                if (merge(highLoadGroup, highLoadGroups, highLoadThread, lowLoadGroup)) {
                                    rebNum += 1;
                                    highLoadGroups.remove(highLoadGroup);
                                }
                                // 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)

Example 15 with EventProcessor

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

the class FirstFitRebalancerImpl method firstFitHeuristic.

private Map<Group, EventProcessor> firstFitHeuristic(final List<EventProcessor> eventProcessors, final Map<EventProcessor, Double> bins, final List<Group> items) {
    final Map<Group, EventProcessor> mapping = new HashMap<>(items.size());
    final Iterator<Group> iterator = items.iterator();
    while (iterator.hasNext()) {
        final Group item = iterator.next();
        // find the first bin that can hold the item
        for (final EventProcessor eventProcessor : eventProcessors) {
            final double size = bins.get(eventProcessor);
            final double itemSize = item.getLoad();
            if (size >= itemSize) {
                // This is the first bin that can hold the item!
                iterator.remove();
                mapping.put(item, eventProcessor);
                bins.put(eventProcessor, size - itemSize);
                break;
            }
        }
    }
    if (!items.isEmpty()) {
        // Second
        final Iterator<Group> secondIter = items.iterator();
        while (secondIter.hasNext()) {
            final Group item = secondIter.next();
            // find the first bin that can hold the item
            for (final EventProcessor eventProcessor : eventProcessors) {
                final double size = bins.get(eventProcessor);
                final double itemSize = item.getLoad();
                if (size > 0) {
                    // This is the first bin that can hold the item!
                    secondIter.remove();
                    mapping.put(item, eventProcessor);
                    bins.put(eventProcessor, size - itemSize);
                    break;
                }
            }
        }
    }
    if (!items.isEmpty()) {
        throw new RuntimeException("First-fit algorithm is incorrect");
    }
    return mapping;
}
Also used : Group(edu.snu.mist.core.task.groupaware.Group) EventProcessor(edu.snu.mist.core.task.groupaware.eventprocessor.EventProcessor)

Aggregations

EventProcessor (edu.snu.mist.core.task.groupaware.eventprocessor.EventProcessor)19 Group (edu.snu.mist.core.task.groupaware.Group)9 Injector (org.apache.reef.tang.Injector)5 JavaConfigurationBuilder (org.apache.reef.tang.JavaConfigurationBuilder)5 Test (org.junit.Test)5 DefaultEventProcessorFactory (edu.snu.mist.core.task.groupaware.eventprocessor.DefaultEventProcessorFactory)4 EventProcessorFactory (edu.snu.mist.core.task.groupaware.eventprocessor.EventProcessorFactory)4 LoadUpdater (edu.snu.mist.core.task.groupaware.rebalancer.LoadUpdater)4 LinkedList (java.util.LinkedList)4 Query (edu.snu.mist.core.task.Query)2 GroupRebalancer (edu.snu.mist.core.task.groupaware.rebalancer.GroupRebalancer)2 List (java.util.List)2 DefaultQueryImpl (edu.snu.mist.core.task.DefaultQueryImpl)1 SourceOutputEmitter (edu.snu.mist.core.task.SourceOutputEmitter)1 DefaultEventProcessor (edu.snu.mist.core.task.groupaware.eventprocessor.DefaultEventProcessor)1 NextGroupSelector (edu.snu.mist.core.task.groupaware.eventprocessor.NextGroupSelector)1 GroupMerger (edu.snu.mist.core.task.groupaware.rebalancer.GroupMerger)1 GroupSplitter (edu.snu.mist.core.task.groupaware.rebalancer.GroupSplitter)1 GroupCheckpoint (edu.snu.mist.formats.avro.GroupCheckpoint)1 GroupStats (edu.snu.mist.formats.avro.GroupStats)1