use of org.apache.storm.metric.StormMetricsRegistry in project storm by apache.
the class TestResourceAwareScheduler method testMultipleUsers.
@Test
public void testMultipleUsers() {
INimbus iNimbus = new INimbusTest();
Map<String, SupervisorDetails> supMap = genSupervisors(20, 4, 1000, 1024 * 10);
Map<String, Map<String, Number>> resourceUserPool = userResourcePool(userRes("jerry", 1_000, 8_192), userRes("bobby", 10_000, 32_768), userRes("derek", 5_000, 16_384));
Config config = createClusterConfig(10, 128, 0, resourceUserPool);
Topologies topologies = new Topologies(genTopology("topo-1", config, 5, 15, 1, 1, currentTime - 2, 20, "jerry"), genTopology("topo-2", config, 5, 15, 1, 1, currentTime - 8, 29, "jerry"), genTopology("topo-3", config, 5, 15, 1, 1, currentTime - 16, 29, "jerry"), genTopology("topo-4", config, 5, 15, 1, 1, currentTime - 16, 20, "jerry"), genTopology("topo-5", config, 5, 15, 1, 1, currentTime - 24, 29, "jerry"), genTopology("topo-6", config, 5, 15, 1, 1, currentTime - 2, 20, "bobby"), genTopology("topo-7", config, 5, 15, 1, 1, currentTime - 8, 29, "bobby"), genTopology("topo-8", config, 5, 15, 1, 1, currentTime - 16, 29, "bobby"), genTopology("topo-9", config, 5, 15, 1, 1, currentTime - 16, 20, "bobby"), genTopology("topo-10", config, 5, 15, 1, 1, currentTime - 24, 29, "bobby"), genTopology("topo-11", config, 5, 15, 1, 1, currentTime - 2, 20, "derek"), genTopology("topo-12", config, 5, 15, 1, 1, currentTime - 8, 29, "derek"), genTopology("topo-13", config, 5, 15, 1, 1, currentTime - 16, 29, "derek"), genTopology("topo-14", config, 5, 15, 1, 1, currentTime - 16, 20, "derek"), genTopology("topo-15", config, 5, 15, 1, 1, currentTime - 24, 29, "derek"));
Cluster cluster = new Cluster(iNimbus, new ResourceMetrics(new StormMetricsRegistry()), supMap, new HashMap<>(), topologies, config);
scheduler = new ResourceAwareScheduler();
scheduler.prepare(config, new StormMetricsRegistry());
scheduler.schedule(topologies, cluster);
for (TopologyDetails td : topologies) {
assertTopologiesFullyScheduled(cluster, td.getName());
}
}
use of org.apache.storm.metric.StormMetricsRegistry in project storm by apache.
the class TestResourceAwareScheduler method testRASNodeSlotAssign.
@Test
public void testRASNodeSlotAssign() {
Config config = new Config();
config.putAll(defaultTopologyConf);
INimbus iNimbus = new INimbusTest();
Map<String, SupervisorDetails> supMap = genSupervisors(5, 4, 400, 2000);
TopologyDetails topology1 = genTopology("topology1", config, 1, 0, 2, 0, 0, 0, "user");
TopologyDetails topology2 = genTopology("topology2", config, 1, 0, 2, 0, 0, 0, "user");
Topologies topologies = new Topologies(topology1, topology2);
Cluster cluster = new Cluster(iNimbus, new ResourceMetrics(new StormMetricsRegistry()), supMap, new HashMap<>(), topologies, config);
Map<String, RasNode> nodes = RasNodes.getAllNodesFrom(cluster);
assertEquals(5, nodes.size());
RasNode node = nodes.get("r000s000");
assertEquals("r000s000", node.getId());
assertTrue(node.isAlive());
assertEquals(0, node.getRunningTopologies().size());
assertTrue(node.isTotallyFree());
assertEquals(4, node.totalSlotsFree());
assertEquals(0, node.totalSlotsUsed());
assertEquals(4, node.totalSlots());
List<ExecutorDetails> executors11 = new ArrayList<>();
executors11.add(new ExecutorDetails(1, 1));
node.assign(node.getFreeSlots().iterator().next(), topology1, executors11);
assertEquals(1, node.getRunningTopologies().size());
assertFalse(node.isTotallyFree());
assertEquals(3, node.totalSlotsFree());
assertEquals(1, node.totalSlotsUsed());
assertEquals(4, node.totalSlots());
List<ExecutorDetails> executors12 = new ArrayList<>();
executors12.add(new ExecutorDetails(2, 2));
node.assign(node.getFreeSlots().iterator().next(), topology1, executors12);
assertEquals(1, node.getRunningTopologies().size());
assertFalse(node.isTotallyFree());
assertEquals(2, node.totalSlotsFree());
assertEquals(2, node.totalSlotsUsed());
assertEquals(4, node.totalSlots());
List<ExecutorDetails> executors21 = new ArrayList<>();
executors21.add(new ExecutorDetails(1, 1));
node.assign(node.getFreeSlots().iterator().next(), topology2, executors21);
assertEquals(2, node.getRunningTopologies().size());
assertFalse(node.isTotallyFree());
assertEquals(1, node.totalSlotsFree());
assertEquals(3, node.totalSlotsUsed());
assertEquals(4, node.totalSlots());
List<ExecutorDetails> executors22 = new ArrayList<>();
executors22.add(new ExecutorDetails(2, 2));
node.assign(node.getFreeSlots().iterator().next(), topology2, executors22);
assertEquals(2, node.getRunningTopologies().size());
assertFalse(node.isTotallyFree());
assertEquals(0, node.totalSlotsFree());
assertEquals(4, node.totalSlotsUsed());
assertEquals(4, node.totalSlots());
node.freeAllSlots();
assertEquals(0, node.getRunningTopologies().size());
assertTrue(node.isTotallyFree());
assertEquals(4, node.totalSlotsFree());
assertEquals(0, node.totalSlotsUsed());
assertEquals(4, node.totalSlots());
}
use of org.apache.storm.metric.StormMetricsRegistry in project storm by apache.
the class TestUser method testResourcePoolUtilization.
@Test
public void testResourcePoolUtilization() {
INimbus iNimbus = new INimbusTest();
Map<String, SupervisorDetails> supMap = genSupervisors(4, 4, 100, 1000);
Double cpuGuarantee = 400.0;
Double memoryGuarantee = 1000.0;
Map<String, Map<String, Number>> resourceUserPool = userResourcePool(userRes("user1", cpuGuarantee, memoryGuarantee));
Config config = createClusterConfig(100, 200, 200, resourceUserPool);
TopologyDetails topo1 = genTopology("topo-1", config, 1, 1, 2, 1, Time.currentTimeSecs() - 24, 9, "user1");
Topologies topologies = new Topologies(topo1);
Cluster cluster = new Cluster(iNimbus, new ResourceMetrics(new StormMetricsRegistry()), supMap, new HashMap<>(), topologies, config);
User user1 = new User("user1", toDouble(resourceUserPool.get("user1")));
WorkerSlot slot = cluster.getAvailableSlots().get(0);
cluster.assign(slot, topo1.getId(), topo1.getExecutors());
Assert.assertEquals("check cpu resource guarantee", cpuGuarantee, user1.getCpuResourceGuaranteed(), 0.001);
Assert.assertEquals("check memory resource guarantee", memoryGuarantee, user1.getMemoryResourceGuaranteed(), 0.001);
Assert.assertEquals("check cpu resource pool utilization", ((100.0 * 3.0) / cpuGuarantee), user1.getCpuResourcePoolUtilization(cluster), 0.001);
Assert.assertEquals("check memory resource pool utilization", ((200.0 + 200.0) * 3.0) / memoryGuarantee, user1.getMemoryResourcePoolUtilization(cluster), 0.001);
}
use of org.apache.storm.metric.StormMetricsRegistry in project storm by apache.
the class TestNodeSorterHostProximity method testAntiAffinityWithMultipleTopologies.
/**
* Schedule two topologies, once with special resources and another without.
* There are enough special resources to hold one topology with special resource ("my.gpu").
* If the sort order is incorrect, scheduling will not succeed.
*/
@Test
public void testAntiAffinityWithMultipleTopologies() {
INimbus iNimbus = new INimbusTest();
Map<String, SupervisorDetails> supMap = genSupervisorsWithRacks(1, 40, 66, 0, 0, 4700, 226200, new HashMap<>());
HashMap<String, Double> extraResources = new HashMap<>();
extraResources.put("my.gpu", 1.0);
supMap.putAll(genSupervisorsWithRacks(1, 40, 66, 1, 0, 4700, 226200, extraResources));
Config config = new Config();
config.putAll(createGrasClusterConfig(88, 775, 25, null, null));
IScheduler scheduler = new ResourceAwareScheduler();
scheduler.prepare(config, new StormMetricsRegistry());
TopologyDetails tdSimple = genTopology("topology-simple", config, 1, 5, 100, 300, 0, 0, "user", 8192);
// Schedule the simple topology first
Topologies topologies = new Topologies(tdSimple);
Cluster cluster = new Cluster(iNimbus, new ResourceMetrics(new StormMetricsRegistry()), supMap, new HashMap<>(), topologies, config);
{
NodeSorterHostProximity nodeSorter = new NodeSorterHostProximity(cluster, tdSimple);
for (ExecutorDetails exec : tdSimple.getExecutors()) {
nodeSorter.prepare(exec);
List<ObjectResourcesItem> sortedRacks = StreamSupport.stream(nodeSorter.getSortedRacks().spliterator(), false).collect(Collectors.toList());
String rackSummaries = StreamSupport.stream(sortedRacks.spliterator(), false).map(x -> String.format("Rack %s -> scheduled-cnt %d, min-avail %f, avg-avail %f, cpu %f, mem %f", x.id, nodeSorter.getScheduledExecCntByRackId().getOrDefault(x.id, new AtomicInteger(-1)).get(), x.minResourcePercent, x.avgResourcePercent, x.availableResources.getTotalCpu(), x.availableResources.getTotalMemoryMb())).collect(Collectors.joining("\n\t"));
NormalizedResourceRequest topoResourceRequest = tdSimple.getApproximateTotalResources();
String topoRequest = String.format("Topo %s, approx-requested-resources %s", tdSimple.getId(), topoResourceRequest.toString());
Assert.assertEquals(rackSummaries + "\n# of racks sorted", 2, sortedRacks.size());
Assert.assertEquals(rackSummaries + "\nFirst rack sorted", "rack-000", sortedRacks.get(0).id);
Assert.assertEquals(rackSummaries + "\nSecond rack sorted", "rack-001", sortedRacks.get(1).id);
}
}
scheduler.schedule(topologies, cluster);
TopologyBuilder builder = topologyBuilder(1, 5, 100, 300);
builder.setBolt("gpu-bolt", new TestBolt(), 40).addResource("my.gpu", 1.0).shuffleGrouping("spout-0");
TopologyDetails tdGpu = topoToTopologyDetails("topology-gpu", config, builder.createTopology(), 0, 0, "user", 8192);
// Now schedule GPU but with the simple topology in place.
topologies = new Topologies(tdSimple, tdGpu);
cluster = new Cluster(cluster, topologies);
{
NodeSorterHostProximity nodeSorter = new NodeSorterHostProximity(cluster, tdGpu);
for (ExecutorDetails exec : tdGpu.getExecutors()) {
String comp = tdGpu.getComponentFromExecutor(exec);
nodeSorter.prepare(exec);
List<ObjectResourcesItem> sortedRacks = StreamSupport.stream(nodeSorter.getSortedRacks().spliterator(), false).collect(Collectors.toList());
String rackSummaries = sortedRacks.stream().map(x -> String.format("Rack %s -> scheduled-cnt %d, min-avail %f, avg-avail %f, cpu %f, mem %f", x.id, nodeSorter.getScheduledExecCntByRackId().getOrDefault(x.id, new AtomicInteger(-1)).get(), x.minResourcePercent, x.avgResourcePercent, x.availableResources.getTotalCpu(), x.availableResources.getTotalMemoryMb())).collect(Collectors.joining("\n\t"));
NormalizedResourceRequest topoResourceRequest = tdSimple.getApproximateTotalResources();
String topoRequest = String.format("Topo %s, approx-requested-resources %s", tdSimple.getId(), topoResourceRequest.toString());
Assert.assertEquals(rackSummaries + "\n# of racks sorted", 2, sortedRacks.size());
if (comp.equals("gpu-bolt")) {
Assert.assertEquals(rackSummaries + "\nFirst rack sorted for " + comp, "rack-001", sortedRacks.get(0).id);
Assert.assertEquals(rackSummaries + "\nSecond rack sorted for " + comp, "rack-000", sortedRacks.get(1).id);
} else {
Assert.assertEquals(rackSummaries + "\nFirst rack sorted for " + comp, "rack-000", sortedRacks.get(0).id);
Assert.assertEquals(rackSummaries + "\nSecond rack sorted for " + comp, "rack-001", sortedRacks.get(1).id);
}
}
}
scheduler.schedule(topologies, cluster);
Map<String, SchedulerAssignment> assignments = new TreeMap<>(cluster.getAssignments());
assertEquals(2, assignments.size());
Map<String, Map<String, AtomicLong>> topoPerRackCount = new HashMap<>();
for (Map.Entry<String, SchedulerAssignment> entry : assignments.entrySet()) {
SchedulerAssignment sa = entry.getValue();
Map<String, AtomicLong> slotsPerRack = new TreeMap<>();
for (WorkerSlot slot : sa.getSlots()) {
String nodeId = slot.getNodeId();
String rack = supervisorIdToRackName(nodeId);
slotsPerRack.computeIfAbsent(rack, (r) -> new AtomicLong(0)).incrementAndGet();
}
LOG.info("{} => {}", entry.getKey(), slotsPerRack);
topoPerRackCount.put(entry.getKey(), slotsPerRack);
}
Map<String, AtomicLong> simpleCount = topoPerRackCount.get("topology-simple-0");
assertNotNull(simpleCount);
// Because the simple topology was scheduled first we want to be sure that it didn't put anything on
// the GPU nodes.
// Only 1 rack is in use
assertEquals(1, simpleCount.size());
// r001 is the second rack with GPUs
assertFalse(simpleCount.containsKey("r001"));
// r000 is the first rack with no GPUs
assertTrue(simpleCount.containsKey("r000"));
// We don't really care too much about the scheduling of topology-gpu-0, because it was scheduled.
}
use of org.apache.storm.metric.StormMetricsRegistry in project storm by apache.
the class TestNodeSorterHostProximity method testFillUpRackAndSpilloverToNextRack.
/**
* If the topology is too large for one rack, it should be partially scheduled onto the next rack (and next rack only).
*/
@Test
public void testFillUpRackAndSpilloverToNextRack() {
INimbus iNimbus = new INimbusTest();
double compPcore = 100;
double compOnHeap = 775;
double compOffHeap = 25;
int topo1NumSpouts = 1;
int topo1NumBolts = 5;
int topo1SpoutParallelism = 100;
int topo1BoltParallelism = 200;
final int numRacks = 3;
final int numSupersPerRack = 10;
final int numPortsPerSuper = 6;
final int numZonesPerHost = 1;
final double numaResourceMultiplier = 1.0;
int rackStartNum = 0;
int supStartNum = 0;
// not enough for topo1
long compPerRack = (topo1NumSpouts * topo1SpoutParallelism + topo1NumBolts * topo1BoltParallelism) * 4 / 5;
long compPerSuper = compPerRack / numSupersPerRack;
double cpuPerSuper = compPcore * compPerSuper;
double memPerSuper = (compOnHeap + compOffHeap) * compPerSuper;
double topo1MaxHeapSize = memPerSuper;
final String topoName1 = "topology1";
Map<String, SupervisorDetails> supMap = genSupervisorsWithRacksAndNuma(numRacks, numSupersPerRack, numZonesPerHost, numPortsPerSuper, rackStartNum, supStartNum, cpuPerSuper, memPerSuper, Collections.emptyMap(), numaResourceMultiplier);
TestDNSToSwitchMapping testDNSToSwitchMapping = new TestDNSToSwitchMapping(supMap.values());
Config config = new Config();
config.putAll(createGrasClusterConfig(compPcore, compOnHeap, compOffHeap, null, null));
config.put(Config.TOPOLOGY_SCHEDULER_STRATEGY, GenericResourceAwareStrategy.class.getName());
IScheduler scheduler = new ResourceAwareScheduler();
scheduler.prepare(config, new StormMetricsRegistry());
TopologyDetails td1 = genTopology(topoName1, config, topo1NumSpouts, topo1NumBolts, topo1SpoutParallelism, topo1BoltParallelism, 0, 0, "user", topo1MaxHeapSize);
// Schedule the topo1 topology and ensure it fits on 2 racks
Topologies topologies = new Topologies(td1);
Cluster cluster = new Cluster(iNimbus, new ResourceMetrics(new StormMetricsRegistry()), supMap, new HashMap<>(), topologies, config);
cluster.setNetworkTopography(testDNSToSwitchMapping.getRackToHosts());
scheduler.schedule(topologies, cluster);
Set<String> assignedRacks = cluster.getAssignedRacks(td1.getId());
assertEquals("Racks for topology=" + td1.getId() + " is " + assignedRacks, 2, assignedRacks.size());
}
Aggregations