From 774c3e9c026599b8969cb7101dcacfc76d1fa2ef Mon Sep 17 00:00:00 2001 From: itsomri Date: Sun, 24 Aug 2025 15:06:21 +0300 Subject: [PATCH 1/4] WIP: incorporate usage in fair share --- .../resource_division/resource_division.go | 31 +++++++++++++++---- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/pkg/scheduler/plugins/proportion/resource_division/resource_division.go b/pkg/scheduler/plugins/proportion/resource_division/resource_division.go index 4309399bf..3e2c4560d 100644 --- a/pkg/scheduler/plugins/proportion/resource_division/resource_division.go +++ b/pkg/scheduler/plugins/proportion/resource_division/resource_division.go @@ -165,11 +165,15 @@ func divideUpToFairShare(totalResourceAmount, kValue float64, queues map[common_ for { shouldRunAnotherRound := false amountToGiveInCurrentRound := totalResourceAmount - totalWeights := getTotalWeightsForUnsatisfied(queues, resourceName) + totalWeights, totalUsages := getTotalWeightsForUnsatisfied(queues, resourceName) if totalWeights == 0 { break } + if totalUsages == 0 { + totalUsages = 1 + } + for _, queue := range queues { requested := getRemainingRequested(queue, resourceName) if requested == 0 { @@ -190,7 +194,12 @@ func divideUpToFairShare(totalResourceAmount, kValue float64, queues map[common_ log.InfraLogger.V(6).Infof("calculating %v resource fair share for %v: deserved: %v, "+ "remaining requested: %v, fairShare: %v", resourceName, queue.Name, resourceShare.Deserved, requested, resourceShare.FairShare) - fairShare := amountToGiveInCurrentRound * (overQuotaWeight / totalWeights) + + // normalize values + nWeight := overQuotaWeight / totalWeights + nUsage := resourceShare.GetUsage() / totalUsages + + fairShare := amountToGiveInCurrentRound * (nWeight + kValue*(nWeight-nUsage)) resourceToGive := getResourceToGiveInCurrentRound(fairShare, requested, queue, remainingRequested) if resourceToGive == 0 { continue @@ -255,14 +264,24 @@ func getResourceToGiveInCurrentRound(fairShare float64, requested float64, queue return resourcesToGive } -func getTotalWeightsForUnsatisfied(queues map[common_info.QueueID]*rs.QueueAttributes, resourceName rs.ResourceName) (totalOverQuotaWeights float64) { +func getTotalWeightsForUnsatisfied(queues map[common_info.QueueID]*rs.QueueAttributes, resourceName rs.ResourceName) (totalOverQuotaWeights, totalUsages float64) { for _, queue := range queues { remainingRequested := getRemainingRequested(queue, resourceName) - if remainingRequested > 0 { - totalOverQuotaWeights += queue.ResourceShare(resourceName).OverQuotaWeight + if remainingRequested <= 0 { + continue } + totalOverQuotaWeights += queue.ResourceShare(resourceName).OverQuotaWeight + + queueUsage := queue.ResourceShare(resourceName).GetUsage() + if queueUsage < 0 { + log.InfraLogger.V(1).Warnf("queue <%v> has negative usage score of <%v> for resource <%v>, expected non-negative", + queue.Name, queueUsage, resourceName) + continue + } + + totalUsages += queueUsage } - return totalOverQuotaWeights + return totalOverQuotaWeights, totalUsages } func getRemainingRequested(queue *rs.QueueAttributes, resourceName rs.ResourceName) float64 { From 3bd441d5d03d843a2adcdd76cc98042443b00fe7 Mon Sep 17 00:00:00 2001 From: itsomri Date: Thu, 28 Aug 2025 15:35:56 +0300 Subject: [PATCH 2/4] Normalize portion --- .../resource_division/resource_division.go | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/pkg/scheduler/plugins/proportion/resource_division/resource_division.go b/pkg/scheduler/plugins/proportion/resource_division/resource_division.go index 3e2c4560d..0116e3e21 100644 --- a/pkg/scheduler/plugins/proportion/resource_division/resource_division.go +++ b/pkg/scheduler/plugins/proportion/resource_division/resource_division.go @@ -174,6 +174,24 @@ func divideUpToFairShare(totalResourceAmount, kValue float64, queues map[common_ totalUsages = 1 } + portions := make(map[common_info.QueueID]float64) + totalPortions := 0.0 + for _, queue := range queues { + share := queue.ResourceShare(resourceName) + if share.Request <= share.FairShare { + // queue is satisfied, no need to give it more resources + continue + } + + // normalize values + nWeight := share.OverQuotaWeight / totalWeights + nUsage := share.GetUsage() / totalUsages + + portion := nWeight + kValue*(nWeight-nUsage) + portions[queue.UID] = portion + totalPortions += portion + } + for _, queue := range queues { requested := getRemainingRequested(queue, resourceName) if requested == 0 { @@ -195,11 +213,11 @@ func divideUpToFairShare(totalResourceAmount, kValue float64, queues map[common_ "remaining requested: %v, fairShare: %v", resourceName, queue.Name, resourceShare.Deserved, requested, resourceShare.FairShare) - // normalize values - nWeight := overQuotaWeight / totalWeights - nUsage := resourceShare.GetUsage() / totalUsages + // normalize portion + portion := portions[queue.UID] + nPortion := portion / totalPortions - fairShare := amountToGiveInCurrentRound * (nWeight + kValue*(nWeight-nUsage)) + fairShare := amountToGiveInCurrentRound * nPortion resourceToGive := getResourceToGiveInCurrentRound(fairShare, requested, queue, remainingRequested) if resourceToGive == 0 { continue From 231ba226a902d6df44f1b77dcdc906e867567c65 Mon Sep 17 00:00:00 2001 From: itsomri Date: Thu, 28 Aug 2025 15:44:39 +0300 Subject: [PATCH 3/4] Don't normalize usage --- .../proportion/resource_division/resource_division.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pkg/scheduler/plugins/proportion/resource_division/resource_division.go b/pkg/scheduler/plugins/proportion/resource_division/resource_division.go index 0116e3e21..510404d8f 100644 --- a/pkg/scheduler/plugins/proportion/resource_division/resource_division.go +++ b/pkg/scheduler/plugins/proportion/resource_division/resource_division.go @@ -183,9 +183,11 @@ func divideUpToFairShare(totalResourceAmount, kValue float64, queues map[common_ continue } - // normalize values + // Normalize queue over quota weight nWeight := share.OverQuotaWeight / totalWeights - nUsage := share.GetUsage() / totalUsages + + // We assume that usage is normalized to usage/clusterCapacity + nUsage := share.GetUsage() portion := nWeight + kValue*(nWeight-nUsage) portions[queue.UID] = portion From cfd410e7a5aa4e85632f5c03923e7028782909bd Mon Sep 17 00:00:00 2001 From: itsomri Date: Thu, 28 Aug 2025 15:45:54 +0300 Subject: [PATCH 4/4] Floor portion to 0 --- .../proportion/resource_division/resource_division.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pkg/scheduler/plugins/proportion/resource_division/resource_division.go b/pkg/scheduler/plugins/proportion/resource_division/resource_division.go index 510404d8f..6daaac898 100644 --- a/pkg/scheduler/plugins/proportion/resource_division/resource_division.go +++ b/pkg/scheduler/plugins/proportion/resource_division/resource_division.go @@ -189,11 +189,17 @@ func divideUpToFairShare(totalResourceAmount, kValue float64, queues map[common_ // We assume that usage is normalized to usage/clusterCapacity nUsage := share.GetUsage() - portion := nWeight + kValue*(nWeight-nUsage) + // Floor portion to 0 if it's negative + portion := math.Max(0, nWeight+kValue*(nWeight-nUsage)) + portions[queue.UID] = portion totalPortions += portion } + if totalPortions == 0 { + break + } + for _, queue := range queues { requested := getRemainingRequested(queue, resourceName) if requested == 0 {