Repository: stratos Updated Branches: refs/heads/4.1.0-test 05eba6145 -> ff1cda638
Dependent scale Rule improvement Project: http://git-wip-us.apache.org/repos/asf/stratos/repo Commit: http://git-wip-us.apache.org/repos/asf/stratos/commit/ff1cda63 Tree: http://git-wip-us.apache.org/repos/asf/stratos/tree/ff1cda63 Diff: http://git-wip-us.apache.org/repos/asf/stratos/diff/ff1cda63 Branch: refs/heads/4.1.0-test Commit: ff1cda638beb7fbba8755707bf7d075cc48993e7 Parents: 05eba61 Author: Lahiru Sandaruwan <[email protected]> Authored: Mon Dec 8 22:11:12 2014 +0530 Committer: Lahiru Sandaruwan <[email protected]> Committed: Tue Dec 9 08:05:18 2014 +0530 ---------------------------------------------------------------------- .../monitor/cluster/VMClusterMonitor.java | 22 +++++++ .../src/main/conf/drools/dependent-scaling.drl | 62 +++++++++++++++++--- 2 files changed, 77 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/stratos/blob/ff1cda63/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/VMClusterMonitor.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/VMClusterMonitor.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/VMClusterMonitor.java index ef8491a..cbe5d96 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/VMClusterMonitor.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/VMClusterMonitor.java @@ -218,6 +218,7 @@ public class VMClusterMonitor extends AbstractClusterMonitor { } + getScaleCheckKnowledgeSession().setGlobal("primaryMembers", primaryMemberListInClusterInstance); getMinCheckKnowledgeSession().setGlobal("clusterId", getClusterId()); getMinCheckKnowledgeSession().setGlobal("isPrimary", hasPrimary); //FIXME when parent chosen the partition @@ -388,6 +389,27 @@ public class VMClusterMonitor extends AbstractClusterMonitor { getClusterInstanceContext(scalingEvent.getNetworkPartitionId(), instanceId); + // store primary members in the cluster instance context + List<String> primaryMemberListInClusterInstance = new ArrayList<String>(); + + for (ClusterLevelPartitionContext partitionContext : clusterInstanceContext.getPartitionCtxts()) { + + // get active primary members in this cluster instance context + for (MemberContext memberContext : partitionContext.getActiveMembers()) { + if (isPrimaryMember(memberContext)) { + primaryMemberListInClusterInstance.add(memberContext.getMemberId()); + } + } + + // get pending primary members in this cluster instance context + for (MemberContext memberContext : partitionContext.getPendingMembers()) { + if (isPrimaryMember(memberContext)) { + primaryMemberListInClusterInstance.add(memberContext.getMemberId()); + } + } + } + + //TODO get min instance count from instance context float requiredInstanceCount = clusterInstanceContext.getMinInstanceCount() * scalingFactorBasedOnDependencies; int roundedRequiredInstanceCount = getRoundedInstanceCount(requiredInstanceCount, http://git-wip-us.apache.org/repos/asf/stratos/blob/ff1cda63/products/stratos/modules/distribution/src/main/conf/drools/dependent-scaling.drl ---------------------------------------------------------------------- diff --git a/products/stratos/modules/distribution/src/main/conf/drools/dependent-scaling.drl b/products/stratos/modules/distribution/src/main/conf/drools/dependent-scaling.drl index 6aaf925..5a0e61e 100644 --- a/products/stratos/modules/distribution/src/main/conf/drools/dependent-scaling.drl +++ b/products/stratos/modules/distribution/src/main/conf/drools/dependent-scaling.drl @@ -22,6 +22,11 @@ package org.apache.stratos.autoscaler.rule; import org.apache.stratos.autoscaler.context.cluster.ClusterInstanceContext; import org.apache.stratos.autoscaler.algorithm.AutoscaleAlgorithm; import org.apache.stratos.autoscaler.context.partition.ClusterLevelPartitionContext; +import org.apache.stratos.autoscaler.context.member.MemberStatsContext; +import org.apache.stratos.autoscaler.pojo.policy.autoscale.RequestsInFlight; +import org.apache.stratos.autoscaler.pojo.policy.autoscale.LoadThresholds; +import org.apache.stratos.autoscaler.pojo.policy.autoscale.MemoryConsumption; +import org.apache.stratos.autoscaler.pojo.policy.autoscale.LoadAverage; global org.apache.stratos.autoscaler.rule.RuleLog log; global java.lang.String clusterId; @@ -29,6 +34,7 @@ global Integer roundedRequiredInstanceCount; global org.apache.stratos.autoscaler.rule.RuleTasksDelegator delegator; global java.lang.String algorithmName; global java.lang.Boolean isPrimary; +global java.util.List primaryMembers; rule "Dependent Scaling Rule" dialect "mvel" @@ -56,9 +62,6 @@ dialect "mvel" delegator.delegateSpawn(partitionContext, clusterId, clusterInstanceContext.getId(), isPrimary); count++; } -// else { -// break; -// } } } else if (scaleDown) { @@ -67,16 +70,61 @@ dialect "mvel" int count = 0; while(count != redundantInstances){ + MemberStatsContext selectedMemberStatsContext = null; + double lowestOverallLoad = 0.0; + boolean foundAValue = false; ClusterLevelPartitionContext partitionContext = (ClusterLevelPartitionContext)autoscaleAlgorithm.getNextScaleDownPartitionContext(clusterInstanceContext.getPartitionCtxtsAsAnArray()); if(partitionContext != null){ log.info("[scale-down] Partition available to scale down, hence trying to terminate an instance to scale down!" ); log.debug("[scale-down] " + " [partition] " + partitionContext.getPartitionId() + " [cluster] " + clusterId ); - delegator.delegateSpawn(partitionContext, clusterId, clusterInstanceContext.getId(), isPrimary); + + for(MemberStatsContext memberStatsContext: partitionContext.getMemberStatsContexts().values()){ + + if( !primaryMembers.contains(memberStatsContext.getMemberId()) ) { + + LoadAverage loadAverage = memberStatsContext.getLoadAverage(); + log.debug("[scale-down] " + " [cluster] " + + clusterId + " [member] " + memberStatsContext.getMemberId() + " Load average: " + loadAverage); + + MemoryConsumption memoryConsumption = memberStatsContext.getMemoryConsumption(); + log.debug("[scale-down] " + " [partition] " + partitionContext.getPartitionId() + " [cluster] " + + clusterId + " [member] " + memberStatsContext.getMemberId() + " Memory consumption: " + memoryConsumption); + + double predictedCpu = delegator.getPredictedValueForNextMinute(loadAverage.getAverage(),loadAverage.getGradient(),loadAverage.getSecondDerivative(), 1); + log.debug("[scale-down] " + " [partition] " + partitionContext.getPartitionId() + " [cluster] " + + clusterId + " [member] " + memberStatsContext.getMemberId() + " Predicted CPU: " + predictedCpu); + + double predictedMemoryConsumption = delegator.getPredictedValueForNextMinute(memoryConsumption.getAverage(),memoryConsumption.getGradient(),memoryConsumption.getSecondDerivative(), 1); + log.debug("[scale-down] " + " [partition] " + partitionContext.getPartitionId() + " [cluster] " + + clusterId + " [member] " + memberStatsContext.getMemberId() + " Predicted memory consumption: " + predictedMemoryConsumption); + + double overallLoad = (predictedCpu + predictedMemoryConsumption) / 2; + log.debug("[scale-down] " + " [partition] " + partitionContext.getPartitionId() + " [cluster] " + + clusterId + " [member] " + memberStatsContext.getMemberId() + " Overall load: " + overallLoad); + + if(!foundAValue){ + foundAValue = true; + selectedMemberStatsContext = memberStatsContext; + lowestOverallLoad = overallLoad; + } else if(overallLoad < lowestOverallLoad){ + selectedMemberStatsContext = memberStatsContext; + lowestOverallLoad = overallLoad; + } + + + } + + } + if(selectedMemberStatsContext != null) { + log.info("[scale-down] Trying to terminating an instace to scale down!" ); + log.debug("[scale-down] " + " [partition] " + partitionContext.getPartitionId() + " [cluster] " + + clusterId + " Member with lowest overall load: " + selectedMemberStatsContext.getMemberId()); + + delegator.delegateTerminate(partitionContext, selectedMemberStatsContext.getMemberId()); + } + count++; } -// else { -// break; -// } } }
