[merge from 2.1.x] Bug 5781: Only grab capacity global lock when accessing capacity tables. Once the queries are done, release the lock so that others can query for the data or update the data as needed.

This commit is contained in:
Kris McQueen 2010-08-23 13:41:03 -07:00
parent f98e272d48
commit adce18b2c0
2 changed files with 139 additions and 131 deletions

View File

@ -154,38 +154,14 @@ public class UserConcentratedAllocator implements PodAllocator {
} }
private boolean dataCenterAndPodHasEnoughCapacity(long dataCenterId, long podId, long capacityNeeded, short capacityType, long[] hostCandidate) { private boolean dataCenterAndPodHasEnoughCapacity(long dataCenterId, long podId, long capacityNeeded, short capacityType, long[] hostCandidate) {
List<CapacityVO> capacities = null;
if (m_capacityCheckLock.lock(120)) { // 2 minutes if (m_capacityCheckLock.lock(120)) { // 2 minutes
try { try {
SearchCriteria<CapacityVO> sc = _capacityDao.createSearchCriteria(); SearchCriteria<CapacityVO> sc = _capacityDao.createSearchCriteria();
sc.addAnd("capacityType", SearchCriteria.Op.EQ, capacityType); sc.addAnd("capacityType", SearchCriteria.Op.EQ, capacityType);
sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, dataCenterId); sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, dataCenterId);
sc.addAnd("podId", SearchCriteria.Op.EQ, podId); sc.addAnd("podId", SearchCriteria.Op.EQ, podId);
List<CapacityVO> capacities = _capacityDao.search(sc, null); capacities = _capacityDao.search(sc, null);
boolean enoughCapacity = false;
if (capacities != null) {
for (CapacityVO capacity : capacities) {
if(capacityType == CapacityVO.CAPACITY_TYPE_CPU || capacityType == CapacityVO.CAPACITY_TYPE_MEMORY) {
//
// for CPU/Memory, we now switch to static allocation
//
if ((capacity.getTotalCapacity() -
calcHostAllocatedCpuMemoryCapacity(capacity.getHostOrPoolId(), capacityType)) >= capacityNeeded) {
hostCandidate[0] = capacity.getHostOrPoolId();
enoughCapacity = true;
break;
}
} else {
if ((capacity.getTotalCapacity() - capacity.getUsedCapacity()) >= capacityNeeded) {
hostCandidate[0] = capacity.getHostOrPoolId();
enoughCapacity = true;
break;
}
}
}
}
return enoughCapacity;
} finally { } finally {
m_capacityCheckLock.unlock(); m_capacityCheckLock.unlock();
} }
@ -203,6 +179,31 @@ public class UserConcentratedAllocator implements PodAllocator {
return true; return true;
*/ */
} }
boolean enoughCapacity = false;
if (capacities != null) {
for (CapacityVO capacity : capacities) {
if(capacityType == CapacityVO.CAPACITY_TYPE_CPU || capacityType == CapacityVO.CAPACITY_TYPE_MEMORY) {
//
// for CPU/Memory, we now switch to static allocation
//
if ((capacity.getTotalCapacity() -
calcHostAllocatedCpuMemoryCapacity(capacity.getHostOrPoolId(), capacityType)) >= capacityNeeded) {
hostCandidate[0] = capacity.getHostOrPoolId();
enoughCapacity = true;
break;
}
} else {
if ((capacity.getTotalCapacity() - capacity.getUsedCapacity()) >= capacityNeeded) {
hostCandidate[0] = capacity.getHostOrPoolId();
enoughCapacity = true;
break;
}
}
}
}
return enoughCapacity;
} }
private boolean skipCalculation(VMInstanceVO vm) { private boolean skipCalculation(VMInstanceVO vm) {

View File

@ -327,16 +327,13 @@ public class AlertManagerImpl implements AlertManager {
// the amount allocated. Hopefully it's limited to 3 entry points and will keep the amount allocated // the amount allocated. Hopefully it's limited to 3 entry points and will keep the amount allocated
// per host accurate. // per host accurate.
if (m_capacityCheckLock.lock(5)) { // 5 second timeout
if (s_logger.isTraceEnabled()) { if (s_logger.isTraceEnabled()) {
s_logger.trace("recalculating system capacity"); s_logger.trace("recalculating system capacity");
} }
try { List<CapacityVO> newCapacities = new ArrayList<CapacityVO>();
// delete the old records
_capacityDao.clearNonStorageCapacities();
// get all hosts.. // get all hosts..
SearchCriteria<HostVO> sc = _hostDao.createSearchCriteria(); SearchCriteria sc = _hostDao.createSearchCriteria();
sc.addAnd("status", SearchCriteria.Op.EQ, Status.Up.toString()); sc.addAnd("status", SearchCriteria.Op.EQ, Status.Up.toString());
List<HostVO> hosts = _hostDao.search(sc, null); List<HostVO> hosts = _hostDao.search(sc, null);
@ -350,6 +347,7 @@ public class AlertManagerImpl implements AlertManager {
if (host.getType() != Host.Type.Routing) { if (host.getType() != Host.Type.Routing) {
continue; continue;
} }
long cpu = 0; long cpu = 0;
long usedMemory = 0; long usedMemory = 0;
List<DomainRouterVO> domainRouters = _routerDao.listUpByHostId(host.getId()); List<DomainRouterVO> domainRouters = _routerDao.listUpByHostId(host.getId());
@ -391,8 +389,8 @@ public class AlertManagerImpl implements AlertManager {
CapacityVO newMemoryCapacity = new CapacityVO(host.getId(), host.getDataCenterId(), host.getPodId(), usedMemory, totalMemory, CapacityVO.CAPACITY_TYPE_MEMORY); CapacityVO newMemoryCapacity = new CapacityVO(host.getId(), host.getDataCenterId(), host.getPodId(), usedMemory, totalMemory, CapacityVO.CAPACITY_TYPE_MEMORY);
CapacityVO newCPUCapacity = new CapacityVO(host.getId(), host.getDataCenterId(), host.getPodId(), cpu, (long)(host.getCpus()*host.getSpeed()* _cpuOverProvisioningFactor), CapacityVO.CAPACITY_TYPE_CPU); CapacityVO newCPUCapacity = new CapacityVO(host.getId(), host.getDataCenterId(), host.getPodId(), cpu, (long)(host.getCpus()*host.getSpeed()* _cpuOverProvisioningFactor), CapacityVO.CAPACITY_TYPE_CPU);
_capacityDao.persist(newMemoryCapacity); newCapacities.add(newMemoryCapacity);
_capacityDao.persist(newCPUCapacity); newCapacities.add(newCPUCapacity);
} }
// Calculate storage pool capacity // Calculate storage pool capacity
@ -406,7 +404,7 @@ public class AlertManagerImpl implements AlertManager {
provFactor = _overProvisioningFactor; provFactor = _overProvisioningFactor;
} }
CapacityVO newStorageCapacity = new CapacityVO(pool.getId(), pool.getDataCenterId(), pool.getPodId(), disk, pool.getCapacityBytes() * provFactor, CapacityVO.CAPACITY_TYPE_STORAGE_ALLOCATED); CapacityVO newStorageCapacity = new CapacityVO(pool.getId(), pool.getDataCenterId(), pool.getPodId(), disk, pool.getCapacityBytes() * provFactor, CapacityVO.CAPACITY_TYPE_STORAGE_ALLOCATED);
_capacityDao.persist(newStorageCapacity); newCapacities.add(newStorageCapacity);
continue; continue;
} }
@ -420,7 +418,7 @@ public class AlertManagerImpl implements AlertManager {
int allocatedPublicIPs = _publicIPAddressDao.countIPs(dcId, -1, true); int allocatedPublicIPs = _publicIPAddressDao.countIPs(dcId, -1, true);
CapacityVO newPublicIPCapacity = new CapacityVO(null, dcId, null, allocatedPublicIPs, totalPublicIPs, CapacityVO.CAPACITY_TYPE_PUBLIC_IP); CapacityVO newPublicIPCapacity = new CapacityVO(null, dcId, null, allocatedPublicIPs, totalPublicIPs, CapacityVO.CAPACITY_TYPE_PUBLIC_IP);
_capacityDao.persist(newPublicIPCapacity); newCapacities.add(newPublicIPCapacity);
} }
// Calculate new Private IP capacity // Calculate new Private IP capacity
@ -433,7 +431,16 @@ public class AlertManagerImpl implements AlertManager {
int allocatedPrivateIPs = _privateIPAddressDao.countIPs(podId, dcId, true); int allocatedPrivateIPs = _privateIPAddressDao.countIPs(podId, dcId, true);
CapacityVO newPrivateIPCapacity = new CapacityVO(null, dcId, podId, allocatedPrivateIPs, totalPrivateIPs, CapacityVO.CAPACITY_TYPE_PRIVATE_IP); CapacityVO newPrivateIPCapacity = new CapacityVO(null, dcId, podId, allocatedPrivateIPs, totalPrivateIPs, CapacityVO.CAPACITY_TYPE_PRIVATE_IP);
_capacityDao.persist(newPrivateIPCapacity); newCapacities.add(newPrivateIPCapacity);
}
if (m_capacityCheckLock.lock(5)) { // 5 second timeout
try {
// delete the old records
_capacityDao.clearNonStorageCapacities();
for (CapacityVO newCapacity : newCapacities) {
_capacityDao.persist(newCapacity);
} }
} finally { } finally {
m_capacityCheckLock.unlock(); m_capacityCheckLock.unlock();