Search in sources :

Example 51 with PackingPlan

use of org.apache.heron.spi.packing.PackingPlan in project heron by twitter.

the class RoundRobinPacking method packInternal.

private PackingPlan packInternal(int numContainer, Map<String, Integer> parallelismMap) {
    // Get the instances' round-robin allocation
    Map<Integer, List<InstanceId>> roundRobinAllocation = getRoundRobinAllocation(numContainer, parallelismMap);
    Resource containerResourceHint = getContainerResourceHint(roundRobinAllocation);
    int largestContainerSize = getLargestContainerSize(roundRobinAllocation);
    // Get the RAM map for every instance
    ByteAmount containerRamDefault = instanceRamDefault.multiply(largestContainerSize).plus(containerRamPadding);
    Map<Integer, Map<InstanceId, ByteAmount>> instancesRamMap = calculateInstancesResourceMapInContainer(roundRobinAllocation, TopologyUtils.getComponentRamMapConfig(topology), containerResourceHint.getRam(), containerRamDefault, instanceRamDefault, containerRamPadding, ByteAmount.ZERO, NOT_SPECIFIED_BYTE_AMOUNT, RAM);
    // Get the CPU map for every instance
    float containerCPUDefault = Math.round(instanceCpuDefault * largestContainerSize + containerCpuPadding);
    Map<Integer, Map<InstanceId, CPUShare>> instancesCpuMap = calculateInstancesResourceMapInContainer(roundRobinAllocation, CPUShare.convertDoubleMapToCpuShareMap(TopologyUtils.getComponentCpuMapConfig(topology)), CPUShare.fromDouble(containerResourceHint.getCpu()), CPUShare.fromDouble(containerCPUDefault), CPUShare.fromDouble(instanceCpuDefault), CPUShare.fromDouble(containerCpuPadding), CPUShare.fromDouble(0.0), CPUShare.fromDouble(NOT_SPECIFIED_CPU_SHARE), CPU);
    LOG.info(String.format("Pack internal: container CPU hint: %.3f, RAM hint: %s, disk hint: %s.", containerResourceHint.getCpu(), containerResourceHint.getRam().toString(), containerResourceHint.getDisk().toString()));
    // Construct the PackingPlan
    Set<PackingPlan.ContainerPlan> containerPlans = new HashSet<>();
    for (int containerId : roundRobinAllocation.keySet()) {
        List<InstanceId> instanceList = roundRobinAllocation.get(containerId);
        // Calculate the resource required for single instance
        Map<InstanceId, PackingPlan.InstancePlan> instancePlanMap = new HashMap<>();
        ByteAmount containerRam = ByteAmount.ZERO;
        double containerCpu = 0.0;
        for (InstanceId instanceId : instanceList) {
            ByteAmount instanceRam = instancesRamMap.get(containerId).get(instanceId);
            Double instanceCpu = instancesCpuMap.get(containerId).get(instanceId).getValue();
            // Currently not yet support disk config for different components, just use the default.
            ByteAmount instanceDisk = instanceDiskDefault;
            Resource resource = new Resource(instanceCpu, instanceRam, instanceDisk);
            // Insert it into the map
            instancePlanMap.put(instanceId, new PackingPlan.InstancePlan(instanceId, resource));
            containerRam = containerRam.plus(instanceRam);
            containerCpu += instanceCpu;
        }
        // finalize container resource
        containerCpu += containerCpuPadding;
        if (containerResourceHint.getCpu() != NOT_SPECIFIED_CPU_SHARE) {
            containerCpu = Math.min(containerCpu, containerResourceHint.getCpu());
        }
        containerRam = containerRam.plus(containerRamPadding);
        if (!containerResourceHint.getRam().equals(NOT_SPECIFIED_BYTE_AMOUNT)) {
            containerRam = ByteAmount.fromBytes(Math.min(containerRam.asBytes(), containerResourceHint.getRam().asBytes()));
        }
        ByteAmount containerDisk = containerResourceHint.getDisk();
        if (containerDisk.equals(NOT_SPECIFIED_BYTE_AMOUNT)) {
            containerDisk = instanceDiskDefault.multiply(largestContainerSize).plus(DEFAULT_DISK_PADDING_PER_CONTAINER);
        }
        Resource resource = new Resource(Math.max(containerCpu, containerResourceHint.getCpu()), containerRam, containerDisk);
        PackingPlan.ContainerPlan containerPlan = new PackingPlan.ContainerPlan(containerId, new HashSet<>(instancePlanMap.values()), resource);
        containerPlans.add(containerPlan);
        LOG.info(String.format("Pack internal finalized: container#%d CPU: %f, RAM: %s, disk: %s.", containerId, resource.getCpu(), resource.getRam().toString(), resource.getDisk().toString()));
    }
    PackingPlan plan = new PackingPlan(topology.getId(), containerPlans);
    validatePackingPlan(plan);
    return plan;
}
Also used : ByteAmount(org.apache.heron.common.basics.ByteAmount) InstanceId(org.apache.heron.spi.packing.InstanceId) HashMap(java.util.HashMap) PackingPlan(org.apache.heron.spi.packing.PackingPlan) Resource(org.apache.heron.spi.packing.Resource) ArrayList(java.util.ArrayList) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map) HashSet(java.util.HashSet)

