From 6bf92fb13620b56a1d644840a42cd2590a4f4131 Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Mon, 6 Apr 2020 22:01:40 +0200 Subject: [PATCH] server: Search zone-wide storage pool when allocation algothrim is firstfitleastconsumed (#4002) --- .../com/cloud/capacity/dao/CapacityDao.java | 2 +- .../cloud/capacity/dao/CapacityDaoImpl.java | 22 +++++++---- .../AbstractStoragePoolAllocator.java | 3 +- .../ZoneWideStoragePoolAllocator.java | 38 +++++++++++++++++++ .../allocator/impl/FirstFitAllocator.java | 3 +- 5 files changed, 58 insertions(+), 10 deletions(-) diff --git a/engine/schema/src/main/java/com/cloud/capacity/dao/CapacityDao.java b/engine/schema/src/main/java/com/cloud/capacity/dao/CapacityDao.java index fcccd56dd6e..f2735b819a9 100644 --- a/engine/schema/src/main/java/com/cloud/capacity/dao/CapacityDao.java +++ b/engine/schema/src/main/java/com/cloud/capacity/dao/CapacityDao.java @@ -56,5 +56,5 @@ public interface CapacityDao extends GenericDao { float findClusterConsumption(Long clusterId, short capacityType, long computeRequested); - List orderHostsByFreeCapacity(Long clusterId, short capacityType); + List orderHostsByFreeCapacity(Long zoneId, Long clusterId, short capacityType); } diff --git a/engine/schema/src/main/java/com/cloud/capacity/dao/CapacityDaoImpl.java b/engine/schema/src/main/java/com/cloud/capacity/dao/CapacityDaoImpl.java index 5b14bd4af3b..72d5b070761 100644 --- a/engine/schema/src/main/java/com/cloud/capacity/dao/CapacityDaoImpl.java +++ b/engine/schema/src/main/java/com/cloud/capacity/dao/CapacityDaoImpl.java @@ -903,20 +903,28 @@ public class CapacityDaoImpl extends GenericDaoBase implements } @Override - public List orderHostsByFreeCapacity(Long clusterId, short capacityTypeForOrdering){ + public List orderHostsByFreeCapacity(Long zoneId, Long clusterId, short capacityTypeForOrdering){ TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; List result = new ArrayList(); StringBuilder sql = new StringBuilder(ORDER_HOSTS_BY_FREE_CAPACITY_PART1); - if(clusterId != null) { - sql.append("AND cluster_id = ?"); - } - sql.append(ORDER_HOSTS_BY_FREE_CAPACITY_PART2); + if (zoneId != null) { + sql.append(" AND data_center_id = ?"); + } + if (clusterId != null) { + sql.append(" AND cluster_id = ?"); + } + sql.append(ORDER_HOSTS_BY_FREE_CAPACITY_PART2); try { pstmt = txn.prepareAutoCloseStatement(sql.toString()); pstmt.setShort(1, capacityTypeForOrdering); - if(clusterId != null) { - pstmt.setLong(2, clusterId); + int index = 2; + if (zoneId != null) { + pstmt.setLong(index, zoneId); + index ++; + } + if (clusterId != null) { + pstmt.setLong(index, clusterId); } ResultSet rs = pstmt.executeQuery(); diff --git a/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java index ef5e21d8899..727d10af130 100644 --- a/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java +++ b/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java @@ -94,6 +94,7 @@ public abstract class AbstractStoragePoolAllocator extends AdapterBase implement protected List reorderPoolsByCapacity(DeploymentPlan plan, List pools) { + Long zoneId = plan.getDataCenterId(); Long clusterId = plan.getClusterId(); short capacityType; if(pools != null && pools.size() != 0){ @@ -102,7 +103,7 @@ public abstract class AbstractStoragePoolAllocator extends AdapterBase implement return null; } - List poolIdsByCapacity = capacityDao.orderHostsByFreeCapacity(clusterId, capacityType); + List poolIdsByCapacity = capacityDao.orderHostsByFreeCapacity(zoneId, clusterId, capacityType); if (s_logger.isDebugEnabled()) { s_logger.debug("List of pools in descending order of free capacity: "+ poolIdsByCapacity); } diff --git a/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/ZoneWideStoragePoolAllocator.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/ZoneWideStoragePoolAllocator.java index aa077f33fef..301704a75a6 100644 --- a/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/ZoneWideStoragePoolAllocator.java +++ b/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/ZoneWideStoragePoolAllocator.java @@ -29,6 +29,8 @@ import org.springframework.stereotype.Component; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +import com.cloud.capacity.Capacity; +import com.cloud.capacity.dao.CapacityDao; import com.cloud.deploy.DeploymentPlan; import com.cloud.deploy.DeploymentPlanner.ExcludeList; import com.cloud.hypervisor.Hypervisor.HypervisorType; @@ -43,6 +45,8 @@ public class ZoneWideStoragePoolAllocator extends AbstractStoragePoolAllocator { private static final Logger LOGGER = Logger.getLogger(ZoneWideStoragePoolAllocator.class); @Inject private DataStoreManager dataStoreMgr; + @Inject + private CapacityDao capacityDao; @Override @@ -110,6 +114,40 @@ public class ZoneWideStoragePoolAllocator extends AbstractStoragePoolAllocator { return !ScopeType.ZONE.equals(storagePoolVO.getScope()) || !storagePoolVO.isManaged(); } + + @Override + protected List reorderPoolsByCapacity(DeploymentPlan plan, + List pools) { + Long zoneId = plan.getDataCenterId(); + short capacityType; + if(pools != null && pools.size() != 0){ + capacityType = pools.get(0).getPoolType().isShared() ? Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED : Capacity.CAPACITY_TYPE_LOCAL_STORAGE; + } else{ + return null; + } + + List poolIdsByCapacity = capacityDao.orderHostsByFreeCapacity(zoneId, null, capacityType); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("List of zone-wide storage pools in descending order of free capacity: "+ poolIdsByCapacity); + } + + //now filter the given list of Pools by this ordered list + Map poolMap = new HashMap<>(); + for (StoragePool pool : pools) { + poolMap.put(pool.getId(), pool); + } + List matchingPoolIds = new ArrayList<>(poolMap.keySet()); + + poolIdsByCapacity.retainAll(matchingPoolIds); + + List reorderedPools = new ArrayList<>(); + for(Long id: poolIdsByCapacity){ + reorderedPools.add(poolMap.get(id)); + } + + return reorderedPools; + } + @Override protected List reorderPoolsByNumberOfVolumes(DeploymentPlan plan, List pools, Account account) { if (account == null) { diff --git a/server/src/main/java/com/cloud/agent/manager/allocator/impl/FirstFitAllocator.java b/server/src/main/java/com/cloud/agent/manager/allocator/impl/FirstFitAllocator.java index f4ad478861e..b6ee3052275 100644 --- a/server/src/main/java/com/cloud/agent/manager/allocator/impl/FirstFitAllocator.java +++ b/server/src/main/java/com/cloud/agent/manager/allocator/impl/FirstFitAllocator.java @@ -345,6 +345,7 @@ public class FirstFitAllocator extends AdapterBase implements HostAllocator { // Reorder hosts in the decreasing order of free capacity. private List reorderHostsByCapacity(DeploymentPlan plan, List hosts) { + Long zoneId = plan.getDataCenterId(); Long clusterId = plan.getClusterId(); //Get capacity by which we should reorder String capacityTypeToOrder = _configDao.getValue(Config.HostCapacityTypeToOrderClusters.key()); @@ -352,7 +353,7 @@ public class FirstFitAllocator extends AdapterBase implements HostAllocator { if("RAM".equalsIgnoreCase(capacityTypeToOrder)){ capacityType = CapacityVO.CAPACITY_TYPE_MEMORY; } - List hostIdsByFreeCapacity = _capacityDao.orderHostsByFreeCapacity(clusterId, capacityType); + List hostIdsByFreeCapacity = _capacityDao.orderHostsByFreeCapacity(zoneId, clusterId, capacityType); if (s_logger.isDebugEnabled()) { s_logger.debug("List of hosts in descending order of free capacity in the cluster: "+ hostIdsByFreeCapacity); }