optimize(scheduler): reduce calculation of network free address (#15595)

- only calculate non-emulated host's network on building
- calculate emulated host's network on scheduling
This commit is contained in:
Zexi Li
2022-12-20 20:54:16 +08:00
committed by GitHub
parent a3844d4b28
commit 2643c8916e
3 changed files with 55 additions and 24 deletions
+6 -6
View File
@@ -192,18 +192,18 @@ func (bb *BaremetalBuilder) Do(ids []string) ([]interface{}, error) {
if err != nil {
return nil, err
}
descs, err := bb.build()
netGetter := newNetworkGetter()
descs, err := bb.build(netGetter)
if err != nil {
return nil, err
}
return descs, nil
}
func (bb *BaremetalBuilder) build() ([]interface{}, error) {
func (bb *BaremetalBuilder) build(netGetter *networkGetter) ([]interface{}, error) {
schedDescs := []interface{}{}
for _, bm := range bb.baremetals {
desc, err := bb.buildOne(&bm)
desc, err := bb.buildOne(&bm, netGetter)
if err != nil {
log.Errorf("BaremetalBuilder error: %v", err)
continue
@@ -213,8 +213,8 @@ func (bb *BaremetalBuilder) build() ([]interface{}, error) {
return schedDescs, nil
}
func (bb *BaremetalBuilder) buildOne(hostObj *computemodels.SHost) (interface{}, error) {
baseDesc, err := newBaseHostDesc(bb.baseBuilder, hostObj)
func (bb *BaremetalBuilder) buildOne(hostObj *computemodels.SHost, netGetter *networkGetter) (interface{}, error) {
baseDesc, err := newBaseHostDesc(bb.baseBuilder, hostObj, netGetter)
if err != nil {
return nil, err
}
+42 -12
View File
@@ -17,6 +17,7 @@ package candidate
import (
"fmt"
"strings"
"sync"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
@@ -326,7 +327,33 @@ func reviseResourceType(resType string) string {
return resType
}
func newBaseHostDesc(b *baseBuilder, host *computemodels.SHost) (*BaseHostDesc, error) {
type networkGetter struct {
netFreeMap *sync.Map
}
func newNetworkGetter() *networkGetter {
return &networkGetter{
netFreeMap: new(sync.Map),
}
}
func (g *networkGetter) GetFreePort(host *computemodels.SHost, n *computemodels.SNetwork) (int, error) {
if host.IsEmulated {
// not calculate emulated host's network free address
return -1, nil
}
if val, ok := g.netFreeMap.Load(n.GetId()); ok {
return val.(int), nil
}
freePort, err := n.GetFreeAddressCount()
if err != nil {
return -1, errors.Wrapf(err, "GetFreeAddressCount for network %s(%s)", n.GetName(), n.GetId())
}
g.netFreeMap.Store(n.GetId(), freePort)
return freePort, nil
}
func newBaseHostDesc(b *baseBuilder, host *computemodels.SHost, netGetter *networkGetter) (*BaseHostDesc, error) {
host.ResourceType = reviseResourceType(host.ResourceType)
desc := &BaseHostDesc{
SHost: host,
@@ -336,17 +363,17 @@ func newBaseHostDesc(b *baseBuilder, host *computemodels.SHost) (*BaseHostDesc,
return nil, fmt.Errorf("Fill cloudprovider info error: %v", err)
}
if err := desc.fillNetworks(host); err != nil {
if err := desc.fillNetworks(host, netGetter); err != nil {
return nil, fmt.Errorf("Fill networks error: %v", err)
}
// only onecloud host should fill onecloud vpc networks
if host.HostType == computeapi.HOST_TYPE_HYPERVISOR {
if err := desc.fillOnecloudVpcNetworks(); err != nil {
if err := desc.fillOnecloudVpcNetworks(netGetter); err != nil {
return nil, fmt.Errorf("Fill onecloud vpc networks error: %v", err)
}
}
if host.HostType == computeapi.HOST_TYPE_CLOUDPODS {
if err := desc.fillCloudpodsVpcNetworks(); err != nil {
if err := desc.fillCloudpodsVpcNetworks(netGetter); err != nil {
return nil, fmt.Errorf("Fill cloudpods vpc networks error: %v", err)
}
}
@@ -430,7 +457,10 @@ func (b *BaseHostDesc) GetFreePort(netId string) int {
if selNet == nil {
return 0
}
// freeCount, _ := selNet.GetFreeAddressCount()
if b.IsEmulated {
freeCount, _ := selNet.GetFreeAddressCount()
return freeCount
}
return selNet.FreePort
}
@@ -583,7 +613,7 @@ func (b *BaseHostDesc) fillSharedDomains() error {
return nil
}
func (b *BaseHostDesc) fillNetworks(host *computemodels.SHost) error {
func (b *BaseHostDesc) fillNetworks(host *computemodels.SHost, netGetter *networkGetter) error {
hostId := host.Id
hostwires := computemodels.HostwireManager.Query().SubQuery()
sq := hostwires.Query(sqlchemy.DISTINCT("wire_id", hostwires.Field("wire_id"))).Equals("host_id", hostId)
@@ -597,9 +627,9 @@ func (b *BaseHostDesc) fillNetworks(host *computemodels.SHost) error {
}
b.Networks = make([]*api.CandidateNetwork, len(nets))
for idx, n := range nets {
freePort, err := n.GetFreeAddressCount()
freePort, err := netGetter.GetFreePort(host, &n)
if err != nil {
return errors.Wrapf(err, "GetFreeAddressCount for network %s(%s)", n.GetName(), n.GetId())
return errors.Wrapf(err, "GetFreePort for network %s(%s)", n.GetName(), n.GetId())
}
b.Networks[idx] = &api.CandidateNetwork{
SNetwork: &nets[idx],
@@ -628,7 +658,7 @@ func (b *BaseHostDesc) fillNetworks(host *computemodels.SHost) error {
return nil
}
func (b *BaseHostDesc) fillCloudpodsVpcNetworks() error {
func (b *BaseHostDesc) fillCloudpodsVpcNetworks(netGetter *networkGetter) error {
nets := computemodels.NetworkManager.Query()
wires := computemodels.WireManager.Query().SubQuery()
vpcs := computemodels.VpcManager.Query().SubQuery()
@@ -659,7 +689,7 @@ func (b *BaseHostDesc) fillCloudpodsVpcNetworks() error {
row := &rows[i]
net := &row.SNetwork
net.SetModelManager(computemodels.NetworkManager, net)
freePort, err := net.GetFreeAddressCount()
freePort, err := netGetter.GetFreePort(b.SHost, net)
if err != nil {
return errors.Wrapf(err, "GetFreeAddressCount for network %s(%s)", net.GetName(), net.GetId())
}
@@ -674,7 +704,7 @@ func (b *BaseHostDesc) fillCloudpodsVpcNetworks() error {
return nil
}
func (b *BaseHostDesc) fillOnecloudVpcNetworks() error {
func (b *BaseHostDesc) fillOnecloudVpcNetworks(netGetter *networkGetter) error {
nets := computemodels.NetworkManager.Query()
wires := computemodels.WireManager.Query().SubQuery()
vpcs := computemodels.VpcManager.Query().SubQuery()
@@ -705,7 +735,7 @@ func (b *BaseHostDesc) fillOnecloudVpcNetworks() error {
row := &rows[i]
net := &row.SNetwork
net.SetModelManager(computemodels.NetworkManager, net)
freePort, err := net.GetFreeAddressCount()
freePort, err := netGetter.GetFreePort(b.SHost, net)
if err != nil {
return errors.Wrapf(err, "GetFreeAddressCount for network %s(%s)", net.GetName(), net.GetId())
}
+7 -6
View File
@@ -759,14 +759,15 @@ func (b *HostBuilder) Do(ids []string) ([]interface{}, error) {
if err != nil {
return nil, err
}
descs, err := b.build()
netGetter := newNetworkGetter()
descs, err := b.build(netGetter)
if err != nil {
return nil, err
}
return descs, nil
}
func (b *HostBuilder) build() ([]interface{}, error) {
func (b *HostBuilder) build(netGetter *networkGetter) ([]interface{}, error) {
schedDescs := make([]interface{}, len(b.hosts))
errs := []error{}
var descResultLock gosync.Mutex
@@ -774,11 +775,11 @@ func (b *HostBuilder) build() ([]interface{}, error) {
buildOne := func(i int) {
if i >= len(b.hosts) {
log.Errorf("invalid host index[%d] in b.hosts:%v\n", i, b.hosts)
log.Errorf("invalid host index[%d] in b.hosts: %v", i, b.hosts)
return
}
host := b.hosts[i]
desc, err := b.buildOne(&host)
desc, err := b.buildOne(&host, netGetter)
if err != nil {
descResultLock.Lock()
errs = append(errs, err)
@@ -801,8 +802,8 @@ func (b *HostBuilder) build() ([]interface{}, error) {
return schedDescs, nil
}
func (b *HostBuilder) buildOne(host *computemodels.SHost) (interface{}, error) {
baseDesc, err := newBaseHostDesc(b.baseBuilder, host)
func (b *HostBuilder) buildOne(host *computemodels.SHost, netGetter *networkGetter) (interface{}, error) {
baseDesc, err := newBaseHostDesc(b.baseBuilder, host, netGetter)
if err != nil {
return nil, err
}