Example 52 with PackingPlan

use of org.apache.heron.spi.packing.PackingPlan in project heron by twitter.

the class AssertPacking method assertPackingPlan.

public static void assertPackingPlan(String expectedTopologyName, Pair<Integer, InstanceId>[] expectedComponentInstances, PackingPlan plan) {
    assertEquals(expectedTopologyName, plan.getId());
    assertEquals("Unexpected number of instances: " + plan.getContainers(), expectedComponentInstances.length, plan.getInstanceCount().intValue());
    // for every instance on a given container...
    Set<Integer> expectedContainerIds = new HashSet<>();
    for (Pair<Integer, InstanceId> expectedComponentInstance : expectedComponentInstances) {
        // verify the expected container exists
        int containerId = expectedComponentInstance.first;
        InstanceId instanceId = expectedComponentInstance.second;
        assertTrue(String.format("Container with id %s not found", containerId), plan.getContainer(containerId).isPresent());
        expectedContainerIds.add(containerId);
        // and that the instance exists on it
        boolean instanceFound = false;
        PackingPlan.ContainerPlan containerPlan = plan.getContainer(containerId).get();
        for (PackingPlan.InstancePlan instancePlan : containerPlan.getInstances()) {
            if (instancePlan.getTaskId() == instanceId.getTaskId()) {
                instanceFound = true;
                assertEquals("Wrong componentName for task " + instancePlan.getTaskId(), instanceId.getComponentName(), instancePlan.getComponentName());
                assertEquals("Wrong getComponentIndex for task " + instancePlan.getTaskId(), instanceId.getComponentIndex(), instancePlan.getComponentIndex());
                break;
            }
        }
        assertTrue(String.format("Container (%s) did not include expected instance with taskId %d", containerPlan, instanceId.getTaskId()), instanceFound);
    }
    Map<Integer, PackingPlan.InstancePlan> taskIds = new HashMap<>();
    Map<String, Set<PackingPlan.InstancePlan>> componentInstances = new HashMap<>();
    for (PackingPlan.ContainerPlan containerPlan : plan.getContainers()) {
        for (PackingPlan.InstancePlan instancePlan : containerPlan.getInstances()) {
            // check for taskId collisions
            PackingPlan.InstancePlan collisionInstance = taskIds.get(instancePlan.getTaskId());
            assertNull(String.format("Task id collision between instance %s and %s", instancePlan, collisionInstance), collisionInstance);
            taskIds.put(instancePlan.getTaskId(), instancePlan);
            // check for componentIndex collisions
            Set<PackingPlan.InstancePlan> instances = componentInstances.get(instancePlan.getComponentName());
            if (instances != null) {
                for (PackingPlan.InstancePlan instance : instances) {
                    assertTrue(String.format("Component index collision between instance %s and %s", instance, instancePlan), instance.getComponentIndex() != instancePlan.getComponentIndex());
                }
            }
            componentInstances.computeIfAbsent(instancePlan.getComponentName(), k -> new HashSet<>());
            componentInstances.get(instancePlan.getComponentName()).add(instancePlan);
        }
    }
    assertEquals(expectedContainerIds.size(), plan.getContainers().size());
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) InstanceId(org.apache.heron.spi.packing.InstanceId) HashMap(java.util.HashMap) PackingPlan(org.apache.heron.spi.packing.PackingPlan) HashSet(java.util.HashSet)

