Merge "Add efficacy indicators for workload_stabilization strategy"

This commit is contained in:
Zuul
2018-10-29 11:46:48 +00:00
committed by Gerrit Code Review
8 changed files with 117 additions and 14 deletions

View File

@@ -72,7 +72,8 @@ class EfficacySpecification(object):
}
for indicator in self.indicators_specs:
schema["properties"][indicator.name] = indicator.schema
schema["required"].append(indicator.name)
if indicator.required:
schema["required"].append(indicator.name)
return schema
def validate_efficacy_indicators(self, indicators_map):

View File

@@ -90,7 +90,7 @@ class ComputeNodesCount(IndicatorSpecification):
return {
"type": "integer",
"minimum": 0
}
}
class ReleasedComputeNodesCount(IndicatorSpecification):
@@ -106,7 +106,25 @@ class ReleasedComputeNodesCount(IndicatorSpecification):
return {
"type": "integer",
"minimum": 0
}
}
class InstancesCount(IndicatorSpecification):
def __init__(self):
super(InstancesCount, self).__init__(
name="instances_count",
description=_("The total number of audited instances in "
"strategy."),
unit=None,
required=False,
)
@property
def schema(self):
return {
"type": "integer",
"minimum": 0
}
class InstanceMigrationsCount(IndicatorSpecification):
@@ -122,7 +140,7 @@ class InstanceMigrationsCount(IndicatorSpecification):
return {
"type": "integer",
"minimum": 0
}
}
class LiveInstanceMigrateCount(IndicatorSpecification):
@@ -138,7 +156,7 @@ class LiveInstanceMigrateCount(IndicatorSpecification):
return {
"type": "integer",
"minimum": 0
}
}
class PlannedLiveInstanceMigrateCount(IndicatorSpecification):
@@ -154,7 +172,7 @@ class PlannedLiveInstanceMigrateCount(IndicatorSpecification):
return {
"type": "integer",
"minimum": 0
}
}
class ColdInstanceMigrateCount(IndicatorSpecification):
@@ -170,7 +188,7 @@ class ColdInstanceMigrateCount(IndicatorSpecification):
return {
"type": "integer",
"minimum": 0
}
}
class PlannedColdInstanceMigrateCount(IndicatorSpecification):
@@ -186,7 +204,7 @@ class PlannedColdInstanceMigrateCount(IndicatorSpecification):
return {
"type": "integer",
"minimum": 0
}
}
class VolumeMigrateCount(IndicatorSpecification):
@@ -202,7 +220,7 @@ class VolumeMigrateCount(IndicatorSpecification):
return {
"type": "integer",
"minimum": 0
}
}
class PlannedVolumeMigrateCount(IndicatorSpecification):
@@ -219,7 +237,7 @@ class PlannedVolumeMigrateCount(IndicatorSpecification):
return {
"type": "integer",
"minimum": 0
}
}
class VolumeUpdateCount(IndicatorSpecification):
@@ -236,7 +254,7 @@ class VolumeUpdateCount(IndicatorSpecification):
return {
"type": "integer",
"minimum": 0
}
}
class PlannedVolumeUpdateCount(IndicatorSpecification):
@@ -253,4 +271,38 @@ class PlannedVolumeUpdateCount(IndicatorSpecification):
return {
"type": "integer",
"minimum": 0
}
}
class StandardDeviationValue(IndicatorSpecification):
def __init__(self):
super(StandardDeviationValue, self).__init__(
name="standard_deviation_after_audit",
description=_("The value of resulted standard deviation."),
unit=None,
required=False,
)
@property
def schema(self):
return {
"type": "number",
"minimum": 0
}
class OriginalStandardDeviationValue(IndicatorSpecification):
def __init__(self):
super(OriginalStandardDeviationValue, self).__init__(
name="standard_deviation_before_audit",
description=_("The value of original standard deviation."),
unit=None,
required=False,
)
@property
def schema(self):
return {
"type": "number",
"minimum": 0
}

View File

@@ -55,6 +55,32 @@ class ServerConsolidation(base.EfficacySpecification):
return global_efficacy
class WorkloadBalancing(base.EfficacySpecification):
def get_indicators_specifications(self):
return [
indicators.InstanceMigrationsCount(),
indicators.InstancesCount(),
indicators.StandardDeviationValue(),
indicators.OriginalStandardDeviationValue()
]
def get_global_efficacy_indicator(self, indicators_map=None):
gl_indicators = []
mig_value = 0
if indicators_map and indicators_map.instance_migrations_count > 0:
mig_value = (
indicators_map.instance_migrations_count /
float(indicators_map.instances_count) * 100)
gl_indicators.append(efficacy.Indicator(
name="live_migrations_count",
description=_("Ratio of migrated virtual machines to audited "
"virtual machines"),
unit='%',
value=mig_value))
return gl_indicators
class HardwareMaintenance(base.EfficacySpecification):
def get_indicators_specifications(self):

