Change:
<!-- Please only use this template for submitting enhancement requests --What would you like to be : Kubernetes scheduler has that specifies what percentage of the cluster nodes should be scored in each scheduling cycle. The scheduler stops scanning more nodes once that many nodes are found feasible for running the pod under consideration. The default value of this config option is 50 (for 50%). We should let the scheduler determine this value based on the size of the cluster when this config option is not provided. I'd propose this formula for finding the percentage: . This is a linear formula that gives us 50 when the cluster size is 100 nodes and 10 for a 5000 node cluster. The scheduler already has a lower bound of 50 nodes per scheduling cycle. As a part of this change, we should also add a 5% lower bound for the formula (If the result of the formula is below 5, we should return 5). Why is this needed: To improve scheduler performance in large clusters. <!-- DO NOT EDIT BELOW THIS LINE --/kind feature /sig scheduling
/assign /remove-help
/assign wgliang
Thanks

Discussion:
Burst:       100, ContentType: "application/vnd.kubernetes.protobuf", }, <del> PercentageOfNodesToScore: 50, BindTimeoutSeconds:       &defaultBindTimeoutSeconds, </del> <ins> BindTimeoutSeconds: &defaultBindTimeoutSeconds, </ins> }, }, {

// at least "minFeasibleNodesToFind" feasible nodes no matter what the value of this flag is. // Example: if the cluster size is 500 nodes and the value of this flag is 30, // then scheduler stops finding further feasible nodes once it finds 150 feasible ones. <del> // When the value is 0, default percentage (50%) of the nodes will be scored. </del> <ins> // When the value is 0, default percentage (5%--50% based on the size of the cluster) of the // nodes will be scored. </ins> PercentageOfNodesToScore int32 // DEPRECATED.

obj.LeaderElection.LockObjectName = kubescedulerconfigv1alpha1.SchedulerDefaultLockObjectName } <del> if obj.PercentageOfNodesToScore == 0 { // by default, stop finding feasible nodes once the number of feasible nodes is 50% of the cluster. obj.PercentageOfNodesToScore = 50 } </del> if len(obj.FailureDomains) == 0 { obj.FailureDomains = kubeletapis.DefaultFailureDomains }

// certain minimum of nodes are checked for feasibility. This in turn helps // ensure a minimum level of spreading. minFeasibleNodesToFind = 100 <ins> // minFeasibleNodesPercentageToFind is the minimum percentage of nodes that // would be scored in each scheduling cycle. This is a semi-arbitrary value // to ensure that a certain minimum of nodes are checked for feasibility. // This in turn helps ensure a minimum level of spreading. minFeasibleNodesPercentageToFind = 5 </ins> ) // FailedPredicateMap declares a map[string][]algorithm.PredicateFailureReason type.

// numFeasibleNodesToFind returns the number of feasible nodes that once found, the scheduler stops // its search for more feasible nodes. <del> func (g *genericScheduler) numFeasibleNodesToFind(numAllNodes int32) int32 { if numAllNodes < minFeasibleNodesToFind || g.percentageOfNodesToScore <= 0 || g.percentageOfNodesToScore >= 100 { </del> <ins> func (g *genericScheduler) numFeasibleNodesToFind(numAllNodes int32) (numNodes int32) { if numAllNodes < minFeasibleNodesToFind || g.percentageOfNodesToScore >= 100 { </ins> return numAllNodes } <del> numNodes := numAllNodes * g.percentageOfNodesToScore / 100 </del> <ins> adaptivePercentage := g.percentageOfNodesToScore if adaptivePercentage <= 0 { adaptivePercentage = schedulerapi.DefaultPercentageOfNodesToScore - numAllNodes/125 if adaptivePercentage < minFeasibleNodesPercentageToFind { adaptivePercentage = minFeasibleNodesPercentageToFind } } numNodes = numAllNodes * adaptivePercentage / 100 </ins> if numNodes < minFeasibleNodesToFind { return minFeasibleNodesToFind } return numNodes }

}) } } <ins> func TestNumFeasibleNodesToFind(t *testing.T) { tests := []struct { name                     string percentageOfNodesToScore int32 numAllNodes              int32 wantNumNodes             int32 }{ { name:         "not set percentageOfNodesToScore and nodes number not more than 50", numAllNodes:  10, wantNumNodes: 10, }, { name:                     "set percentageOfNodesToScore and nodes number not more than 50", percentageOfNodesToScore: 40, numAllNodes:              10, wantNumNodes:             10, }, { name:         "not set percentageOfNodesToScore and nodes number more than 50", numAllNodes:  1000, wantNumNodes: 420, }, { name:                     "set percentageOfNodesToScore and nodes number more than 50", percentageOfNodesToScore: 40, numAllNodes:              1000, wantNumNodes:             400, }, { name:         "not set percentageOfNodesToScore and nodes number more than 50*125", numAllNodes:  6000, wantNumNodes: 300, }, { name:                     "set percentageOfNodesToScore and nodes number more than 50*125", percentageOfNodesToScore: 40, numAllNodes:              6000, wantNumNodes:             2400, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { g := &genericScheduler{ percentageOfNodesToScore: tt.percentageOfNodesToScore, } if gotNumNodes := g.numFeasibleNodesToFind(tt.numAllNodes); gotNumNodes != tt.wantNumNodes { t.Errorf("genericScheduler.numFeasibleNodesToFind() = %v, want %v", gotNumNodes, tt.wantNumNodes) } }) } } </ins>

// at least "minFeasibleNodesToFind" feasible nodes no matter what the value of this flag is. // Example: if the cluster size is 500 nodes and the value of this flag is 30, // then scheduler stops finding further feasible nodes once it finds 150 feasible ones. <del> // When the value is 0, default percentage (50%) of the nodes will be scored. </del> <ins> // When the value is 0, default percentage (5%--50% based on the size of the cluster) of the // nodes will be scored. </ins> PercentageOfNodesToScore int32 `json:"percentageOfNodesToScore"` // DEPRECATED.