Example 53 with PackingPlan

use of org.apache.heron.spi.packing.PackingPlan in project heron by twitter.

the class RoundRobinPackingTest method testPartialRamMapWithoutContainerRequestedResources.

@Test
public void testPartialRamMapWithoutContainerRequestedResources() throws Exception {
    // Explicit set resources for container
    // max container resource is 6G
    ByteAmount containerRam = ByteAmount.fromGigabytes(6);
    ByteAmount containerDisk = ByteAmount.fromGigabytes(20);
    double containerCpu = 30;
    ByteAmount boltRam = ByteAmount.fromGigabytes(1);
    Resource containerResource = new Resource(containerCpu, containerRam, containerDisk);
    // Don't set container RAM
    topologyConfig.setContainerDiskRequested(containerDisk);
    topologyConfig.setContainerCpuRequested(containerCpu);
    topologyConfig.setComponentRam(BOLT_NAME, boltRam);
    topology = getTopology(spoutParallelism, boltParallelism, topologyConfig);
    PackingPlan packingPlan = doPackingTestWithPartialResource(topology, Optional.of(boltRam), Optional.empty(), boltParallelism, Optional.empty(), Optional.empty(), spoutParallelism, numContainers, getDefaultPadding(), containerResource);
    for (PackingPlan.ContainerPlan containerPlan : packingPlan.getContainers()) {
        // All instances' resource requirement should be equal
        // So the size of set should be 1
        Set<Resource> differentResources = new HashSet<>();
        for (PackingPlan.InstancePlan instancePlan : containerPlan.getInstances()) {
            differentResources.add(instancePlan.getResource());
        }
        int instancesCount = containerPlan.getInstances().size();
        if (instancesCount == 4) {
            // Biggest container
            Assert.assertEquals(1, differentResources.size());
        } else {
            // Smaller container
            Assert.assertEquals(2, differentResources.size());
        }
    }
}
Also used : ByteAmount(org.apache.heron.common.basics.ByteAmount) PackingPlan(org.apache.heron.spi.packing.PackingPlan) Resource(org.apache.heron.spi.packing.Resource) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 54 with PackingPlan

use of org.apache.heron.spi.packing.PackingPlan in project heron by twitter.

the class RoundRobinPackingTest method testRepackingWithMoreTotalInstances.

/**
 * test re-packing with more total instances
 */
@Test
public void testRepackingWithMoreTotalInstances() throws Exception {
    int componentParallelism = 4;
    boltParallelism = componentParallelism;
    spoutParallelism = componentParallelism;
    topology = getTopology(spoutParallelism, boltParallelism, topologyConfig);
    PackingPlan packingPlan = doPackingTestWithPartialResource(topology, Optional.empty(), Optional.empty(), boltParallelism, Optional.empty(), Optional.empty(), spoutParallelism, numContainers, getDefaultPadding(), getDefaultUnspecifiedContainerResource(boltParallelism + spoutParallelism, numContainers, getDefaultPadding()));
    Map<String, Integer> componentChanges = new HashMap<>();
    componentChanges.put(SPOUT_NAME, +1);
    componentChanges.put(BOLT_NAME, +1);
    doScalingTestWithPartialResource(topology, packingPlan, componentChanges, Optional.empty(), Optional.empty(), boltParallelism, Optional.empty(), Optional.empty(), spoutParallelism, numContainers + 1, getDefaultPadding(), getDefaultUnspecifiedContainerResource(boltParallelism + spoutParallelism, numContainers, getDefaultPadding()));
}
Also used : HashMap(java.util.HashMap) PackingPlan(org.apache.heron.spi.packing.PackingPlan) Test(org.junit.Test)

