From d0f17b02fe08248e37eda5185eb6c5e40fcb1dcc Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 8 Apr 2021 10:13:20 +0200 Subject: exp: Simplify metric reporting via monitor This change simplifies the way metrics are reported to the monitor. Previously, power draw was collected separately from the other metrics. However, with the migration to OpenTelemetry, we collect all metrics every 5 minutes, which drastically simplifies the metric gathering logic. --- .../capelin/monitor/ExperimentMetricExporter.kt | 3 +- .../capelin/monitor/ExperimentMonitor.kt | 9 +- .../capelin/monitor/ParquetExperimentMonitor.kt | 128 +++------------------ .../telemetry/parquet/ParquetHostEventWriter.kt | 2 +- .../experiments/capelin/CapelinIntegrationTest.kt | 2 +- 5 files changed, 24 insertions(+), 120 deletions(-) (limited to 'simulator/opendc-experiments/opendc-experiments-capelin/src') diff --git a/simulator/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt b/simulator/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt index 799de60f..39f18a1b 100644 --- a/simulator/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt +++ b/simulator/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt @@ -89,11 +89,10 @@ public class ExperimentMetricExporter( hostMetric.interferedBurst, hostMetric.cpuUsage, hostMetric.cpuDemand, + hostMetric.powerDraw, hostMetric.numberOfDeployedImages, host ) - - monitor.reportPowerConsumption(host, hostMetric.powerDraw) } } diff --git a/simulator/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMonitor.kt b/simulator/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMonitor.kt index 5e75c890..68631dee 100644 --- a/simulator/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMonitor.kt +++ b/simulator/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMonitor.kt @@ -41,11 +41,6 @@ public interface ExperimentMonitor : AutoCloseable { */ public fun reportHostStateChange(time: Long, host: Host, newState: HostState) {} - /** - * Report the power consumption of a host. - */ - public fun reportPowerConsumption(host: Host, draw: Double) {} - /** * This method is invoked for a host for each slice that is finishes. */ @@ -57,9 +52,9 @@ public interface ExperimentMonitor : AutoCloseable { interferedBurst: Long, cpuUsage: Double, cpuDemand: Double, + powerDraw: Double, numberOfDeployedImages: Int, - host: Host, - duration: Long = 5 * 60 * 1000L + host: Host ) { } diff --git a/simulator/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ParquetExperimentMonitor.kt b/simulator/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ParquetExperimentMonitor.kt index 0e675d87..983b4cff 100644 --- a/simulator/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ParquetExperimentMonitor.kt +++ b/simulator/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ParquetExperimentMonitor.kt @@ -50,52 +50,11 @@ public class ParquetExperimentMonitor(base: File, partition: String, bufferSize: File(base, "provisioner-metrics/$partition/data.parquet"), bufferSize ) - private val currentHostEvent = mutableMapOf() - private var startTime = -1L - override fun reportVmStateChange(time: Long, server: Server, newState: ServerState) { - if (startTime < 0) { - startTime = time - - // Update timestamp of initial event - currentHostEvent.replaceAll { _, v -> v.copy(timestamp = startTime) } - } - } + override fun reportVmStateChange(time: Long, server: Server, newState: ServerState) {} override fun reportHostStateChange(time: Long, host: Host, newState: HostState) { logger.debug { "Host ${host.uid} changed state $newState [$time]" } - - val previousEvent = currentHostEvent[host] - - val roundedTime = previousEvent?.let { - val duration = time - it.timestamp - val k = 5 * 60 * 1000L // 5 min in ms - val rem = duration % k - - if (rem == 0L) { - time - } else { - it.timestamp + duration + k - rem - } - } ?: time - - reportHostSlice( - roundedTime, - 0, - 0, - 0, - 0, - 0.0, - 0.0, - 0, - host - ) - } - - private val lastPowerConsumption = mutableMapOf() - - override fun reportPowerConsumption(host: Host, draw: Double) { - lastPowerConsumption[host] = draw } override fun reportHostSlice( @@ -106,69 +65,26 @@ public class ParquetExperimentMonitor(base: File, partition: String, bufferSize: interferedBurst: Long, cpuUsage: Double, cpuDemand: Double, + powerDraw: Double, numberOfDeployedImages: Int, - host: Host, - duration: Long + host: Host ) { - val previousEvent = currentHostEvent[host] - when { - previousEvent == null -> { - val event = HostEvent( - time, - 5 * 60 * 1000L, - host, - numberOfDeployedImages, - requestedBurst, - grantedBurst, - overcommissionedBurst, - interferedBurst, - cpuUsage, - cpuDemand, - lastPowerConsumption[host] ?: 200.0, - host.model.cpuCount - ) - - currentHostEvent[host] = event - } - previousEvent.timestamp == time -> { - val event = HostEvent( - time, - previousEvent.duration, - host, - numberOfDeployedImages, - requestedBurst, - grantedBurst, - overcommissionedBurst, - interferedBurst, - cpuUsage, - cpuDemand, - lastPowerConsumption[host] ?: 200.0, - host.model.cpuCount - ) - - currentHostEvent[host] = event - } - else -> { - hostWriter.write(previousEvent) - - val event = HostEvent( - time, - time - previousEvent.timestamp, - host, - numberOfDeployedImages, - requestedBurst, - grantedBurst, - overcommissionedBurst, - interferedBurst, - cpuUsage, - cpuDemand, - lastPowerConsumption[host] ?: 200.0, - host.model.cpuCount - ) - - currentHostEvent[host] = event - } - } + hostWriter.write( + HostEvent( + time, + 5 * 60 * 1000L, + host, + numberOfDeployedImages, + requestedBurst, + grantedBurst, + overcommissionedBurst, + interferedBurst, + cpuUsage, + cpuDemand, + powerDraw, + host.model.cpuCount + ) + ) } override fun reportProvisionerMetrics( @@ -196,12 +112,6 @@ public class ParquetExperimentMonitor(base: File, partition: String, bufferSize: } override fun close() { - // Flush remaining events - for ((_, event) in currentHostEvent) { - hostWriter.write(event) - } - currentHostEvent.clear() - hostWriter.close() provisionerWriter.close() } diff --git a/simulator/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/parquet/ParquetHostEventWriter.kt b/simulator/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/parquet/ParquetHostEventWriter.kt index 4a3e7963..c8fe1cb2 100644 --- a/simulator/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/parquet/ParquetHostEventWriter.kt +++ b/simulator/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/telemetry/parquet/ParquetHostEventWriter.kt @@ -52,7 +52,7 @@ public class ParquetHostEventWriter(path: File, bufferSize: Int) : record.put("interfered_burst", event.interferedBurst) record.put("cpu_usage", event.cpuUsage) record.put("cpu_demand", event.cpuDemand) - record.put("power_draw", event.powerDraw * (1.0 / 12)) + record.put("power_draw", event.powerDraw) record.put("cores", event.cores) } diff --git a/simulator/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/simulator/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index 0441cfed..bc639765 100644 --- a/simulator/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/simulator/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -197,9 +197,9 @@ class CapelinIntegrationTest { interferedBurst: Long, cpuUsage: Double, cpuDemand: Double, + powerDraw: Double, numberOfDeployedImages: Int, host: Host, - duration: Long ) { totalRequestedBurst += requestedBurst totalGrantedBurst += grantedBurst -- cgit v1.2.3 From 41ad2f2950550fcd95a599bd8869aa191c88396a Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 8 Apr 2021 11:47:01 +0200 Subject: simulator: Divide CPU usage over all cores This change fixes an issue in SimTraceWorkload where the CPU usage was not divided across the cores, but was instead requested for all cores. --- .../org/opendc/experiments/capelin/CapelinIntegrationTest.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'simulator/opendc-experiments/opendc-experiments-capelin/src') diff --git a/simulator/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/simulator/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index bc639765..9a620fb2 100644 --- a/simulator/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/simulator/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -118,9 +118,9 @@ class CapelinIntegrationTest { { assertEquals(0, monitorResults.runningVms, "All VMs should finish after a run") }, { assertEquals(0, monitorResults.unscheduledVms, "No VM should not be unscheduled") }, { assertEquals(0, monitorResults.queuedVms, "No VM should not be in the queue") }, - { assertEquals(1672916917970, monitor.totalRequestedBurst) { "Incorrect requested burst" } }, - { assertEquals(434262255818, monitor.totalGrantedBurst) { "Incorrect granted burst" } }, - { assertEquals(1236692477983, monitor.totalOvercommissionedBurst) { "Incorrect overcommitted burst" } }, + { assertEquals(207629398281, monitor.totalRequestedBurst) { "Incorrect requested burst" } }, + { assertEquals(204986447775, monitor.totalGrantedBurst) { "Incorrect granted burst" } }, + { assertEquals(2642950497, monitor.totalOvercommissionedBurst) { "Incorrect overcommitted burst" } }, { assertEquals(0, monitor.totalInterferedBurst) { "Incorrect interfered burst" } } ) } @@ -156,9 +156,9 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(702636229989, monitor.totalRequestedBurst) { "Total requested work incorrect" } }, - { assertEquals(172636987071, monitor.totalGrantedBurst) { "Total granted work incorrect" } }, - { assertEquals(528959213229, monitor.totalOvercommissionedBurst) { "Total overcommitted work incorrect" } }, + { assertEquals(96538919775, monitor.totalRequestedBurst) { "Total requested work incorrect" } }, + { assertEquals(96519182315, monitor.totalGrantedBurst) { "Total granted work incorrect" } }, + { assertEquals(19737460, monitor.totalOvercommissionedBurst) { "Total overcommitted work incorrect" } }, { assertEquals(0, monitor.totalInterferedBurst) { "Total interfered work incorrect" } } ) } -- cgit v1.2.3 From 6a04ae25ca18f959b8f2b768c8ce2c285ed72c09 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 8 Apr 2021 12:32:11 +0200 Subject: exp: Fix metric recording of summary data This change fixes an issue in the metric exporter for summary metrics, where instead of some average value, the sum value was reported. --- .../capelin/monitor/ExperimentMetricExporter.kt | 16 +++------------- .../opendc/experiments/capelin/CapelinIntegrationTest.kt | 8 ++++---- 2 files changed, 7 insertions(+), 17 deletions(-) (limited to 'simulator/opendc-experiments/opendc-experiments-capelin/src') diff --git a/simulator/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt b/simulator/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt index 39f18a1b..5f8002e2 100644 --- a/simulator/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt +++ b/simulator/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/monitor/ExperimentMetricExporter.kt @@ -103,19 +103,9 @@ public class ExperimentMetricExporter( val hostMetric = hostMetrics[uid] if (hostMetric != null) { - block(hostMetric, point.sum) - } - } - } - - private fun mapDoubleSum(data: MetricData?, hostMetrics: MutableMap, block: (HostMetrics, Double) -> Unit) { - val points = data?.doubleSumData?.points ?: emptyList() - for (point in points) { - val uid = point.labels["host"] - val hostMetric = hostMetrics[uid] - - if (hostMetric != null) { - block(hostMetric, point.value) + // Take the average of the summary + val avg = (point.percentileValues[0].value + point.percentileValues[1].value) / 2 + block(hostMetric, avg) } } } diff --git a/simulator/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/simulator/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index 9a620fb2..d2e7473f 100644 --- a/simulator/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/simulator/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -118,8 +118,8 @@ class CapelinIntegrationTest { { assertEquals(0, monitorResults.runningVms, "All VMs should finish after a run") }, { assertEquals(0, monitorResults.unscheduledVms, "No VM should not be unscheduled") }, { assertEquals(0, monitorResults.queuedVms, "No VM should not be in the queue") }, - { assertEquals(207629398281, monitor.totalRequestedBurst) { "Incorrect requested burst" } }, - { assertEquals(204986447775, monitor.totalGrantedBurst) { "Incorrect granted burst" } }, + { assertEquals(207388095207, monitor.totalRequestedBurst) { "Incorrect requested burst" } }, + { assertEquals(204745144701, monitor.totalGrantedBurst) { "Incorrect granted burst" } }, { assertEquals(2642950497, monitor.totalOvercommissionedBurst) { "Incorrect overcommitted burst" } }, { assertEquals(0, monitor.totalInterferedBurst) { "Incorrect interfered burst" } } ) @@ -156,8 +156,8 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(96538919775, monitor.totalRequestedBurst) { "Total requested work incorrect" } }, - { assertEquals(96519182315, monitor.totalGrantedBurst) { "Total granted work incorrect" } }, + { assertEquals(96350072517, monitor.totalRequestedBurst) { "Total requested work incorrect" } }, + { assertEquals(96330335057, monitor.totalGrantedBurst) { "Total granted work incorrect" } }, { assertEquals(19737460, monitor.totalOvercommissionedBurst) { "Total overcommitted work incorrect" } }, { assertEquals(0, monitor.totalInterferedBurst) { "Total interfered work incorrect" } } ) -- cgit v1.2.3 From 638dd7a33d5f7f0b8fcca9c99cdc92819cf0847c Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 30 Mar 2021 22:42:41 +0200 Subject: exp: Add experiment for OpenDC Energy project This change adds an experiment for the OpenDC Energy project, which tests various energy models that have been implemented in OpenDC. --- .../trace/Sc20StreamingParquetTraceReader.kt | 30 +++++++++++++--------- 1 file changed, 18 insertions(+), 12 deletions(-) (limited to 'simulator/opendc-experiments/opendc-experiments-capelin/src') diff --git a/simulator/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/Sc20StreamingParquetTraceReader.kt b/simulator/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/Sc20StreamingParquetTraceReader.kt index 9ab69572..c5294b55 100644 --- a/simulator/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/Sc20StreamingParquetTraceReader.kt +++ b/simulator/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/trace/Sc20StreamingParquetTraceReader.kt @@ -57,8 +57,8 @@ private val logger = KotlinLogging.logger {} @OptIn(ExperimentalStdlibApi::class) public class Sc20StreamingParquetTraceReader( traceFile: File, - performanceInterferenceModel: PerformanceInterferenceModel, - selectedVms: List, + performanceInterferenceModel: PerformanceInterferenceModel? = null, + selectedVms: List = emptyList(), random: Random ) : TraceReader { /** @@ -229,20 +229,26 @@ public class Sc20StreamingParquetTraceReader( buffers.remove(id) } val relevantPerformanceInterferenceModelItems = - PerformanceInterferenceModel( - performanceInterferenceModel.items.filter { it.workloadNames.contains(id) }.toSortedSet(), - Random(random.nextInt()) - ) + if (performanceInterferenceModel != null) + PerformanceInterferenceModel( + performanceInterferenceModel.items.filter { it.workloadNames.contains(id) }.toSortedSet(), + Random(random.nextInt()) + ) + else + null val workload = SimTraceWorkload(fragments) + val meta = mapOf( + "cores" to maxCores, + "required-memory" to requiredMemory, + "workload" to workload + ) TraceEntry( uid, id, submissionTime, workload, - mapOf( - IMAGE_PERF_INTERFERENCE_MODEL to relevantPerformanceInterferenceModelItems, - "cores" to maxCores, - "required-memory" to requiredMemory, - "workload" to workload - ) + if (performanceInterferenceModel != null) + meta + mapOf(IMAGE_PERF_INTERFERENCE_MODEL to relevantPerformanceInterferenceModelItems as Any) + else + meta ) } .sortedBy { it.start } -- cgit v1.2.3