Code change:
} } <ins> func nodeSchedulingPropertiesChanged(newNode *v1.Node, oldNode *v1.Node) bool { if nodeSpecUnschedulableChanged(newNode, oldNode) { return true } if nodeAllocatableChanged(newNode, oldNode) { return true } if nodeLabelsChanged(newNode, oldNode) { return true } if nodeTaintsChanged(newNode, oldNode) { return true } if nodeConditionsChanged(newNode, oldNode) { return true } return false } func nodeAllocatableChanged(newNode *v1.Node, oldNode *v1.Node) bool { return !reflect.DeepEqual(oldNode.Status.Allocatable, newNode.Status.Allocatable) } func nodeLabelsChanged(newNode *v1.Node, oldNode *v1.Node) bool { return !reflect.DeepEqual(oldNode.GetLabels(), newNode.GetLabels()) } func nodeTaintsChanged(newNode *v1.Node, oldNode *v1.Node) bool { return !reflect.DeepEqual(newNode.Spec.Taints, oldNode.Spec.Taints) } func nodeConditionsChanged(newNode *v1.Node, oldNode *v1.Node) bool { strip := func(conditions []v1.NodeCondition) map[v1.NodeConditionType]v1.ConditionStatus { conditionStatuses := make(map[v1.NodeConditionType]v1.ConditionStatus, len(conditions)) for i := range conditions { conditionStatuses[conditions[i].Type] = conditions[i].Status } return conditionStatuses } return !reflect.DeepEqual(strip(oldNode.Status.Conditions), strip(newNode.Status.Conditions)) } func nodeSpecUnschedulableChanged(newNode *v1.Node, oldNode *v1.Node) bool { return newNode.Spec.Unschedulable != oldNode.Spec.Unschedulable && newNode.Spec.Unschedulable == false } </ins> func (c *configFactory) deleteNodeFromCache(obj interface{}) { var node *v1.Node switch t := obj.(type) {

Related discussion:
text: <!-- Please only use this template for submitting enhancement requests --What would you like to be : Today, the scheduler re-processes unschedulable nodes . Node updates are sent by Kubelet frequently (every 10 seconds) and often times they don't change any of the node properties that could potentially make them feasible. We should be smarter about these updates and move pods to the schedulable queue only when certain properties of nodes change that could make them feasible. These properties include node allocatable, node conditions, taints, labels, .... Why is this needed: Improves performance of the scheduler and avoids doing unnecessary attempts to schedule pods. This is particularly helpful when a cluster has a lot of unschedulable pods. <!-- DO NOT EDIT BELOW THIS LINE --/kind feature This is not a feature really. It is performance optimization, but in the absence of such a label, I need to use "feature" here. /sig scheduling
I can help to fix it. /assign mlmhl
The main reason for this problem is / update their status too frequently and most of these updates are heartbeats without any meaningful change. Recently sig-node introduces a new to alleviate this problem. With this mechanism, kubelet will split heartbeat and node status updates into two independent operations, and reduce the frequency of status updates to once per 1 minute(or more). In the long run this mechanism can indeed alleviate our problems, but at present it does not help us much as this is still an alpha feature and the node status updates frequency is still a bit high(per 1 minute right now).
Maybe we can try comparing old and new nodes after stripping their heartbeat info, like this:
I think that had sent earlier is more efficient. However, that PR does not filter out . In Wei's code, the heartbeat time is removed correctly. I think we should fix this issue and resubmit that PR.
could you resubmit a PR to: disregard in conditions comparison: and (optionally) disregard timestamp in taints comparison:
Thanks for all your advice, a new PR is submitted: This PR does not include your second suggestion(disregard timestamp in taints comparison) as I'm not sure if can be changed when node updating.