Example 55 with PackingPlan

use of org.apache.heron.spi.packing.PackingPlan in project heron by twitter.

the class RoundRobinPackingTest method testHugePartialRamMapWithoutContainerRequestedResources.

// Throw an error if default container resource (default instance resource * number of instances
// + padding) is not enough.
@Test(expected = PackingException.class)
public void testHugePartialRamMapWithoutContainerRequestedResources() throws Exception {
    // Explicit set resources for container
    ByteAmount containerRam = ByteAmount.fromGigabytes(10);
    ByteAmount containerDisk = ByteAmount.fromGigabytes(20);
    double containerCpu = 30;
    Resource containerResource = new Resource(containerCpu, containerRam, containerDisk);
    ByteAmount boltRam = ByteAmount.fromGigabytes(10);
    // Don't set container RAM
    topologyConfig.setContainerDiskRequested(containerDisk);
    topologyConfig.setContainerCpuRequested(containerCpu);
    topologyConfig.setComponentRam(BOLT_NAME, boltRam);
    topology = getTopology(spoutParallelism, boltParallelism, topologyConfig);
    PackingPlan packingPlan = doPackingTestWithPartialResource(topology, Optional.of(boltRam), Optional.empty(), boltParallelism, Optional.empty(), Optional.empty(), spoutParallelism, numContainers, getDefaultPadding(), containerResource);
    for (PackingPlan.ContainerPlan containerPlan : packingPlan.getContainers()) {
        // All instances' resource requirement should be equal
        // So the size of set should be 1
        Set<Resource> differentResources = new HashSet<>();
        for (PackingPlan.InstancePlan instancePlan : containerPlan.getInstances()) {
            differentResources.add(instancePlan.getResource());
        }
        Assert.assertEquals(1, differentResources.size());
        int instancesCount = containerPlan.getInstances().size();
        Assert.assertEquals(containerRam.minus(RoundRobinPacking.DEFAULT_RAM_PADDING_PER_CONTAINER).divide(instancesCount), differentResources.iterator().next().getRam());
        Assert.assertEquals((containerCpu - RoundRobinPacking.DEFAULT_CPU_PADDING_PER_CONTAINER) / instancesCount, differentResources.iterator().next().getCpu(), DELTA);
    }
}
Also used : ByteAmount(org.apache.heron.common.basics.ByteAmount) PackingPlan(org.apache.heron.spi.packing.PackingPlan) Resource(org.apache.heron.spi.packing.Resource) HashSet(java.util.HashSet) Test(org.junit.Test)

Aggregations

PackingPlan (org.apache.heron.spi.packing.PackingPlan)83 Test (org.junit.Test)43 HashSet (java.util.HashSet)32 Resource (org.apache.heron.spi.packing.Resource)18 Config (org.apache.heron.spi.common.Config)15 PrepareForTest (org.powermock.core.classloader.annotations.PrepareForTest)14 ByteAmount (org.apache.heron.common.basics.ByteAmount)13 HashMap (java.util.HashMap)10 SchedulerStateManagerAdaptor (org.apache.heron.spi.statemgr.SchedulerStateManagerAdaptor)9 TopologyAPI (org.apache.heron.api.generated.TopologyAPI)8 RoundRobinPacking (org.apache.heron.packing.roundrobin.RoundRobinPacking)7 InstanceId (org.apache.heron.spi.packing.InstanceId)7 Pair (org.apache.heron.common.basics.Pair)6 PackingPlans (org.apache.heron.proto.system.PackingPlans)6 PackingPlanProtoDeserializer (org.apache.heron.spi.packing.PackingPlanProtoDeserializer)6 ContainerPlan (org.apache.heron.spi.packing.PackingPlan.ContainerPlan)5 ArrayList (java.util.ArrayList)4 PackingPlanProtoSerializer (org.apache.heron.spi.packing.PackingPlanProtoSerializer)4 EvaluatorRequest (org.apache.reef.driver.evaluator.EvaluatorRequest)4 Before (org.junit.Before)3