Indexer
Indexer原理
我们知道reflector会生产数据放入到Delta FIFO Queue
这个队列里面,然后Delta FIFO会将数据交给下方的消费者,这里有两个消费者,一个是事件处理办法(sharedProcessor),一个是indexers。Delta FIFO数据处理完之后它就会进行删除,这个indexers此时会将所有数据保存下来(也就是这个indexers这个组件会将所有全量数据进行缓存,并实时更新),它存储的数据跟API server的数据是保持一致的,所以当Controller需要读取某个对象的数据的时候,一方面可以通过直接调用APS server的读请求 ,另一方面也可以通过indexers来读取,有了indexers这样可以减轻apiserver的压力。
数据存储
cache委托threadSafeMap存放数据
type Indexer interface {
Store
Index(indexName string, obj interface{}) ([]interface{}, error)
IndexKeys(indexName, indexedValue string) ([]string, error)
ListIndexFuncValues(indexName string) []string
ByIndex(indexName, indexedValue string) ([]interface{}, error)
GetIndexers() Indexers
AddIndexers(newIndexers Indexers) error
}
建立索引
//key是IndexFunc计算出来的结果,比如default,value是所有obj的key的集合
type Index map[string]sets.String
//key是索引的分类名,比如namespace,value是一个方法,通过该方法可以获取obj的namespace,比如default(value就是一个index的function[指IndexFunc],这个IndexFunc它的定义其实就是通过我们传入一个object,它会返回一个index的数组,然后我们可以通过这个方法获取到object的namespace,比如说default)
type Indexers map[string]IndexFunc
//key是索引的分类名,比如namespace(Indices最开始的初始化状态,其实也是一个空的map。它的key和indexers是一样的。比如说上面第二个key是namespace,下面这个key也是namespace,然后通过这个namespace我们可以到index【第一条】, index它其实是一个也是一个map,比如说它的key可能是default,然后通过这个key就可以拿到default这个namespace下的所有pods的key,此时就拿到了default这个namespace下的所有的pod的key,然后再通过这些key,去items里面去获取对应的pod。这样就可以加快访问指定索引下的数据。)
type Indices map[string]Index
更新索引
通过updateIndices
实现
其实所有的added方法、updated方法、deleted方法等等,都会调用updateIndices这个方法。
在刚开始Indices没有数据的时候,那我们就是建立索引;当有数据的时候,数据发生变更相当于就是更新索引。
如上图所示,比如我们要更新索引,需要经历下面的步骤:
1、首先知道我们的indexers是什么
2、然后通过循环
3、取得支持的index的维度(比如namespace)
4、然后通过Indices指定它的key为namespace
5、然后我们就可以得到一个Index,然后会判断这个Index它是不是存在
6、如果不存在,我们会根据当前这个对象调用这个indexFunc(obj)
7、获取到它的index(比如是default,我们的namespace是default)
6、它其实取的object的namespace那个字段,取得这个字段之后,因为这个func本身得到的是一个数组
8、所以我们这里需要循环一下
9、将我们的index的value取出来,比如我们得到的可能就是default
5、这时只需要根据这个index它的key为default
9、然后同时把这个对象的key获取出来
10、然后放到这个index的set里面去,那如果存在的话,它可能就会去更新我们这个set了。