View File

@@ -141,7 +141,7 @@ class WorkloadBalancing(base.Goal):
@classmethod
def get_efficacy_specification(cls):
"""The efficacy spec for the current goal"""
return specs.Unclassified()
return specs.WorkloadBalancing()
class AirflowOptimization(base.Goal):

View File

@@ -399,4 +399,7 @@ class StorageCapacityBalance(base.WorkloadStabilizationBaseStrategy):
"""Post-execution phase
"""
pass
self.solution.set_efficacy_indicators(
instance_migrations_count=0,
instances_count=0,
)

View File

@@ -81,6 +81,7 @@ class WorkloadBalance(base.WorkloadStabilizationBaseStrategy):
# the migration plan will be triggered when the CPU or RAM
# utilization % reaches threshold
self._meter = None
self.instance_migrations_count = 0
@classmethod
def get_name(cls):
@@ -377,6 +378,7 @@ class WorkloadBalance(base.WorkloadStabilizationBaseStrategy):
self.solution.add_action(action_type=self.MIGRATION,
resource_id=instance_src.uuid,
input_parameters=parameters)
self.instance_migrations_count += 1
def post_execute(self):
"""Post-execution phase
@@ -384,5 +386,9 @@ class WorkloadBalance(base.WorkloadStabilizationBaseStrategy):
This can be used to compute the global efficacy
"""
self.solution.model = self.compute_model
self.solution.set_efficacy_indicators(
instance_migrations_count=self.instance_migrations_count,
instances_count=len(self.compute_model.get_all_instances())
)
LOG.debug(self.compute_model.to_string())

View File

@@ -80,6 +80,10 @@ class WorkloadStabilization(base.WorkloadStabilizationBaseStrategy):
self.retry_count = None
self.periods = None
self.aggregation_method = None
self.sd_before_audit = 0
self.sd_after_audit = 0
self.instance_migrations_count = 0
self.instances_count = 0
@classmethod
def get_name(cls):
@@ -460,6 +464,7 @@ class WorkloadStabilization(base.WorkloadStabilizationBaseStrategy):
'threshold': float(self.thresholds[metric]),
'sd': metric_sd})
LOG.info("Launching workload optimization...")
self.sd_before_audit = metric_sd
return self.simulate_migrations(hosts_load)
def add_migration(self,
@@ -482,6 +487,7 @@ class WorkloadStabilization(base.WorkloadStabilizationBaseStrategy):
self.add_migration(mig_instance.uuid, 'live',
mig_source_node.uuid,
mig_destination_node.uuid)
self.instance_migrations_count += 1
def migrate(self, instance_uuid, src_host, dst_host):
mig_instance = self.compute_model.get_instance_by_uuid(instance_uuid)
@@ -545,6 +551,7 @@ class WorkloadStabilization(base.WorkloadStabilizationBaseStrategy):
self.migrate(instance_host['instance'],
instance_host['s_host'],
instance_host['host'])
self.sd_after_audit = min_sd
for metric, value in zip(self.metrics, instance_load[:-1]):
if value < float(self.thresholds[metric]):
@@ -564,4 +571,11 @@ class WorkloadStabilization(base.WorkloadStabilizationBaseStrategy):
"""
self.fill_solution()
self.solution.set_efficacy_indicators(
instance_migrations_count=self.instance_migrations_count,
standard_deviation_before_audit=self.sd_before_audit,
standard_deviation_after_audit=self.sd_after_audit,
instances_count=len(self.compute_model.get_all_instances()),
)
LOG.debug(self.compute_model.to_string())

View File

@@ -243,6 +243,7 @@ class TestWorkloadStabilization(base.TestCase):
self.strategy.thresholds = {'cpu_util': 0.042,
'memory.resident': 0.0001}
self.strategy.simulate_migrations = mock.Mock(return_value=False)
self.strategy.instance_migrations_count = 0
with mock.patch.object(self.strategy, 'migrate') as mock_migrate:
self.strategy.execute()
mock_migrate.assert_not_called()