tools/cache 深度分析(上篇)--- 模块定位、整体结构、接口与依赖关系
基于
client-go v0.36.1tools/cache/源码的超深度、逐行、专业级分析源文件共 30 个 Go 文件(非测试),合计 ~9789 行
一、模块定位
1.1 业务职责与功能定位
tools/cache 是 client-go 中最核心的客户端缓存框架,实现了 Kubernetes Controller 的标准编程范式(Informer 模式)。它提供了从 API Server 监听资源变更、本地缓存、事件分发、队列处理的完整基础设施。
核心职责:
| 职责 | 描述 |
|---|---|
| 资源监听 | Reflector 通过 ListWatch 从 API Server 获取初始数据并持续 Watch |
| 变更缓冲 | DeltaFIFO / RealFIFO 缓冲变更事件,保证有序、去重 |
| 本地缓存 | Store / cache / threadSafeStore 提供线程安全的本地读写缓存 |
| 索引查询 | Indexer 支持按 Namespace、Label 等维度高效查询 |
| 事件分发 | sharedProcessor 将变更事件扇出给多个 Listener |
| 生命周期 | SharedInformer 统一管理 Reflector + FIFO + Store + Processor |
| TTL 过期 | ExpirationCache 提供带 TTL 的自动过期缓存 |
| 优先队列 | Heap 提供线程安全的优先队列 |
| 变更检测 | MutationDetector 检测缓存对象被非法修改 |
| 优雅同步 | synctrack 追踪初始同步是否完成 |
1.2 在系统中的位置
#mermaid-svg-h74Oa6QOLd20UAlx{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-h74Oa6QOLd20UAlx .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-h74Oa6QOLd20UAlx .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-h74Oa6QOLd20UAlx .error-icon{fill:#552222;}#mermaid-svg-h74Oa6QOLd20UAlx .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-h74Oa6QOLd20UAlx .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-h74Oa6QOLd20UAlx .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-h74Oa6QOLd20UAlx .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-h74Oa6QOLd20UAlx .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-h74Oa6QOLd20UAlx .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-h74Oa6QOLd20UAlx .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-h74Oa6QOLd20UAlx .marker{fill:#333333;stroke:#333333;}#mermaid-svg-h74Oa6QOLd20UAlx .marker.cross{stroke:#333333;}#mermaid-svg-h74Oa6QOLd20UAlx svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-h74Oa6QOLd20UAlx p{margin:0;}#mermaid-svg-h74Oa6QOLd20UAlx .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-h74Oa6QOLd20UAlx .cluster-label text{fill:#333;}#mermaid-svg-h74Oa6QOLd20UAlx .cluster-label span{color:#333;}#mermaid-svg-h74Oa6QOLd20UAlx .cluster-label span p{background-color:transparent;}#mermaid-svg-h74Oa6QOLd20UAlx .label text,#mermaid-svg-h74Oa6QOLd20UAlx span{fill:#333;color:#333;}#mermaid-svg-h74Oa6QOLd20UAlx .node rect,#mermaid-svg-h74Oa6QOLd20UAlx .node circle,#mermaid-svg-h74Oa6QOLd20UAlx .node ellipse,#mermaid-svg-h74Oa6QOLd20UAlx .node polygon,#mermaid-svg-h74Oa6QOLd20UAlx .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-h74Oa6QOLd20UAlx .rough-node .label text,#mermaid-svg-h74Oa6QOLd20UAlx .node .label text,#mermaid-svg-h74Oa6QOLd20UAlx .image-shape .label,#mermaid-svg-h74Oa6QOLd20UAlx .icon-shape .label{text-anchor:middle;}#mermaid-svg-h74Oa6QOLd20UAlx .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-h74Oa6QOLd20UAlx .rough-node .label,#mermaid-svg-h74Oa6QOLd20UAlx .node .label,#mermaid-svg-h74Oa6QOLd20UAlx .image-shape .label,#mermaid-svg-h74Oa6QOLd20UAlx .icon-shape .label{text-align:center;}#mermaid-svg-h74Oa6QOLd20UAlx .node.clickable{cursor:pointer;}#mermaid-svg-h74Oa6QOLd20UAlx .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-h74Oa6QOLd20UAlx .arrowheadPath{fill:#333333;}#mermaid-svg-h74Oa6QOLd20UAlx .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-h74Oa6QOLd20UAlx .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-h74Oa6QOLd20UAlx .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-h74Oa6QOLd20UAlx .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-h74Oa6QOLd20UAlx .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-h74Oa6QOLd20UAlx .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-h74Oa6QOLd20UAlx .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-h74Oa6QOLd20UAlx .cluster text{fill:#333;}#mermaid-svg-h74Oa6QOLd20UAlx .cluster span{color:#333;}#mermaid-svg-h74Oa6QOLd20UAlx div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-h74Oa6QOLd20UAlx .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-h74Oa6QOLd20UAlx rect.text{fill:none;stroke-width:0;}#mermaid-svg-h74Oa6QOLd20UAlx .icon-shape,#mermaid-svg-h74Oa6QOLd20UAlx .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-h74Oa6QOLd20UAlx .icon-shape p,#mermaid-svg-h74Oa6QOLd20UAlx .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-h74Oa6QOLd20UAlx .icon-shape .label rect,#mermaid-svg-h74Oa6QOLd20UAlx .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-h74Oa6QOLd20UAlx .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-h74Oa6QOLd20UAlx .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-h74Oa6QOLd20UAlx :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} API Server
REST Client Layer
tools/cache (本次分析)
Application Layer
用户 Controller
WorkQueue
GenericLister
SharedInformer
Controller
Reflector
DeltaFIFO
RealFIFO
cache / Store
threadSafeStore
Indexer / storeIndex
sharedProcessor
processorListener
ListWatch
MutationDetector
ExpirationCache
Heap
MutationCache
UndeltaStore
InformerName
synctrack
RetryWithDeadline
ObjectName
rest.Client
watch.Interface
kube-apiserver
1.3 数据流入流出
#mermaid-svg-II9ZcQ6DsY3Eehfd{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-II9ZcQ6DsY3Eehfd .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-II9ZcQ6DsY3Eehfd .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-II9ZcQ6DsY3Eehfd .error-icon{fill:#552222;}#mermaid-svg-II9ZcQ6DsY3Eehfd .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-II9ZcQ6DsY3Eehfd .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-II9ZcQ6DsY3Eehfd .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-II9ZcQ6DsY3Eehfd .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-II9ZcQ6DsY3Eehfd .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-II9ZcQ6DsY3Eehfd .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-II9ZcQ6DsY3Eehfd .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-II9ZcQ6DsY3Eehfd .marker{fill:#333333;stroke:#333333;}#mermaid-svg-II9ZcQ6DsY3Eehfd .marker.cross{stroke:#333333;}#mermaid-svg-II9ZcQ6DsY3Eehfd svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-II9ZcQ6DsY3Eehfd p{margin:0;}#mermaid-svg-II9ZcQ6DsY3Eehfd .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-II9ZcQ6DsY3Eehfd .cluster-label text{fill:#333;}#mermaid-svg-II9ZcQ6DsY3Eehfd .cluster-label span{color:#333;}#mermaid-svg-II9ZcQ6DsY3Eehfd .cluster-label span p{background-color:transparent;}#mermaid-svg-II9ZcQ6DsY3Eehfd .label text,#mermaid-svg-II9ZcQ6DsY3Eehfd span{fill:#333;color:#333;}#mermaid-svg-II9ZcQ6DsY3Eehfd .node rect,#mermaid-svg-II9ZcQ6DsY3Eehfd .node circle,#mermaid-svg-II9ZcQ6DsY3Eehfd .node ellipse,#mermaid-svg-II9ZcQ6DsY3Eehfd .node polygon,#mermaid-svg-II9ZcQ6DsY3Eehfd .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-II9ZcQ6DsY3Eehfd .rough-node .label text,#mermaid-svg-II9ZcQ6DsY3Eehfd .node .label text,#mermaid-svg-II9ZcQ6DsY3Eehfd .image-shape .label,#mermaid-svg-II9ZcQ6DsY3Eehfd .icon-shape .label{text-anchor:middle;}#mermaid-svg-II9ZcQ6DsY3Eehfd .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-II9ZcQ6DsY3Eehfd .rough-node .label,#mermaid-svg-II9ZcQ6DsY3Eehfd .node .label,#mermaid-svg-II9ZcQ6DsY3Eehfd .image-shape .label,#mermaid-svg-II9ZcQ6DsY3Eehfd .icon-shape .label{text-align:center;}#mermaid-svg-II9ZcQ6DsY3Eehfd .node.clickable{cursor:pointer;}#mermaid-svg-II9ZcQ6DsY3Eehfd .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-II9ZcQ6DsY3Eehfd .arrowheadPath{fill:#333333;}#mermaid-svg-II9ZcQ6DsY3Eehfd .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-II9ZcQ6DsY3Eehfd .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-II9ZcQ6DsY3Eehfd .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-II9ZcQ6DsY3Eehfd .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-II9ZcQ6DsY3Eehfd .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-II9ZcQ6DsY3Eehfd .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-II9ZcQ6DsY3Eehfd .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-II9ZcQ6DsY3Eehfd .cluster text{fill:#333;}#mermaid-svg-II9ZcQ6DsY3Eehfd .cluster span{color:#333;}#mermaid-svg-II9ZcQ6DsY3Eehfd div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-II9ZcQ6DsY3Eehfd .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-II9ZcQ6DsY3Eehfd rect.text{fill:none;stroke-width:0;}#mermaid-svg-II9ZcQ6DsY3Eehfd .icon-shape,#mermaid-svg-II9ZcQ6DsY3Eehfd .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-II9ZcQ6DsY3Eehfd .icon-shape p,#mermaid-svg-II9ZcQ6DsY3Eehfd .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-II9ZcQ6DsY3Eehfd .icon-shape .label rect,#mermaid-svg-II9ZcQ6DsY3Eehfd .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-II9ZcQ6DsY3Eehfd .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-II9ZcQ6DsY3Eehfd .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-II9ZcQ6DsY3Eehfd :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 数据消费
tools/cache
数据源
List() → 初始数据
Watch() → 增量事件
Reflector
DeltaFIFO / RealFIFO
Store / Indexer
Processor
ResourceEventHandler
WorkQueue
GenericLister
二、模块整体结构
2.1 核心接口层次与类结构
渲染错误: Mermaid 渲染失败: Parse error on line 7: ... +List() \[\]interface{} +ListKeys -----------------------^ Expecting 'STRUCT_STOP', 'MEMBER', got 'OPEN_IN_STRUCT'
2.2 辅助组件类结构
渲染错误: Mermaid 渲染失败: Parse error on line 17: ... +Obj interface{} +Timestam -----------------------^ Expecting 'STRUCT_STOP', 'MEMBER', got 'OPEN_IN_STRUCT'
2.3 源文件索引
| 文件 | 行数 | 核心内容 | 已深度分析 |
|---|---|---|---|
shared_informer.go |
1409 | SharedInformer 主逻辑 | ✅ |
reflector.go |
1333 | Reflector ListWatch 循环 | ✅ |
controller.go |
878 | Controller 双循环模型 | ✅ |
the_real_fifo.go |
859 | RealFIFO 新一代队列 | ❌ |
delta_fifo.go |
800 | DeltaFIFO 经典队列 | ✅ |
thread_safe_store.go |
552 | threadSafeMap + storeIndex | ✅ |
store.go |
439 | cache + Store 构造 | ✅ |
listwatch.go |
312 | ListWatch 实现 | ✅(浅) |
heap.go |
322 | Heap 优先队列 | ❌ |
mutation_cache.go |
264 | MutationCache LRU层 | ❌ |
expiration_cache.go |
224 | ExpirationCache TTL缓存 | ❌ |
identity.go |
217 | InformerName 注册表 | ❌ |
synctrack/synctrack.go |
214 | AsyncTracker/SingleFileTracker | ❌ |
listers.go |
184 | GenericLister 通用查询 | ❌ |
mutation_detector.go |
167 | MutationDetector 变更检测 | ❌ |
fifo.go |
345 | FIFO 基础队列 | ✅ |
undelta_store.go |
89 | UndeltaStore 全量推送 | ❌ |
synctrack/lazy.go |
83 | Lazy 延迟求值 | ❌ |
retry_with_deadline.go |
78 | RetryWithDeadline | ❌ |
object-names.go |
65 | ObjectName 值类型 | ❌ |
event_handler_name.go |
121 | EventHandler 命名 | ❌ |
fifo_metrics.go |
122 | FIFO 指标 | ✅(浅) |
fake_custom_store.go |
102 | FakeCustomStore 测试用 | --- |
index.go |
100 | IndexFunc / Indexers 定义 | ✅ |
reflector_metrics.go |
95 | Reflector 指标 | ✅ |
doc.go |
24 | 包文档 | --- |
expiration_cache_fakes.go |
57 | 测试用假实现 | --- |
reflector_data_consistency_detector.go |
43 | 数据一致性检测 | ✅ |
| 合计 | ~9789 | --- | --- |
2.4 核心方法清单
Store 接口方法
| 方法 | 作用 |
|---|---|
Add(obj) |
添加对象到缓存 |
Update(obj) |
更新缓存中的对象 |
Delete(obj) |
删除缓存中的对象 |
List() |
列出所有对象 |
ListKeys() |
列出所有 key |
Get(obj) |
根据 obj 获取缓存对象 |
GetByKey(key) |
根据 key 获取缓存对象 |
Replace(items, rv) |
替换整个缓存内容 |
Resync() |
重新同步(全量 Resync) |
Queue 接口扩展方法
| 方法 | 作用 |
|---|---|
Pop(process) |
弹出并处理下一个 item |
AddIfNotPresent(obj) |
不存在时才添加 |
HasSynced() |
初始同步是否完成 |
Close() |
关闭队列 |
Indexer 接口扩展方法
| 方法 | 作用 |
|---|---|
Index(indexName, obj) |
按索引名和对象查索引结果 |
IndexKeys(indexName, indexKey) |
按索引名和索引键查 key 列表 |
ListIndexFuncValues(indexName) |
列出某索引的所有索引键 |
ByIndex(indexName, indexKey) |
按索引名和索引键查对象列表 |
GetIndexers() |
获取所有索引器 |
AddIndexers(newIndexers) |
添加新的索引器 |
SharedInformer 方法
| 方法 | 作用 |
|---|---|
AddEventHandler(handler) |
注册事件处理器 |
AddEventHandlerWithResyncPeriod(handler, period) |
注册带自定义 Resync 周期的处理器 |
GetStore() |
获取底层 Store |
GetController() |
获取底层 Controller |
Run(stopCh) |
启动 Informer |
HasSynced() |
是否同步完成 |
LastSyncResourceVersion() |
最后同步的 RV |
SetWatchErrorHandler(handler) |
设置 Watch 错误处理器 |
SetTransformFunc(transformFunc) |
设置转换函数 |
2.5 内部调用关系 --- 完整调用链
#mermaid-svg-Ja1Otr8cR1Gm7N5Y{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .error-icon{fill:#552222;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .marker.cross{stroke:#333333;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y p{margin:0;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .cluster-label text{fill:#333;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .cluster-label span{color:#333;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .cluster-label span p{background-color:transparent;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .label text,#mermaid-svg-Ja1Otr8cR1Gm7N5Y span{fill:#333;color:#333;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .node rect,#mermaid-svg-Ja1Otr8cR1Gm7N5Y .node circle,#mermaid-svg-Ja1Otr8cR1Gm7N5Y .node ellipse,#mermaid-svg-Ja1Otr8cR1Gm7N5Y .node polygon,#mermaid-svg-Ja1Otr8cR1Gm7N5Y .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .rough-node .label text,#mermaid-svg-Ja1Otr8cR1Gm7N5Y .node .label text,#mermaid-svg-Ja1Otr8cR1Gm7N5Y .image-shape .label,#mermaid-svg-Ja1Otr8cR1Gm7N5Y .icon-shape .label{text-anchor:middle;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .rough-node .label,#mermaid-svg-Ja1Otr8cR1Gm7N5Y .node .label,#mermaid-svg-Ja1Otr8cR1Gm7N5Y .image-shape .label,#mermaid-svg-Ja1Otr8cR1Gm7N5Y .icon-shape .label{text-align:center;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .node.clickable{cursor:pointer;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .arrowheadPath{fill:#333333;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .cluster text{fill:#333;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .cluster span{color:#333;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y rect.text{fill:none;stroke-width:0;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .icon-shape,#mermaid-svg-Ja1Otr8cR1Gm7N5Y .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .icon-shape p,#mermaid-svg-Ja1Otr8cR1Gm7N5Y .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .icon-shape .label rect,#mermaid-svg-Ja1Otr8cR1Gm7N5Y .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Ja1Otr8cR1Gm7N5Y :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} User
Processor
Store
Queue
Reflector
Controller
SharedInformer
SharedInformer.Run()
AddEventHandler()
Controller.RunWithContext()
processLoop()
Reflector.Run()
ListAndWatch()
watchHandler()
Add/Update/Delete
Pop(process)
Replace()
Resync()
cache.Add()
cache.Get()
cache.List()
cache.ByIndex()
sharedProcessor.run()
distribute()
listener.add()
listener.run()
listener.pop()
ResourceEventHandler
2.6 依赖注入关系
#mermaid-svg-DdGaLZaNmqxQx7TQ{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-DdGaLZaNmqxQx7TQ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-DdGaLZaNmqxQx7TQ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-DdGaLZaNmqxQx7TQ .error-icon{fill:#552222;}#mermaid-svg-DdGaLZaNmqxQx7TQ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-DdGaLZaNmqxQx7TQ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-DdGaLZaNmqxQx7TQ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-DdGaLZaNmqxQx7TQ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-DdGaLZaNmqxQx7TQ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-DdGaLZaNmqxQx7TQ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-DdGaLZaNmqxQx7TQ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-DdGaLZaNmqxQx7TQ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-DdGaLZaNmqxQx7TQ .marker.cross{stroke:#333333;}#mermaid-svg-DdGaLZaNmqxQx7TQ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-DdGaLZaNmqxQx7TQ p{margin:0;}#mermaid-svg-DdGaLZaNmqxQx7TQ .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-DdGaLZaNmqxQx7TQ .cluster-label text{fill:#333;}#mermaid-svg-DdGaLZaNmqxQx7TQ .cluster-label span{color:#333;}#mermaid-svg-DdGaLZaNmqxQx7TQ .cluster-label span p{background-color:transparent;}#mermaid-svg-DdGaLZaNmqxQx7TQ .label text,#mermaid-svg-DdGaLZaNmqxQx7TQ span{fill:#333;color:#333;}#mermaid-svg-DdGaLZaNmqxQx7TQ .node rect,#mermaid-svg-DdGaLZaNmqxQx7TQ .node circle,#mermaid-svg-DdGaLZaNmqxQx7TQ .node ellipse,#mermaid-svg-DdGaLZaNmqxQx7TQ .node polygon,#mermaid-svg-DdGaLZaNmqxQx7TQ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-DdGaLZaNmqxQx7TQ .rough-node .label text,#mermaid-svg-DdGaLZaNmqxQx7TQ .node .label text,#mermaid-svg-DdGaLZaNmqxQx7TQ .image-shape .label,#mermaid-svg-DdGaLZaNmqxQx7TQ .icon-shape .label{text-anchor:middle;}#mermaid-svg-DdGaLZaNmqxQx7TQ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-DdGaLZaNmqxQx7TQ .rough-node .label,#mermaid-svg-DdGaLZaNmqxQx7TQ .node .label,#mermaid-svg-DdGaLZaNmqxQx7TQ .image-shape .label,#mermaid-svg-DdGaLZaNmqxQx7TQ .icon-shape .label{text-align:center;}#mermaid-svg-DdGaLZaNmqxQx7TQ .node.clickable{cursor:pointer;}#mermaid-svg-DdGaLZaNmqxQx7TQ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-DdGaLZaNmqxQx7TQ .arrowheadPath{fill:#333333;}#mermaid-svg-DdGaLZaNmqxQx7TQ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-DdGaLZaNmqxQx7TQ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-DdGaLZaNmqxQx7TQ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-DdGaLZaNmqxQx7TQ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-DdGaLZaNmqxQx7TQ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-DdGaLZaNmqxQx7TQ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-DdGaLZaNmqxQx7TQ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-DdGaLZaNmqxQx7TQ .cluster text{fill:#333;}#mermaid-svg-DdGaLZaNmqxQx7TQ .cluster span{color:#333;}#mermaid-svg-DdGaLZaNmqxQx7TQ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-DdGaLZaNmqxQx7TQ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-DdGaLZaNmqxQx7TQ rect.text{fill:none;stroke-width:0;}#mermaid-svg-DdGaLZaNmqxQx7TQ .icon-shape,#mermaid-svg-DdGaLZaNmqxQx7TQ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-DdGaLZaNmqxQx7TQ .icon-shape p,#mermaid-svg-DdGaLZaNmqxQx7TQ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-DdGaLZaNmqxQx7TQ .icon-shape .label rect,#mermaid-svg-DdGaLZaNmqxQx7TQ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-DdGaLZaNmqxQx7TQ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-DdGaLZaNmqxQx7TQ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-DdGaLZaNmqxQx7TQ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 被注入的依赖
构造函数注入
NewDeltaFIFOWithOptions
(keyFunc, knownObjects, transformer)
NewRealFIFOWithOptions
(keyFunc, knownObjects, transformer, atomicEvents)
NewStore
(keyFunc)
NewIndexer
(keyFunc, indexers)
NewReflectorWithOptions
(listerWatcher, store, config)
NewController
(config)
NewSharedInformer
(listerWatcher, objType, resyncPeriod)
NewHeap
(keyFunc, lessFunc)
NewTTLStore
(keyFunc, ttl)
NewListWatchFromClient
(client, resource, ns, fieldSelector)
KeyFunc
ListerWatcher
KeyListerGetter (knownObjects)
TransformFunc
LessFunc
ExpirationPolicy
PushFunc
三、核心设计决策与架构特点
3.1 两种 FIFO 队列对比:DeltaFIFO vs RealFIFO
#mermaid-svg-Q4NNMmbrmWekEX1H{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Q4NNMmbrmWekEX1H .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Q4NNMmbrmWekEX1H .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Q4NNMmbrmWekEX1H .error-icon{fill:#552222;}#mermaid-svg-Q4NNMmbrmWekEX1H .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Q4NNMmbrmWekEX1H .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Q4NNMmbrmWekEX1H .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Q4NNMmbrmWekEX1H .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Q4NNMmbrmWekEX1H .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Q4NNMmbrmWekEX1H .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Q4NNMmbrmWekEX1H .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Q4NNMmbrmWekEX1H .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Q4NNMmbrmWekEX1H .marker.cross{stroke:#333333;}#mermaid-svg-Q4NNMmbrmWekEX1H svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Q4NNMmbrmWekEX1H p{margin:0;}#mermaid-svg-Q4NNMmbrmWekEX1H .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Q4NNMmbrmWekEX1H .cluster-label text{fill:#333;}#mermaid-svg-Q4NNMmbrmWekEX1H .cluster-label span{color:#333;}#mermaid-svg-Q4NNMmbrmWekEX1H .cluster-label span p{background-color:transparent;}#mermaid-svg-Q4NNMmbrmWekEX1H .label text,#mermaid-svg-Q4NNMmbrmWekEX1H span{fill:#333;color:#333;}#mermaid-svg-Q4NNMmbrmWekEX1H .node rect,#mermaid-svg-Q4NNMmbrmWekEX1H .node circle,#mermaid-svg-Q4NNMmbrmWekEX1H .node ellipse,#mermaid-svg-Q4NNMmbrmWekEX1H .node polygon,#mermaid-svg-Q4NNMmbrmWekEX1H .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Q4NNMmbrmWekEX1H .rough-node .label text,#mermaid-svg-Q4NNMmbrmWekEX1H .node .label text,#mermaid-svg-Q4NNMmbrmWekEX1H .image-shape .label,#mermaid-svg-Q4NNMmbrmWekEX1H .icon-shape .label{text-anchor:middle;}#mermaid-svg-Q4NNMmbrmWekEX1H .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Q4NNMmbrmWekEX1H .rough-node .label,#mermaid-svg-Q4NNMmbrmWekEX1H .node .label,#mermaid-svg-Q4NNMmbrmWekEX1H .image-shape .label,#mermaid-svg-Q4NNMmbrmWekEX1H .icon-shape .label{text-align:center;}#mermaid-svg-Q4NNMmbrmWekEX1H .node.clickable{cursor:pointer;}#mermaid-svg-Q4NNMmbrmWekEX1H .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Q4NNMmbrmWekEX1H .arrowheadPath{fill:#333333;}#mermaid-svg-Q4NNMmbrmWekEX1H .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Q4NNMmbrmWekEX1H .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Q4NNMmbrmWekEX1H .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Q4NNMmbrmWekEX1H .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Q4NNMmbrmWekEX1H .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Q4NNMmbrmWekEX1H .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Q4NNMmbrmWekEX1H .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Q4NNMmbrmWekEX1H .cluster text{fill:#333;}#mermaid-svg-Q4NNMmbrmWekEX1H .cluster span{color:#333;}#mermaid-svg-Q4NNMmbrmWekEX1H div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Q4NNMmbrmWekEX1H .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Q4NNMmbrmWekEX1H rect.text{fill:none;stroke-width:0;}#mermaid-svg-Q4NNMmbrmWekEX1H .icon-shape,#mermaid-svg-Q4NNMmbrmWekEX1H .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Q4NNMmbrmWekEX1H .icon-shape p,#mermaid-svg-Q4NNMmbrmWekEX1H .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Q4NNMmbrmWekEX1H .icon-shape .label rect,#mermaid-svg-Q4NNMmbrmWekEX1H .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Q4NNMmbrmWekEX1H .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Q4NNMmbrmWekEX1H .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Q4NNMmbrmWekEX1H :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} RealFIFO (新一代)
items: \[\]Delta
(有序 Delta 列表)
Pop: 一次 Pop 一个 Delta
PopBatch: 批量 Pop 多个 Delta
AtomicEvents: Replace 一次 ReplacedAll
UnlockWhileProcessing
(处理时可解锁)
无 items map
(不按 key 聚合)
DeltaFIFO (经典)
items: mapstringDeltas
(按 key 聚合)
Pop: 一次 Pop 一个 key
返回该 key 的所有 Deltas
queue: \[\]string
(去重 key 列表)
去重: 同 key 的 Delta 合并
Replace: 逐个 Added/Replaced
| 维度 | DeltaFIFO | RealFIFO |
|---|---|---|
| 内部结构 | map[string]Deltas + []string |
[]Delta (纯列表) |
| 去重 | ✅ 同 key 合并 Delta | ❌ 不去重,每个 Delta 独立 |
| Pop 粒度 | 一个 key 的所有 Delta | 单个 Delta |
| 批量处理 | ❌ | ✅ PopBatch (最多 batchSize) |
| 原子事件 | ❌ Replace 逐个发出 | ✅ ReplacedAll/SyncAll |
| 处理时解锁 | ❌ | ✅ unlockWhileProcessing |
| Bookmark Delta | ❌ | ✅ emitDeltaTypeBookmark |
| KnownObjects | 必须 | AtomicEvents=true 时不需要 |
| 适用场景 | 传统 Informer | 高性能 Informer (KCM) |
3.2 Delta 类型体系
#mermaid-svg-zpv9GBVfrsV90snM{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-zpv9GBVfrsV90snM .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-zpv9GBVfrsV90snM .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-zpv9GBVfrsV90snM .error-icon{fill:#552222;}#mermaid-svg-zpv9GBVfrsV90snM .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-zpv9GBVfrsV90snM .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-zpv9GBVfrsV90snM .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-zpv9GBVfrsV90snM .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-zpv9GBVfrsV90snM .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-zpv9GBVfrsV90snM .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-zpv9GBVfrsV90snM .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-zpv9GBVfrsV90snM .marker{fill:#333333;stroke:#333333;}#mermaid-svg-zpv9GBVfrsV90snM .marker.cross{stroke:#333333;}#mermaid-svg-zpv9GBVfrsV90snM svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-zpv9GBVfrsV90snM p{margin:0;}#mermaid-svg-zpv9GBVfrsV90snM .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-zpv9GBVfrsV90snM .cluster-label text{fill:#333;}#mermaid-svg-zpv9GBVfrsV90snM .cluster-label span{color:#333;}#mermaid-svg-zpv9GBVfrsV90snM .cluster-label span p{background-color:transparent;}#mermaid-svg-zpv9GBVfrsV90snM .label text,#mermaid-svg-zpv9GBVfrsV90snM span{fill:#333;color:#333;}#mermaid-svg-zpv9GBVfrsV90snM .node rect,#mermaid-svg-zpv9GBVfrsV90snM .node circle,#mermaid-svg-zpv9GBVfrsV90snM .node ellipse,#mermaid-svg-zpv9GBVfrsV90snM .node polygon,#mermaid-svg-zpv9GBVfrsV90snM .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-zpv9GBVfrsV90snM .rough-node .label text,#mermaid-svg-zpv9GBVfrsV90snM .node .label text,#mermaid-svg-zpv9GBVfrsV90snM .image-shape .label,#mermaid-svg-zpv9GBVfrsV90snM .icon-shape .label{text-anchor:middle;}#mermaid-svg-zpv9GBVfrsV90snM .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-zpv9GBVfrsV90snM .rough-node .label,#mermaid-svg-zpv9GBVfrsV90snM .node .label,#mermaid-svg-zpv9GBVfrsV90snM .image-shape .label,#mermaid-svg-zpv9GBVfrsV90snM .icon-shape .label{text-align:center;}#mermaid-svg-zpv9GBVfrsV90snM .node.clickable{cursor:pointer;}#mermaid-svg-zpv9GBVfrsV90snM .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-zpv9GBVfrsV90snM .arrowheadPath{fill:#333333;}#mermaid-svg-zpv9GBVfrsV90snM .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-zpv9GBVfrsV90snM .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-zpv9GBVfrsV90snM .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-zpv9GBVfrsV90snM .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-zpv9GBVfrsV90snM .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-zpv9GBVfrsV90snM .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-zpv9GBVfrsV90snM .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-zpv9GBVfrsV90snM .cluster text{fill:#333;}#mermaid-svg-zpv9GBVfrsV90snM .cluster span{color:#333;}#mermaid-svg-zpv9GBVfrsV90snM div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-zpv9GBVfrsV90snM .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-zpv9GBVfrsV90snM rect.text{fill:none;stroke-width:0;}#mermaid-svg-zpv9GBVfrsV90snM .icon-shape,#mermaid-svg-zpv9GBVfrsV90snM .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-zpv9GBVfrsV90snM .icon-shape p,#mermaid-svg-zpv9GBVfrsV90snM .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-zpv9GBVfrsV90snM .icon-shape .label rect,#mermaid-svg-zpv9GBVfrsV90snM .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-zpv9GBVfrsV90snM .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-zpv9GBVfrsV90snM .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-zpv9GBVfrsV90snM :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} DeltaType (string)
Sync
(Resync 产生的全量同步)
Added
(新资源创建)
Updated
(资源更新)
Deleted
(资源删除)
Replaced
(Replace 中的单个替换)
ReplacedAll
(原子 Replace)
SyncAll
(原子 Resync)
Bookmark
(RV 进度标记)
DeltaFIFO 使用的 DeltaType :Sync, Added, Updated, Deleted, Replaced
RealFIFO 额外的 DeltaType:ReplacedAll, SyncAll, Bookmark
3.3 Informer 生命周期状态机
#mermaid-svg-IJ3AtidLSPC9xWeR{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-IJ3AtidLSPC9xWeR .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-IJ3AtidLSPC9xWeR .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-IJ3AtidLSPC9xWeR .error-icon{fill:#552222;}#mermaid-svg-IJ3AtidLSPC9xWeR .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-IJ3AtidLSPC9xWeR .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-IJ3AtidLSPC9xWeR .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-IJ3AtidLSPC9xWeR .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-IJ3AtidLSPC9xWeR .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-IJ3AtidLSPC9xWeR .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-IJ3AtidLSPC9xWeR .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-IJ3AtidLSPC9xWeR .marker{fill:#333333;stroke:#333333;}#mermaid-svg-IJ3AtidLSPC9xWeR .marker.cross{stroke:#333333;}#mermaid-svg-IJ3AtidLSPC9xWeR svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-IJ3AtidLSPC9xWeR p{margin:0;}#mermaid-svg-IJ3AtidLSPC9xWeR defs #statediagram-barbEnd{fill:#333333;stroke:#333333;}#mermaid-svg-IJ3AtidLSPC9xWeR g.stateGroup text{fill:#9370DB;stroke:none;font-size:10px;}#mermaid-svg-IJ3AtidLSPC9xWeR g.stateGroup text{fill:#333;stroke:none;font-size:10px;}#mermaid-svg-IJ3AtidLSPC9xWeR g.stateGroup .state-title{font-weight:bolder;fill:#131300;}#mermaid-svg-IJ3AtidLSPC9xWeR g.stateGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-IJ3AtidLSPC9xWeR g.stateGroup line{stroke:#333333;stroke-width:1;}#mermaid-svg-IJ3AtidLSPC9xWeR .transition{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-IJ3AtidLSPC9xWeR .stateGroup .composit{fill:white;border-bottom:1px;}#mermaid-svg-IJ3AtidLSPC9xWeR .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px;}#mermaid-svg-IJ3AtidLSPC9xWeR .state-note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-IJ3AtidLSPC9xWeR .state-note text{fill:black;stroke:none;font-size:10px;}#mermaid-svg-IJ3AtidLSPC9xWeR .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-IJ3AtidLSPC9xWeR .edgeLabel .label rect{fill:#ECECFF;opacity:0.5;}#mermaid-svg-IJ3AtidLSPC9xWeR .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-IJ3AtidLSPC9xWeR .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-IJ3AtidLSPC9xWeR .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-IJ3AtidLSPC9xWeR .edgeLabel .label text{fill:#333;}#mermaid-svg-IJ3AtidLSPC9xWeR .label div .edgeLabel{color:#333;}#mermaid-svg-IJ3AtidLSPC9xWeR .stateLabel text{fill:#131300;font-size:10px;font-weight:bold;}#mermaid-svg-IJ3AtidLSPC9xWeR .node circle.state-start{fill:#333333;stroke:#333333;}#mermaid-svg-IJ3AtidLSPC9xWeR .node .fork-join{fill:#333333;stroke:#333333;}#mermaid-svg-IJ3AtidLSPC9xWeR .node circle.state-end{fill:#9370DB;stroke:white;stroke-width:1.5;}#mermaid-svg-IJ3AtidLSPC9xWeR .end-state-inner{fill:white;stroke-width:1.5;}#mermaid-svg-IJ3AtidLSPC9xWeR .node rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-IJ3AtidLSPC9xWeR .node polygon{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-IJ3AtidLSPC9xWeR #statediagram-barbEnd{fill:#333333;}#mermaid-svg-IJ3AtidLSPC9xWeR .statediagram-cluster rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-IJ3AtidLSPC9xWeR .cluster-label,#mermaid-svg-IJ3AtidLSPC9xWeR .nodeLabel{color:#131300;}#mermaid-svg-IJ3AtidLSPC9xWeR .statediagram-cluster rect.outer{rx:5px;ry:5px;}#mermaid-svg-IJ3AtidLSPC9xWeR .statediagram-state .divider{stroke:#9370DB;}#mermaid-svg-IJ3AtidLSPC9xWeR .statediagram-state .title-state{rx:5px;ry:5px;}#mermaid-svg-IJ3AtidLSPC9xWeR .statediagram-cluster.statediagram-cluster .inner{fill:white;}#mermaid-svg-IJ3AtidLSPC9xWeR .statediagram-cluster.statediagram-cluster-alt .inner{fill:#f0f0f0;}#mermaid-svg-IJ3AtidLSPC9xWeR .statediagram-cluster .inner{rx:0;ry:0;}#mermaid-svg-IJ3AtidLSPC9xWeR .statediagram-state rect.basic{rx:5px;ry:5px;}#mermaid-svg-IJ3AtidLSPC9xWeR .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#f0f0f0;}#mermaid-svg-IJ3AtidLSPC9xWeR .note-edge{stroke-dasharray:5;}#mermaid-svg-IJ3AtidLSPC9xWeR .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-IJ3AtidLSPC9xWeR .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-IJ3AtidLSPC9xWeR .statediagram-note text{fill:black;}#mermaid-svg-IJ3AtidLSPC9xWeR .statediagram-note .nodeLabel{color:black;}#mermaid-svg-IJ3AtidLSPC9xWeR .statediagram .edgeLabel{color:red;}#mermaid-svg-IJ3AtidLSPC9xWeR #dependencyStart,#mermaid-svg-IJ3AtidLSPC9xWeR #dependencyEnd{fill:#333333;stroke:#333333;stroke-width:1;}#mermaid-svg-IJ3AtidLSPC9xWeR .statediagramTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-IJ3AtidLSPC9xWeR :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} NewSharedInformer()
AddEventHandler()
Run(stopCh)
stopCh closed
cleanup
Controller.Run()
processor.run()
Created
NotStarted
Running
ReflectorRunning
ListAndWatch
Watch starts
Watch error / Resync
Listing
Watching
Relisting
ProcessorRunning
handleDeltas
listener.add()
listener.pop()
Distributing
Notifying
Processing
Stopping
3.4 数据流 --- 从 API Server 到 EventHandler
EventHandler processorListener sharedProcessor cache (Indexer) Controller DeltaFIFO/RealFIFO Reflector API Server EventHandler processorListener sharedProcessor cache (Indexer) Controller DeltaFIFO/RealFIFO Reflector API Server #mermaid-svg-Hn5T5HKIM1VGma3L{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Hn5T5HKIM1VGma3L .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Hn5T5HKIM1VGma3L .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Hn5T5HKIM1VGma3L .error-icon{fill:#552222;}#mermaid-svg-Hn5T5HKIM1VGma3L .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Hn5T5HKIM1VGma3L .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Hn5T5HKIM1VGma3L .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Hn5T5HKIM1VGma3L .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Hn5T5HKIM1VGma3L .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Hn5T5HKIM1VGma3L .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Hn5T5HKIM1VGma3L .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Hn5T5HKIM1VGma3L .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Hn5T5HKIM1VGma3L .marker.cross{stroke:#333333;}#mermaid-svg-Hn5T5HKIM1VGma3L svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Hn5T5HKIM1VGma3L p{margin:0;}#mermaid-svg-Hn5T5HKIM1VGma3L .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-Hn5T5HKIM1VGma3L text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-Hn5T5HKIM1VGma3L .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-Hn5T5HKIM1VGma3L .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-Hn5T5HKIM1VGma3L .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-Hn5T5HKIM1VGma3L .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-Hn5T5HKIM1VGma3L #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-Hn5T5HKIM1VGma3L .sequenceNumber{fill:white;}#mermaid-svg-Hn5T5HKIM1VGma3L #sequencenumber{fill:#333;}#mermaid-svg-Hn5T5HKIM1VGma3L #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-Hn5T5HKIM1VGma3L .messageText{fill:#333;stroke:none;}#mermaid-svg-Hn5T5HKIM1VGma3L .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-Hn5T5HKIM1VGma3L .labelText,#mermaid-svg-Hn5T5HKIM1VGma3L .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-Hn5T5HKIM1VGma3L .loopText,#mermaid-svg-Hn5T5HKIM1VGma3L .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-Hn5T5HKIM1VGma3L .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-Hn5T5HKIM1VGma3L .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-Hn5T5HKIM1VGma3L .noteText,#mermaid-svg-Hn5T5HKIM1VGma3L .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-Hn5T5HKIM1VGma3L .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-Hn5T5HKIM1VGma3L .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-Hn5T5HKIM1VGma3L .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-Hn5T5HKIM1VGma3L .actorPopupMenu{position:absolute;}#mermaid-svg-Hn5T5HKIM1VGma3L .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-Hn5T5HKIM1VGma3L .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-Hn5T5HKIM1VGma3L .actor-man circle,#mermaid-svg-Hn5T5HKIM1VGma3L line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-Hn5T5HKIM1VGma3L :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Controller processLoop 消费 EventHandler 将 key 入 WorkQueue List (初始数据)Replace(items, rv)Watch event (Added)Add(obj)Watch event (Updated)Update(obj)Watch event (Deleted)Delete(obj)Pop → DeltasStore.Add/Update/Deletedistribute(obj, isInitialList)listener.add(notification)OnAdd/OnUpdate/OnDelete
3.5 关键设计模式
| 模式 | 体现 |
|---|---|
| 观察者模式 | sharedProcessor 扇出事件给多个 Listener |
| 生产者-消费者 | Reflector 生产 → FIFO → Controller 消费 |
| 装饰器模式 | UndeltaStore 包装 Store 增加全量推送 |
| 策略模式 | KeyFunc/LessFunc/ExpirationPolicy 可注入 |
| 工厂模式 | NewStore/NewIndexer/NewHeap/NewTTLStore |
| 单例注册 | InformerName 全局注册表防重复 |
| 延迟求值 | synctrack.Lazy 延迟计算缓存 |
| 原子计数 | SingleFileTracker 用 atomic 追踪同步状态 |
| TTL 自动过期 | ExpirationCache + TTLPolicy 惰性删除 |
| LRU 叠层 | MutationCache 在 Store 之上叠加 LRU |
| 变更检测 | MutationDetector 对象深拷贝对比 |
| 双路径处理 | RealFIFO 的 Pop(单条) vs PopBatch(批量) |
附录A:tools/cache 包完整导出符号清单
接口
| 接口 | 文件 | 用途 |
|---|---|---|
| Store | store.go | 基础 CRUD 缓存 |
| Indexer | store.go | 带索引的 Store |
| Queue | fifo.go | 可 Pop 的 Store |
| QueueWithBatch | fifo.go | 可批量 Pop 的 Queue |
| ThreadSafeStore | thread_safe_store.go | 线程安全内部存储 |
| ResourceEventHandler | controller.go | 事件处理回调 |
| ListerWatcher | listwatch.go | List + Watch |
| MutationDetector | mutation_detector.go | 对象变更检测 |
| MutationCache | mutation_cache.go | 变更叠加 LRU 缓存 |
| ExpirationPolicy | expiration_cache.go | 过期策略 |
| GenericLister | listers.go | 通用 Lister |
| GenericNamespaceLister | listers.go | 命名空间 Lister |
| RetryWithDeadline | retry_with_deadline.go | 带截止期限重试 |
| TransformingStore | fifo.go | 支持 TransformFunc 的 Store |
| DoneChecker | fifo.go | 异步完成检查 |
核心类型
| 类型 | 文件 | 用途 |
|---|---|---|
| cache | store.go | Store + Indexer 实现 |
| DeltaFIFO | delta_fifo.go | 经典去重 FIFO |
| RealFIFO | the_real_fifo.go | 新一代 FIFO |
| Reflector | reflector.go | ListWatch 循环 |
| Controller | controller.go | 双循环模型 |
| SharedInformer | shared_informer.go | 共享 Informer |
| Heap | heap.go | 线程安全优先队列 |
| ExpirationCache | expiration_cache.go | TTL 过期缓存 |
| UndeltaStore | undelta_store.go | 增量转全量 Store |
| ListWatch | listwatch.go | List + Watch 实现 |
| InformerName | identity.go | 全局唯一 Informer 标识 |
| ObjectName | object-names.go | 对象名值类型 |
| Delta | delta_fifo.go | 变更事件 (Type + Object) |
| Deltas | delta_fifo.go | 同 key 的 Delta 列表 |
| DeletedFinalStateUnknown | delta_fifo.go | 删除墓碑对象 |
工厂函数
| 函数 | 返回类型 |
|---|---|
| NewStore | Store |
| NewIndexer | Indexer |
| NewDeltaFIFO | *DeltaFIFO |
| NewRealFIFO | *RealFIFO |
| NewHeap | *Heap |
| NewTTLStore | Store |
| NewUndeltaStore | *UndeltaStore |
| NewListWatchFromClient | *ListWatch |
| NewGenericLister | GenericLister |
| NewInformerName | *InformerName, error |
| NewSharedInformer | SharedInformer |
附录B:DeltaType 枚举值
| DeltaType | 使用者 | 语义 |
|---|---|---|
| Added | DeltaFIFO + RealFIFO | 新资源创建 |
| Updated | DeltaFIFO + RealFIFO | 资源更新 |
| Deleted | DeltaFIFO + RealFIFO | 资源删除 |
| Sync | DeltaFIFO + RealFIFO | Resync 全量同步 |
| Replaced | DeltaFIFO + RealFIFO | Replace 中的单条替换 |
| ReplacedAll | RealFIFO only | 原子 Replace |
| SyncAll | RealFIFO only | 原子 Resync |
| Bookmark | RealFIFO only | RV 进度标记 |