Merge "Add efficacy indicators for workload_stabilization strategy"
This commit is contained in:
@@ -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):
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -399,4 +399,7 @@ class StorageCapacityBalance(base.WorkloadStabilizationBaseStrategy):
|
||||
"""Post-execution phase
|
||||
|
||||
"""
|
||||
pass
|
||||
self.solution.set_efficacy_indicators(
|
||||
instance_migrations_count=0,
|
||||
instances_count=0,
|
||||
)
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user