Skip to content

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

Open
@jianghushinian

Description

@jianghushinian

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions