mirror of https://github.com/apache/cloudstack.git
Bug 9117: allocator performance improvements
Fix for following optimization: Make PodAllocator aware of host tags. If the service offering has host_tag specified, PodAllocator can pick the pods having hosts with that tag. This would reduce the list of pods the allocator has to iterate through to find a suitable pod. Added a new PodAllocator 'HostTagBasedPodAllocator' that extends the 'UserConcentratedAllocator'.
This commit is contained in:
parent
3d558166a9
commit
0f3922f324
|
|
@ -30,6 +30,8 @@ public interface HostPodDao extends GenericDao<HostPodVO, Long> {
|
|||
|
||||
public HostPodVO findByName(String name, long dcId);
|
||||
|
||||
public HashMap<Long, List<Object>> getCurrentPodCidrSubnets(long zoneId, long podIdToSkip);
|
||||
public HashMap<Long, List<Object>> getCurrentPodCidrSubnets(long zoneId, long podIdToSkip);
|
||||
|
||||
public List<HostPodVO> listPodsByHostTag(long dcId, String hostTag);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ import com.cloud.utils.db.GenericDaoBase;
|
|||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.net.NetUtils;
|
||||
|
||||
@Local(value={HostPodDao.class})
|
||||
|
|
@ -43,7 +44,11 @@ public class HostPodDaoImpl extends GenericDaoBase<HostPodVO, Long> implements H
|
|||
private static final Logger s_logger = Logger.getLogger(HostPodDaoImpl.class);
|
||||
|
||||
protected SearchBuilder<HostPodVO> DataCenterAndNameSearch;
|
||||
protected SearchBuilder<HostPodVO> DataCenterIdSearch;
|
||||
protected SearchBuilder<HostPodVO> DataCenterIdSearch;
|
||||
|
||||
private static final String PodsByHostTag = "SELECT DISTINCT host_pod_ref.* FROM (host_tags JOIN host ON host_tags.host_id = host.id AND host_tags.tag = ?) JOIN host_pod_ref " +
|
||||
"ON host_pod_ref.id = host.pod_id WHERE host_pod_ref.data_center_id = ? ";
|
||||
|
||||
|
||||
protected HostPodDaoImpl() {
|
||||
DataCenterAndNameSearch = createSearchBuilder();
|
||||
|
|
@ -96,7 +101,31 @@ public class HostPodDaoImpl extends GenericDaoBase<HostPodVO, Long> implements H
|
|||
}
|
||||
|
||||
return currentPodCidrSubnets;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HostPodVO> listPodsByHostTag(long dcId, String hostTag) {
|
||||
|
||||
StringBuilder sql = new StringBuilder(PodsByHostTag);
|
||||
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
PreparedStatement pstmt = s_initStmt;
|
||||
try {
|
||||
pstmt = txn.prepareAutoCloseStatement(sql.toString());
|
||||
int i = 1;
|
||||
pstmt.setString(i++, hostTag);
|
||||
pstmt.setLong(i++, dcId);
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
List<HostPodVO> pods = new ArrayList<HostPodVO>();
|
||||
while (rs.next()) {
|
||||
pods.add(toEntityBean(rs, false));
|
||||
}
|
||||
return pods;
|
||||
} catch (SQLException e) {
|
||||
throw new CloudRuntimeException("Unable to execute " + pstmt.toString(), e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,65 @@
|
|||
/**
|
||||
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.cloud.agent.manager.allocator.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.ejb.Local;
|
||||
import org.apache.log4j.Logger;
|
||||
import com.cloud.agent.manager.allocator.PodAllocator;
|
||||
import com.cloud.dc.HostPodVO;
|
||||
import com.cloud.dc.dao.HostPodDao;
|
||||
import com.cloud.service.ServiceOffering;
|
||||
import com.cloud.utils.component.Inject;
|
||||
|
||||
/*
|
||||
* Use this PodAllocator when the deployment is such that pod has homogeneous tags on hosts.
|
||||
* If any pod can contain hosts with any tag, this optimization will not yield much benefit.
|
||||
*/
|
||||
@Local(value=PodAllocator.class)
|
||||
public class HostTagBasedPodAllocator extends UserConcentratedAllocator {
|
||||
private final static Logger s_logger = Logger.getLogger(HostTagBasedPodAllocator.class);
|
||||
@Inject HostPodDao _podDao;
|
||||
|
||||
public HostTagBasedPodAllocator() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<HostPodVO> listPods(long zoneId, ServiceOffering offering){
|
||||
List<HostPodVO> podsInZone = new ArrayList<HostPodVO>();
|
||||
|
||||
if(offering != null && offering.getHostTag() != null){
|
||||
String hostTag = offering.getHostTag();
|
||||
podsInZone = _podDao.listPodsByHostTag(zoneId, hostTag);
|
||||
|
||||
if(podsInZone.size() == 0){
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.info("No Pods found in Zone: '"+zoneId+"' having Hosts with host tag: '"+ hostTag +"'");
|
||||
}
|
||||
}else{
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Found "+podsInZone.size() +" Pods in Zone: '"+zoneId+"' having Hosts with host tag: '"+ hostTag +"'");
|
||||
}
|
||||
}
|
||||
}else{
|
||||
podsInZone = super.listPods(zoneId, offering);
|
||||
}
|
||||
|
||||
return podsInZone;
|
||||
}
|
||||
}
|
||||
|
|
@ -83,7 +83,7 @@ public class UserConcentratedAllocator implements PodAllocator {
|
|||
@Override
|
||||
public Pair<HostPodVO, Long> allocateTo(VirtualMachineTemplate template, ServiceOfferingVO offering, DataCenterVO zone, long accountId, Set<Long> avoids) {
|
||||
long zoneId = zone.getId();
|
||||
List<HostPodVO> podsInZone = _podDao.listByDataCenterId(zoneId);
|
||||
List<HostPodVO> podsInZone = listPods(zoneId, offering);
|
||||
|
||||
if (podsInZone.size() == 0) {
|
||||
s_logger.debug("No pods found in zone " + zone.getName());
|
||||
|
|
@ -100,10 +100,7 @@ public class UserConcentratedAllocator implements PodAllocator {
|
|||
s_logger.debug("Checking Pod: " + podId);
|
||||
}
|
||||
|
||||
if (template != null && !templateAvailableInPod(template.getId(), pod.getDataCenterId(), podId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (offering != null) {
|
||||
// test for enough memory in the pod (make sure to check for enough memory for the service offering, plus some extra padding for xen overhead
|
||||
long[] hostCandiates = new long[1];
|
||||
|
|
@ -160,6 +157,14 @@ public class UserConcentratedAllocator implements PodAllocator {
|
|||
return new Pair<HostPodVO, Long>(selectedPod, podHostCandidates.get(selectedPod.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
protected List<HostPodVO> listPods(long zoneId, ServiceOffering offering){
|
||||
List<HostPodVO> podsInZone = _podDao.listByDataCenterId(zoneId);
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Found "+podsInZone.size() +" Pods in Zone: "+zoneId);
|
||||
}
|
||||
return podsInZone;
|
||||
}
|
||||
|
||||
private boolean dataCenterAndPodHasEnoughCapacity(long dataCenterId, long podId, long capacityNeeded, short capacityType, long[] hostCandidate) {
|
||||
List<CapacityVO> capacities = null;
|
||||
|
|
|
|||
Loading…
Reference in New Issue