k8s源码设计模式之Flyweight

Flyweight也叫缓存Cache,享元模式

享元模式是一种结构型设计模式, 它摒弃了在每个对象中保存所有数据的方式, 通过共享多个对象所共有的相同状态, 让你能在有限的内存容量中载入更多对象。

在 Kubernetes 源码中,有多个地方使用了享元模式(Flyweight Pattern),其中最常见的就是 client-go 中的 cache 包。该包实现了 Kubernetes 中的各种资源对象的本地缓存,并使用享元模式来尽可能地重用缓存对象,以降低内存消耗和提高效率。

Informers Factory中,每个类型的资源(如PodsServicesDeployments等)只需要创建一个Informer即可,因为每个Informer可以观察到同一类型的所有资源对象。因此,在创建Informer之前,需要首先判断该类型的Informer是否已经存在。如果存在,则直接返回已经存在的Informer;否则,创建新的Informer并存储到f.informers中供以后使用。

这种设计方式减少了Informer的创建次数,提高了Informer的重用率,减少了系统开销,同时也降低了代码的复杂度。这正是享元模式的优点所在。

k8s中informer创建

k8s中的informer创建使用了享元模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// staging/src/k8s.io/client-go/informers/factory.go
func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer {
f.lock.Lock()
defer f.lock.Unlock()

informerType := reflect.TypeOf(obj)
// 判断是否已经存在
informer, exists := f.informers[informerType]
if exists {
return informer
}

resyncPeriod, exists := f.customResync[informerType]
if !exists {
resyncPeriod = f.defaultResync
}

informer = newFunc(f.client, resyncPeriod)
f.informers[informerType] = informer

return informer
}


REF:
1.client-go/informers/factory.go