From cbe380a0682308ce70a625d9a556e1acf7e31c72 Mon Sep 17 00:00:00 2001 From: Daniel Augusto Veronezi Salvador <38945620+GutoVeronezi@users.noreply.github.com> Date: Fri, 16 Jul 2021 03:38:36 -0300 Subject: [PATCH] Externalize secondary storage capacity threshold (#4790) * Externalize secondary storage capacity threshold * Use default value as threshold when config value is lower than 0.0 * Move config to CapacityManager * Validate config in CapacityManagerImpl * Use config in StorageOrchestrator * Change config description * Remove unused import Co-authored-by: Daniel Augusto Veronezi Salvador --- .../com/cloud/capacity/CapacityManager.java | 3 ++ .../orchestration/StorageOrchestrator.java | 4 +-- .../cloud/capacity/CapacityManagerImpl.java | 2 +- .../ConfigurationManagerImpl.java | 1 + .../java/com/cloud/server/StatsCollector.java | 28 +++++++++++++++---- 5 files changed, 30 insertions(+), 8 deletions(-) diff --git a/engine/components-api/src/main/java/com/cloud/capacity/CapacityManager.java b/engine/components-api/src/main/java/com/cloud/capacity/CapacityManager.java index e347c61cf01..44de85edeef 100644 --- a/engine/components-api/src/main/java/com/cloud/capacity/CapacityManager.java +++ b/engine/components-api/src/main/java/com/cloud/capacity/CapacityManager.java @@ -89,6 +89,9 @@ public interface CapacityManager { ConfigKey.Scope.ImageStore, null); + static final ConfigKey SecondaryStorageCapacityThreshold = new ConfigKey("Advanced", Float.class, "secondary.storage.capacity.threshold", "0.90", + "Percentage (as a value between 0 and 1) of secondary storage capacity threshold.", true); + public boolean releaseVmCapacity(VirtualMachine vm, boolean moveFromReserved, boolean moveToReservered, Long hostId); void allocateVmCapacity(VirtualMachine vm, boolean fromLastHost); diff --git a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/StorageOrchestrator.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/StorageOrchestrator.java index ab53fd46488..2046adafb1d 100644 --- a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/StorageOrchestrator.java +++ b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/StorageOrchestrator.java @@ -17,6 +17,7 @@ package org.apache.cloudstack.engine.orchestration; +import com.cloud.capacity.CapacityManager; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; @@ -101,7 +102,6 @@ public class StorageOrchestrator extends ManagerBase implements StorageOrchestra true, ConfigKey.Scope.Global); Integer numConcurrentCopyTasksPerSSVM = 2; - private double imageStoreCapacityThreshold = 0.90; @Override public String getConfigComponentName() { @@ -404,7 +404,7 @@ public class StorageOrchestrator extends ManagerBase implements StorageOrchestra private boolean storageCapacityBelowThreshold(Map> storageCapacities, Long destStoreId) { Pair imageStoreCapacity = storageCapacities.get(destStoreId); long usedCapacity = imageStoreCapacity.second() - imageStoreCapacity.first(); - if (imageStoreCapacity != null && (usedCapacity / (imageStoreCapacity.second() * 1.0)) <= imageStoreCapacityThreshold) { + if (imageStoreCapacity != null && (usedCapacity / (imageStoreCapacity.second() * 1.0)) <= CapacityManager.SecondaryStorageCapacityThreshold.value()) { s_logger.debug("image store: " + destStoreId + " has sufficient capacity to proceed with migration of file"); return true; } diff --git a/server/src/main/java/com/cloud/capacity/CapacityManagerImpl.java b/server/src/main/java/com/cloud/capacity/CapacityManagerImpl.java index 05ea9fd94ca..181b1db3f4a 100644 --- a/server/src/main/java/com/cloud/capacity/CapacityManagerImpl.java +++ b/server/src/main/java/com/cloud/capacity/CapacityManagerImpl.java @@ -1252,6 +1252,6 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager, @Override public ConfigKey[] getConfigKeys() { return new ConfigKey[] {CpuOverprovisioningFactor, MemOverprovisioningFactor, StorageCapacityDisableThreshold, StorageOverprovisioningFactor, - StorageAllocatedCapacityDisableThreshold, StorageOperationsExcludeCluster, VmwareCreateCloneFull, ImageStoreNFSVersion}; + StorageAllocatedCapacityDisableThreshold, StorageOperationsExcludeCluster, VmwareCreateCloneFull, ImageStoreNFSVersion, SecondaryStorageCapacityThreshold}; } } diff --git a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java index f431945c632..319f7977315 100755 --- a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java @@ -497,6 +497,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati weightBasedParametersForValidation.add(DeploymentClusterPlanner.ClusterMemoryCapacityDisableThreshold.key()); weightBasedParametersForValidation.add(Config.AgentLoadThreshold.key()); weightBasedParametersForValidation.add(Config.VmUserDispersionWeight.key()); + weightBasedParametersForValidation.add(CapacityManager.SecondaryStorageCapacityThreshold.key()); } diff --git a/server/src/main/java/com/cloud/server/StatsCollector.java b/server/src/main/java/com/cloud/server/StatsCollector.java index 0da1d78c224..fd59fb86c76 100644 --- a/server/src/main/java/com/cloud/server/StatsCollector.java +++ b/server/src/main/java/com/cloud/server/StatsCollector.java @@ -70,6 +70,7 @@ import com.cloud.agent.api.VmDiskStatsEntry; import com.cloud.agent.api.VmNetworkStatsEntry; import com.cloud.agent.api.VmStatsEntry; import com.cloud.agent.api.VolumeStatsEntry; +import com.cloud.capacity.CapacityManager; import com.cloud.cluster.ManagementServerHostVO; import com.cloud.cluster.dao.ManagementServerHostDao; import com.cloud.dc.Vlan.VlanType; @@ -145,6 +146,7 @@ import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.VMInstanceDao; import static com.cloud.utils.NumbersUtil.toHumanReadableSize; +import org.apache.commons.io.FileUtils; /** * Provides real time stats for various agent resources up to x seconds @@ -296,8 +298,6 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc private long volumeStatsInterval = -1L; private long autoScaleStatsInterval = -1L; - private double _imageStoreCapacityThreshold = 0.90; - private String externalStatsPrefix = ""; String externalStatsHost = null; int externalStatsPort = -1; @@ -1375,10 +1375,28 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc if (!_storageStats.keySet().contains(imageStore.getId())) { // Stats not available for this store yet, can be a new store. Better to assume it has enough capacity? return true; } - StorageStats imageStoreStats = _storageStats.get(imageStore.getId()); - if (imageStoreStats != null && (imageStoreStats.getByteUsed() / (imageStoreStats.getCapacityBytes() * 1.0)) <= _imageStoreCapacityThreshold) { + + long imageStoreId = imageStore.getId(); + StorageStats imageStoreStats = _storageStats.get(imageStoreId); + + if (imageStoreStats == null) { + s_logger.debug(String.format("Stats for image store [%s] not found.", imageStoreId)); + return false; + } + + double totalCapacity = imageStoreStats.getCapacityBytes(); + double usedCapacity = imageStoreStats.getByteUsed(); + double threshold = getImageStoreCapacityThreshold(); + String readableTotalCapacity = FileUtils.byteCountToDisplaySize((long) totalCapacity); + String readableUsedCapacity = FileUtils.byteCountToDisplaySize((long) usedCapacity); + + s_logger.debug(String.format("Verifying image storage [%s]. Capacity: total=[%s], used=[%s], threshold=[%s%%].", imageStoreId, readableTotalCapacity, readableUsedCapacity, threshold * 100)); + + if (usedCapacity / totalCapacity <= threshold) { return true; } + + s_logger.warn(String.format("Image storage [%s] has not enough capacity. Capacity: total=[%s], used=[%s], threshold=[%s%%].", imageStoreId, readableTotalCapacity, readableUsedCapacity, threshold * 100)); return false; } @@ -1611,6 +1629,6 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc } public double getImageStoreCapacityThreshold() { - return _imageStoreCapacityThreshold; + return CapacityManager.SecondaryStorageCapacityThreshold.value(); } }