mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	Merge pull request #102330 from tnqn/replicaset-optimization
Add controllerUID index to improve ReplicaSetController performance
This commit is contained in:
		@@ -71,6 +71,10 @@ const (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// The number of times we retry updating a ReplicaSet's status.
 | 
						// The number of times we retry updating a ReplicaSet's status.
 | 
				
			||||||
	statusUpdateRetries = 1
 | 
						statusUpdateRetries = 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// controllerUIDIndex is the name for the ReplicaSet store's index function,
 | 
				
			||||||
 | 
						// which is to index by ReplicaSet's controllerUID.
 | 
				
			||||||
 | 
						controllerUIDIndex = "controllerUID"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ReplicaSetController is responsible for synchronizing ReplicaSet objects stored
 | 
					// ReplicaSetController is responsible for synchronizing ReplicaSet objects stored
 | 
				
			||||||
@@ -98,6 +102,7 @@ type ReplicaSetController struct {
 | 
				
			|||||||
	// rsListerSynced returns true if the pod store has been synced at least once.
 | 
						// rsListerSynced returns true if the pod store has been synced at least once.
 | 
				
			||||||
	// Added as a member to the struct to allow injection for testing.
 | 
						// Added as a member to the struct to allow injection for testing.
 | 
				
			||||||
	rsListerSynced cache.InformerSynced
 | 
						rsListerSynced cache.InformerSynced
 | 
				
			||||||
 | 
						rsIndexer      cache.Indexer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// A store of pods, populated by the shared informer passed to NewReplicaSetController
 | 
						// A store of pods, populated by the shared informer passed to NewReplicaSetController
 | 
				
			||||||
	podLister corelisters.PodLister
 | 
						podLister corelisters.PodLister
 | 
				
			||||||
@@ -150,6 +155,20 @@ func NewBaseController(rsInformer appsinformers.ReplicaSetInformer, podInformer
 | 
				
			|||||||
		UpdateFunc: rsc.updateRS,
 | 
							UpdateFunc: rsc.updateRS,
 | 
				
			||||||
		DeleteFunc: rsc.deleteRS,
 | 
							DeleteFunc: rsc.deleteRS,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
						rsInformer.Informer().AddIndexers(cache.Indexers{
 | 
				
			||||||
 | 
							controllerUIDIndex: func(obj interface{}) ([]string, error) {
 | 
				
			||||||
 | 
								rs, ok := obj.(*apps.ReplicaSet)
 | 
				
			||||||
 | 
								if !ok {
 | 
				
			||||||
 | 
									return []string{}, nil
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								controllerRef := metav1.GetControllerOf(rs)
 | 
				
			||||||
 | 
								if controllerRef == nil {
 | 
				
			||||||
 | 
									return []string{}, nil
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return []string{string(controllerRef.UID)}, nil
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						rsc.rsIndexer = rsInformer.Informer().GetIndexer()
 | 
				
			||||||
	rsc.rsLister = rsInformer.Lister()
 | 
						rsc.rsLister = rsInformer.Lister()
 | 
				
			||||||
	rsc.rsListerSynced = rsInformer.Informer().HasSynced
 | 
						rsc.rsListerSynced = rsInformer.Informer().HasSynced
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -206,17 +225,14 @@ func (rsc *ReplicaSetController) getReplicaSetsWithSameController(rs *apps.Repli
 | 
				
			|||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	allRSs, err := rsc.rsLister.ReplicaSets(rs.Namespace).List(labels.Everything())
 | 
						objects, err := rsc.rsIndexer.ByIndex(controllerUIDIndex, string(controllerRef.UID))
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		utilruntime.HandleError(err)
 | 
							utilruntime.HandleError(err)
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						relatedRSs := make([]*apps.ReplicaSet, 0, len(objects))
 | 
				
			||||||
	var relatedRSs []*apps.ReplicaSet
 | 
						for _, obj := range objects {
 | 
				
			||||||
	for _, r := range allRSs {
 | 
							relatedRSs = append(relatedRSs, obj.(*apps.ReplicaSet))
 | 
				
			||||||
		if ref := metav1.GetControllerOf(r); ref != nil && ref.UID == controllerRef.UID {
 | 
					 | 
				
			||||||
			relatedRSs = append(relatedRSs, r)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// The if check is used to avoid the overhead for the KObjs call, see
 | 
						// The if check is used to avoid the overhead for the KObjs call, see
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,6 +36,7 @@ import (
 | 
				
			|||||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
						metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/runtime"
 | 
						"k8s.io/apimachinery/pkg/runtime"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/runtime/schema"
 | 
						"k8s.io/apimachinery/pkg/runtime/schema"
 | 
				
			||||||
 | 
						"k8s.io/apimachinery/pkg/types"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/util/sets"
 | 
						"k8s.io/apimachinery/pkg/util/sets"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/util/uuid"
 | 
						"k8s.io/apimachinery/pkg/util/uuid"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/util/wait"
 | 
						"k8s.io/apimachinery/pkg/util/wait"
 | 
				
			||||||
@@ -438,6 +439,36 @@ func TestGetReplicaSetsWithSameController(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func BenchmarkGetReplicaSetsWithSameController(b *testing.B) {
 | 
				
			||||||
 | 
						stopCh := make(chan struct{})
 | 
				
			||||||
 | 
						defer close(stopCh)
 | 
				
			||||||
 | 
						controller, informers := testNewReplicaSetControllerFromClient(clientset.NewForConfigOrDie(&restclient.Config{Host: "", ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Group: "", Version: "v1"}}}), stopCh, BurstReplicas)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						targetRS := newReplicaSet(1, map[string]string{"foo": "bar"})
 | 
				
			||||||
 | 
						targetRS.Name = "rs1"
 | 
				
			||||||
 | 
						targetRS.ObjectMeta.OwnerReferences[0].UID = "123456"
 | 
				
			||||||
 | 
						informers.Apps().V1().ReplicaSets().Informer().GetIndexer().Add(targetRS)
 | 
				
			||||||
 | 
						relatedRS := newReplicaSet(1, map[string]string{"foo": "bar"})
 | 
				
			||||||
 | 
						relatedRS.Name = "rs2"
 | 
				
			||||||
 | 
						relatedRS.ObjectMeta.OwnerReferences[0].UID = "123456"
 | 
				
			||||||
 | 
						informers.Apps().V1().ReplicaSets().Informer().GetIndexer().Add(relatedRS)
 | 
				
			||||||
 | 
						for i := 0; i < 100; i++ {
 | 
				
			||||||
 | 
							unrelatedRS := newReplicaSet(1, map[string]string{"foo": fmt.Sprintf("baz-%d", i)})
 | 
				
			||||||
 | 
							unrelatedRS.Name = fmt.Sprintf("rs-%d", i)
 | 
				
			||||||
 | 
							unrelatedRS.ObjectMeta.OwnerReferences[0].UID = types.UID(fmt.Sprintf("%d", i))
 | 
				
			||||||
 | 
							informers.Apps().V1().ReplicaSets().Informer().GetIndexer().Add(unrelatedRS)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						b.ReportAllocs()
 | 
				
			||||||
 | 
						b.ResetTimer()
 | 
				
			||||||
 | 
						for n := 0; n < b.N; n++ {
 | 
				
			||||||
 | 
							gotRSs := controller.getReplicaSetsWithSameController(targetRS)
 | 
				
			||||||
 | 
							if len(gotRSs) != 2 {
 | 
				
			||||||
 | 
								b.Errorf("Incorrect ReplicaSets number, expected 2, got: %d", len(gotRSs))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestPodControllerLookup(t *testing.T) {
 | 
					func TestPodControllerLookup(t *testing.T) {
 | 
				
			||||||
	stopCh := make(chan struct{})
 | 
						stopCh := make(chan struct{})
 | 
				
			||||||
	defer close(stopCh)
 | 
						defer close(stopCh)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user