Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I'm planning to implement a new scheduling algorithm, I don't know if it will be accepted? #61

Open
jianghushinian opened this issue Aug 13, 2022 · 0 comments

Comments

@jianghushinian
Copy link
Contributor

I found two scheduling algorithms getCapacityWeightedMap and getCapacityWeightedMap in the project , according to actual needs, I plan to implement a scheduling algorithm getFreeCapacityWeightedMap, it can be scores to nodes by disk free capacity, something like this:

device-localpv/pkg/driver/schd_helper.go:

// key value struct for creating the node list
type kv struct {
	Key   string
	Value int64
}

func getFreeCapacityWeightedMap(deviceName string) (map[string]int64, error) {
	nmap := map[string]int64{}

	nodeList, err := nodebuilder.NewKubeclient().
		WithNamespace(device.DeviceNamespace).
		List(metav1.ListOptions{})

	if err != nil {
		return nmap, err
	}

	// create the map of the free capacity
	// for the given deviceName
	nFreeMap := map[string]int64{}
	for _, n := range nodeList.Items {
		for _, dev := range n.Devices {
			i, ok := dev.Free.AsInt64()
			if !ok {
				klog.Infof("Disk: Free capacity convert int64 failure %s, %+v", dev.Free, err)
				continue
			}
			devRegex, err := regexp.Compile(dev.Name)
			if err != nil {
				klog.Infof("Disk: Regex compile failure %s, %+v", dev.Name, err)
				continue
			}
			if devRegex.MatchString(deviceName) {
				nFreeMap[n.Name] += i
			}
		}
	}

	var nList []kv
	for k, v := range nFreeMap {
		nList = append(nList, kv{k, v})
	}

	// sort the node map by free capacity
	sort.Slice(nList, func(i, j int) bool {
		return nList[i].Value > nList[j].Value
	})

	// score nodes by free capacity
	for i, v := range nList {
		nmap[v.Key] = int64(i)
	}

	return nmap, nil
}

It can query the disk free capacity on all nodes, and give higher scores to nodes with larger disk free capacity.

To do this, I will also modify the code that creates the DeviceNode CRD:

device-localpv/pkg/mgmt/devicenode/devicenode.go:

// syncNode is the function which tries to converge to a desired state for the
// DeviceNode
func (c *NodeController) syncNode(namespace string, name string) error {
	...
	if node == nil { // if it doesn't exists, create device node object
		if devices == nil {
			devices = []apis.Device{}
		}
		if node, err = nodebuilder.NewBuilder().
			WithNamespace(namespace).WithName(name).
			WithDevices(devices).
			WithOwnerReferences(c.ownerRef).
			Build(); err != nil {
			return err
		}

		klog.Infof("device node controller: creating new node object for %+v", node)
		if node, err = nodebuilder.NewKubeclient().WithNamespace(namespace).Create(node); err != nil {
			return fmt.Errorf("create device node %s/%s: %v", namespace, name, err)
		}
		klog.Infof("device node controller: created node object %s/%s", namespace, name)
		return nil
	}
	...
}

add this code:

if devices == nil {
	devices = []apis.Device{}
}

To avoid DeviceNode creation failure when devices == nil, the purpose is to query nodes without free capacity in getFreeCapacityWeightedMap, in this way, when scoring according to the free capacity, nodes with no free capacity will get a very low score, avoiding PV scheduling in the past.

That's my plan, looking forward to making suggestions and requests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant