Batch NIC and VLAN reads in collectVmNetworkStatistics to reduce per-NIC DB round-trips (#13474)

Co-authored-by: Aaron Chung <aaron_chung@apple.com>
This commit is contained in:
Vishesh 2026-06-29 19:15:56 +05:30 committed by GitHub
parent d5101b0c90
commit 4625a43672
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 54 additions and 7 deletions

View File

@ -51,6 +51,8 @@ public interface VlanDao extends GenericDao<VlanVO, Long> {
List<VlanVO> listVlansByNetworkId(long networkId);
List<VlanVO> listVlansByNetworkIds(List<Long> networkIds);
List<VlanVO> listVlansByNetworkIdIncludingRemoved(long networkId);
List<VlanVO> listVlansByPhysicalNetworkId(long physicalNetworkId);

View File

@ -20,6 +20,7 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@ -27,6 +28,7 @@ import javax.inject.Inject;
import javax.naming.ConfigurationException;
import com.cloud.dc.VlanDetailsVO;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
@ -134,7 +136,7 @@ public class VlanDaoImpl extends GenericDaoBase<VlanVO, Long> implements VlanDao
ZoneTypeSearch.done();
NetworkVlanSearch = createSearchBuilder();
NetworkVlanSearch.and("networkId", NetworkVlanSearch.entity().getNetworkId(), SearchCriteria.Op.EQ);
NetworkVlanSearch.and("networkId", NetworkVlanSearch.entity().getNetworkId(), SearchCriteria.Op.IN);
NetworkVlanSearch.done();
PhysicalNetworkVlanSearch = createSearchBuilder();
@ -392,6 +394,16 @@ public class VlanDaoImpl extends GenericDaoBase<VlanVO, Long> implements VlanDao
return listBy(sc);
}
@Override
public List<VlanVO> listVlansByNetworkIds(List<Long> networkIds) {
if (CollectionUtils.isEmpty(networkIds)) {
return Collections.emptyList();
}
SearchCriteria<VlanVO> sc = NetworkVlanSearch.create();
sc.setParameters("networkId", networkIds.toArray());
return listBy(sc);
}
@Override public List<VlanVO> listVlansByNetworkIdIncludingRemoved(long networkId) {
SearchCriteria<VlanVO> sc = NetworkVlanSearch.create();
sc.setParameters("networkId", networkId);

View File

@ -97,6 +97,8 @@ public interface NicDao extends GenericDao<NicVO, Long> {
NicVO findByMacAddress(String macAddress, long networkId);
List<NicVO> listByMacAddresses(List<String> macAddresses);
NicVO findByNetworkIdAndMacAddressIncludingRemoved(long networkId, String mac);
List<NicVO> findNicsByIpv6GatewayIpv6CidrAndReserver(String ipv6Gateway, String ipv6Cidr, String reserverName);

View File

@ -18,12 +18,13 @@ package com.cloud.vm.dao;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;
import com.cloud.utils.db.Filter;
@ -71,7 +72,7 @@ public class NicDaoImpl extends GenericDaoBase<NicVO, Long> implements NicDao {
AllFieldsSearch.and("strategy", AllFieldsSearch.entity().getReservationStrategy(), Op.EQ);
AllFieldsSearch.and("strategyNEQ", AllFieldsSearch.entity().getReservationStrategy(), Op.NEQ);
AllFieldsSearch.and("reserverName",AllFieldsSearch.entity().getReserver(),Op.EQ);
AllFieldsSearch.and("macAddress", AllFieldsSearch.entity().getMacAddress(), Op.EQ);
AllFieldsSearch.and("macAddress", AllFieldsSearch.entity().getMacAddress(), Op.IN);
AllFieldsSearch.and("deviceid", AllFieldsSearch.entity().getDeviceId(), Op.EQ);
AllFieldsSearch.and("ipv6Gateway", AllFieldsSearch.entity().getIPv6Gateway(), Op.EQ);
AllFieldsSearch.and("ipv6Cidr", AllFieldsSearch.entity().getIPv6Cidr(), Op.EQ);
@ -427,6 +428,16 @@ public class NicDaoImpl extends GenericDaoBase<NicVO, Long> implements NicDao {
return findOneBy(sc);
}
@Override
public List<NicVO> listByMacAddresses(List<String> macAddresses) {
if (CollectionUtils.isEmpty(macAddresses)) {
return Collections.emptyList();
}
SearchCriteria<NicVO> sc = AllFieldsSearch.create();
sc.setParameters("macAddress", macAddresses.toArray());
return listBy(sc);
}
@Override
public List<NicVO> findNicsByIpv6GatewayIpv6CidrAndReserver(String ipv6Gateway, String ipv6Cidr, String reserverName) {
SearchCriteria<NicVO> sc = AllFieldsSearch.create();

View File

@ -5195,11 +5195,31 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
return;
}
List<String> macAddresses = new ArrayList<>(vmNetworkStats.size());
for (VmNetworkStatsEntry entry : vmNetworkStats) {
macAddresses.add(entry.getMacAddress());
}
Map<String, NicVO> nicsByMac = new HashMap<>();
for (NicVO nic : _nicDao.listByMacAddresses(macAddresses)) {
nicsByMac.put(nic.getMacAddress(), nic);
}
Set<Long> networkIds = new HashSet<>();
for (NicVO nic : nicsByMac.values()) {
networkIds.add(nic.getNetworkId());
}
Map<Long, List<VlanVO>> vlansByNetwork = new HashMap<>();
for (VlanVO vlan : _vlanDao.listVlansByNetworkIds(new ArrayList<>(networkIds))) {
vlansByNetwork.computeIfAbsent(vlan.getNetworkId(), k -> new ArrayList<>()).add(vlan);
}
for (VmNetworkStatsEntry vmNetworkStat:vmNetworkStats) {
SearchCriteria<NicVO> sc_nic = _nicDao.createSearchCriteria();
sc_nic.addAnd("macAddress", SearchCriteria.Op.EQ, vmNetworkStat.getMacAddress());
NicVO nic = _nicDao.search(sc_nic, null).get(0);
List<VlanVO> vlan = _vlanDao.listVlansByNetworkId(nic.getNetworkId());
NicVO nic = nicsByMac.get(vmNetworkStat.getMacAddress());
if (nic == null) {
logger.warn("Unable to find nic for mac " + vmNetworkStat.getMacAddress());
continue;
}
List<VlanVO> vlan = vlansByNetwork.get(nic.getNetworkId());
if (vlan == null || vlan.size() == 0 || vlan.get(0).getVlanType() != VlanType.DirectAttached)
{
break; // only get network statistics for DirectAttached network (shared networks in Basic zone and Advanced zone with/without SG)