Cwww3's Blog

Record what you think

0%

Informer机制

在这里插入图片描述

在 Informer 架构中,有多个核心组件

Reflector

Reflector 是用于监控指定资源的(Watch),一旦资源发生改变,将资源存入 DeltaFIFO 中。

在第一次运行时,会先获取一份完成的资源列表(List)存入 DeltaFIFO 中。

DeltaFIFO

DeltaFIFO 可以分开理解,首先 FIFO 是一个先进先出的队列,拥有操作队列的基本方法,Delta 则是存储资源对象以及对象的操作类型(Add/Delete/Update/Sync),DeltaFIFO 与其他队列最大的不同则是它会保留所有资源对象的操作类型,即队列中会存在拥有不同操作类型的同一个资源对象。

1
2
3
4
5
6
7
type DeltaFIFO struct {
...
queue []string // 存储的是key,资源对象通过KeyOf生成key,key与资源对象对应
items map[string]Deltas // map的key就是queue中的元素
}

type Deltas []Delta // Delta 保存的是资源对象以及操作类型 Deltas中每个资源的操作类型都不同(去重)

资源从队列中被 Pop 出之后,会执行 informer 会调用 HandleDeltas 方法,将它加入到 indexder 中,此外,还会将它分发给用户通过 Informer 的 AddEventHandler 方法注册的回调函数中。

Resync

Resync 机制会将 Indexer 中存储的资源对象同步到 DeltaFIFO 中,并将这些资源对象设置为 Sync 的操作类型。

Resync 函数在 Reflector 中定时执行,执行周期由创建 informer 时设定。

Indexer

indexer 是 client-go 用来存储资源对象并自带索引功能的本地存储。Reflector 从 DeltaFIFO 中取出对象存储至 Indexer。Indexer 与 Etcd 中所保存的数据完全一致,client-go 可以很方便的从本地获取数据,而不需要每次请求 API Server 从 Etcd 中获取数据,从而减轻了 API Server 和 Etcd 的压力。

Indexer 是在 ThreadSafeMap 的基础上进行封装的。ThreadSafeMap 是一个并发读写安全的 map,Indexer 在此基础上实现了索引功能。

Index 有四个非常重要的数据结构,分别是 Indices(index 的复数形式),index,Indexers 和 IndexerFunc。

1
2
3
4
type Indexers map[string]IndexFunc
type IndexFunc func(obj interface{}) ([]string, error)
type Indices map[string]Index
type Index map[string]sets.String

Indexers:用于存储索引器,key 为索引器的名称,value 位索引器的实现函数,它定义了获取资源对象的什么信息,以及如何获取,并组装成字符串数组返回。

IndexFunc: 索引器函数,定义为接收一个资源对象,返回检索结果列表

Indeces: 用于存储 Index,key 为索引器的名字,value 为 Index

index: 用于存储缓存的数据

index.ByIndex 函数通过执行索引器函数得到索引结果。

1
2
3
4
5
6
7
8
9
10
func (c *threadSafeMap) ByIndex(indexName, indexKey string) ([]interface(),error)
{
...
indexFunc := c.indexers[indexName] // 根据索引器名称得到索引器函数
... // 执行该函数

index := c.indices[indexName] // 根据索引器名称从indices中获取index
set := index[indexKey] // 根据查询的key得到查询的结果
...
}
Donate comment here.