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 <daniel@scclouds.com.br>
This commit is contained in:
Daniel Augusto Veronezi Salvador 2021-07-16 03:38:36 -03:00 committed by GitHub
parent 5ac184edd6
commit cbe380a068
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 30 additions and 8 deletions

View File

@ -89,6 +89,9 @@ public interface CapacityManager {
ConfigKey.Scope.ImageStore,
null);
static final ConfigKey<Float> SecondaryStorageCapacityThreshold = new ConfigKey<Float>("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);

View File

@ -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<Long, Pair<Long, Long>> storageCapacities, Long destStoreId) {
Pair<Long, Long> 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;
}

View File

@ -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};
}
}

View File

@ -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());
}

View File

@ -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();
}
}