diff --git a/doc/source/strategies/workload-stabilization.rst b/doc/source/strategies/workload-stabilization.rst index 2e872ebe4..c3eafec18 100644 --- a/doc/source/strategies/workload-stabilization.rst +++ b/doc/source/strategies/workload-stabilization.rst @@ -92,12 +92,22 @@ parameter type default Value description host from list. ``retry_count`` number 1 Count of random returned hosts. +``periods`` object |periods| These periods are used to get + statistic aggregation for + instance and host metrics. + The period is simply a + repeating interval of time + into which the samples are + grouped for aggregation. + Watcher uses only the last + period of all recieved ones. ==================== ====== ===================== ============================= .. |metrics| replace:: ["cpu_util", "memory.resident"] .. |thresholds| replace:: {"cpu_util": 0.2, "memory.resident": 0.2} .. |weights| replace:: {"cpu_util_weight": 1.0, "memory.resident_weight": 1.0} .. |instance_metrics| replace:: {"cpu_util": "compute.node.cpu.percent", "memory.resident": "hardware.memory.used"} +.. |periods| replace:: {"instance": 720, "node": 600} Efficacy Indicator ------------------ diff --git a/watcher/decision_engine/strategy/strategies/workload_stabilization.py b/watcher/decision_engine/strategy/strategies/workload_stabilization.py index c63bd3d55..957d1142e 100644 --- a/watcher/decision_engine/strategy/strategies/workload_stabilization.py +++ b/watcher/decision_engine/strategy/strategies/workload_stabilization.py @@ -80,6 +80,7 @@ class WorkloadStabilization(base.WorkloadStabilizationBaseStrategy): self.host_choice = None self.instance_metrics = None self.retry_count = None + self.periods = None @classmethod def get_name(cls): @@ -138,6 +139,17 @@ class WorkloadStabilization(base.WorkloadStabilizationBaseStrategy): "description": "Count of random returned hosts", "type": "number", "default": 1 + }, + "periods": { + "description": "These periods are used to get statistic " + "aggregation for instance and host " + "metrics. The period is simply a repeating" + " interval of time into which the samples" + " are grouped for aggregation. Watcher " + "uses only the last period of all recieved" + " ones.", + "type": "object", + "default": {"instance": 720, "node": 600} } } } @@ -190,7 +202,7 @@ class WorkloadStabilization(base.WorkloadStabilizationBaseStrategy): avg_meter = self.ceilometer.statistic_aggregation( resource_id=instance_uuid, meter_name=meter, - period="120", + period=self.periods['instance'], aggregate='min' ) if avg_meter is None: @@ -244,7 +256,7 @@ class WorkloadStabilization(base.WorkloadStabilizationBaseStrategy): avg_meter = self.ceilometer.statistic_aggregation( resource_id=resource_id, meter_name=self.instance_metrics[metric], - period="60", + period=self.periods['node'], aggregate='avg' ) if avg_meter is None: @@ -414,6 +426,7 @@ class WorkloadStabilization(base.WorkloadStabilizationBaseStrategy): self.host_choice = self.input_parameters.host_choice self.instance_metrics = self.input_parameters.instance_metrics self.retry_count = self.input_parameters.retry_count + self.periods = self.input_parameters.periods def do_execute(self): migration = self.check_threshold() diff --git a/watcher/tests/decision_engine/strategy/strategies/test_workload_stabilization.py b/watcher/tests/decision_engine/strategy/strategies/test_workload_stabilization.py index 14b0bb2d9..2e725fe75 100644 --- a/watcher/tests/decision_engine/strategy/strategies/test_workload_stabilization.py +++ b/watcher/tests/decision_engine/strategy/strategies/test_workload_stabilization.py @@ -79,7 +79,8 @@ class TestWorkloadStabilization(base.TestCase): {"cpu_util": "compute.node.cpu.percent", "memory.resident": "hardware.memory.used"}, 'host_choice': 'retry', - 'retry_count': 1}) + 'retry_count': 1, + 'periods': {"instance": 720, "node": 600}}) self.strategy.metrics = ["cpu_util", "memory.resident"] self.strategy.thresholds = {"cpu_util": 0.2, "memory.resident": 0.2} self.strategy.weights = {"cpu_util_weight": 1.0, @@ -89,6 +90,7 @@ class TestWorkloadStabilization(base.TestCase): "memory.resident": "hardware.memory.used"} self.strategy.host_choice = 'retry' self.strategy.retry_count = 1 + self.strategy.periods = {"instance": 720, "node": 600} def test_get_instance_load(self): self.m_model.return_value = self.fake_cluster.generate_scenario_1() @@ -98,6 +100,23 @@ class TestWorkloadStabilization(base.TestCase): self.assertEqual( instance_0_dict, self.strategy.get_instance_load("INSTANCE_0")) + def test_periods(self): + self.m_model.return_value = self.fake_cluster.generate_scenario_1() + p_ceilometer = mock.patch.object( + strategies.WorkloadStabilization, "ceilometer") + m_ceilometer = p_ceilometer.start() + self.addCleanup(p_ceilometer.stop) + m_ceilometer.return_value = mock.Mock( + statistic_aggregation=self.fake_metrics.mock_get_statistics) + self.strategy.get_instance_load("INSTANCE_0") + m_ceilometer.statistic_aggregation.assert_called_with( + aggregate='min', meter_name='memory.resident', + period=720, resource_id='INSTANCE_0') + self.strategy.get_hosts_load() + m_ceilometer.statistic_aggregation.assert_called_with( + aggregate='avg', meter_name='hardware.memory.used', + period=600, resource_id=mock.ANY) + def test_normalize_hosts_load(self): self.m_model.return_value = self.fake_cluster.generate_scenario_1() fake_hosts = {'Node_0': {'cpu_util': 0.07, 'memory.resident': 7},