Kubernetes client-go Indexer / ThreadSafeStore 源码分析
Contents
概述
源码版本信息
- Project: kubernetes
- Branch: master
- Last commit id: d25d741c
- Date: 2021-09-26
Indexer 主要依赖于 ThreadSafeStore 实现,是 client-go 提供的一种缓存机制,通过检索本地缓存可以有效降低 apiserver 的压力,我们在自定义控制器里调用一个 List() 方法带一个 ListOption 本质就是加上条件检索了 Indexer,掌握 Indexer 的实现可以在 Operator 编码时更加心里有底。
Indexer 接口
Indexer 接口主要是在 Store 接口的基础上拓展了对象的检索功能
- client-go/tools/cache/index.go:35
|
|
Indexer 的默认实现是 cache
|
|
cache 对应两个方法体实现完全一样的 New 函数:
|
|
这里涉及到两个类型:
- KeyFunc
- ThreadSafeStore
我们先看一下 Indexer 的 Add()、Update() 等方法是怎么实现的:
|
|
可以看到这里的逻辑就是调用 keyFunc() 方法获取 key,然后调用 cacheStorage.Xxx() 方法完成对应增删改查过程。KeyFunc 类型时这样定义的:
|
|
也就是给一个对象,返回一个字符串类型的 key。KeyFunc 的一个默认实现如下:
|
|
可以看到一般情况下返回值是 <namespace><name>
,如果 namespace 为空则直接返回 name。类似的还有一个叫做 IndexFunc 的类型,定义如下:
|
|
这是给一个对象生成 Index 用的,一个通用实现如下,直接返回对象的 namespace 字段作为 Index
|
|
下面我们直接来看 cacheStorage 是如果实现增删改查的。
ThreadSafeStore
ThreadSafeStore 是 Indexer 的核心逻辑所在,Indexer 的多数方法是直接调用内部 cacheStorage 属性的方法实现的,同样先看接口定义:
- client-go/tools/cache/thread_safe_store.go:41
|
|
对应实现:
|
|
这里的 Indexers 和 Indices 是:
|
|
对照图片理解一下这几个字段的关系:Indexers 里存的是 Index 函数 map,一个典型的实现是字符串 namespace 作为 key,IndexFunc 类型的实现 MetaNamespaceIndexFunc
函数作为 value,也就是我们希望通过 namespace 来检索时,通过 Indexers 可以拿到对应的计算 Index 的函数,接着拿着这个函数,把对象穿进去,就可以计算出这个对象对应的 key,在这里也就是具体的 namespace 值,比如 default、kube-system 这种。然后在 Indices 里存的也是一个 map,key 是上面计算出来的 default 这种 namespace 值,value 是一个 set,而 set 表示的是这个 default namespace 下的一些具体 pod 的 <namespace>/<name>
这类字符串。最后拿着这种 key,就可以在 items 里检索到对应的对象了。
threadSafeMap.Xxx()
比如 Add() 方法代码如下:
|
|
可以看到更复杂的逻辑在 updateIndices 方法里,我们继续来看:
- client-go/tools/cache/thread_safe_store.go:256
|
|
上面还提到了一个 deleteFromIndices 方法,前半段和上面逻辑上类似的,最后拿到 set 后不同于上面的 Insert 过程,这里调用了一个 Delete。
|
|
Index() 等实现
最后看几个具体方法等实现
Index() 方法
来看一下 Index() 方法的实现,Index() 方法的作用是给定一个 obj 和 indexName,比如 pod1和 “namespace”,然后返回 pod1 所在 namespace 下的所有 pod。
- client-go/tools/cache/thread_safe_store.go:141
|
|
ByIndex() 方法
相比 Index(),这个函数要简单的多,直接传递 indexedValue,也就不需要通过 obj 去计算 key 了,例如 indexName == namespace & indexValue == default 就是直接检索 default 下的资源对象。
|
|
IndexKeys() 方法
和上面返回 obj 列表不同,这里只返回 key 列表,就是 []string{“default/pod_1”} 这种数据
|
|
Replace() 方法
Replace() 的实现简单粗暴,给一个新 items map,直接替换到 threadSafeMap.items 中,然后重建索引。
|
|
(转载请保留本文原始链接)
https://www.danielhu.cn/post/k8s/client-go-indexer/
Kubernetes client-go Indexer / ThreadSafeStore 源码分析的更多相关文章
- kubernetes垃圾回收器GarbageCollector Controller源码分析(二)
kubernetes版本:1.13.2 接上一节:kubernetes垃圾回收器GarbageCollector Controller源码分析(一) 主要步骤 GarbageCollector Con ...
- eureka client服务续约源码分析
必备知识: 1.定时任务 ScheduledExecutorService public class demo { public static void main(String[] args){ Sc ...
- Kubernetes client-go DeltaFIFO 源码分析
概述Queue 接口DeltaFIFO元素增删改 - queueActionLocked()Pop()Replace() 概述 源码版本信息 Project: kubernetes Branch: m ...
- Kubernetes client-go Informer 源码分析
概述ControllerController 的初始化Controller 的启动processLoopHandleDeltas()SharedIndexInformersharedIndexerIn ...
- Kubernetes Deployment 源码分析(二)
概述startDeploymentController 入口逻辑DeploymentController 对象DeploymentController 类型定义DeploymentController ...
- client-go客户端自定义开发Kubernetes及源码分析
介绍 client-go 是一种能够与 Kubernetes 集群通信的客户端,通过它可以对 Kubernetes 集群中各资源类型进行 CRUD 操作,它有三大 client 类,分别为:Clien ...
- k8s client-go源码分析 informer源码分析(6)-Indexer源码分析
client-go之Indexer源码分析 1.Indexer概述 Indexer中有informer维护的指定资源对象的相对于etcd数据的一份本地内存缓存,可通过该缓存获取资源对象,以减少对api ...
- 【原】Spark中Client源码分析(二)
继续前一篇的内容.前一篇内容为: Spark中Client源码分析(一)http://www.cnblogs.com/yourarebest/p/5313006.html DriverClient中的 ...
- Docker源码分析(二):Docker Client创建与命令执行
1. 前言 如今,Docker作为业界领先的轻量级虚拟化容器管理引擎,给全球开发者提供了一种新颖.便捷的软件集成测试与部署之道.在团队开发软件时,Docker可以提供可复用的运行环境.灵活的资源配置. ...
随机推荐
- WPF 中的形状和基本绘图概述
本主题概述如何使用 Shape 对象绘图. Shape 是一种允许您在屏幕中绘制形状的 UIElement 类型. 由于它们是 UI 元素,因此 Shape 对象可以在 Panel 元素和大多数控件中 ...
- 【权限管理】springboot集成security
摘自: https://www.cnblogs.com/hhhshct/p/9726378.html https://blog.csdn.net/weixin_42849689/article/det ...
- 【nodejs】express框架+mysql后台数据查询
一 环境部署 1,首先安装nodejs,并配置好环境变量(看自己习惯), 2,安装Express npm install express -g //全局安装 npm install express-g ...
- python进阶(20) 正则表达式的超详细使用
正则表达式 正则表达式(Regular Expression,在代码中常简写为regex. regexp.RE 或re)是预先定义好的一个"规则字符率",通过这个"规 ...
- Matlab实现BP神经网络预测(附实例数据及代码)
BP神经网络介绍 神经网络是机器学习中一种常见的数学模型,通过构建类似于大脑神经突触联接的结构,来进行信息处理.在应用神经网络的过程中,处理信息的单元一般分为三类:输入单元.输出单元和隐含单元. 顾名 ...
- 浅谈Java和Go的程序退出
前言 今天在开发中对Java程序的退出产生了困惑,因为题主之前写过一段时间Go,这两者的程序退出逻辑是不同的,下面首先给出结论,再通过简单的例子来介绍. 对于Java程序,Main线程退出,如果当前存 ...
- MySQL中的seconds_behind_master的理解
通过show slave status查看到的Seconds_Behind_Master,从字面上来看,他是slave落后master的秒数,一般情况下,也确实这样,我们可以通过Seconds_Beh ...
- sizeof关键字
sizeof关键字 sizeof不是函数,所以不需要包含任何头文件,它的功能是计算一个数据类型的大小,单位为字节 sizeof的返回值为size_t size_t类型在32位操作系统下是unsigne ...
- 从kratos分析breaker熔断器源码实现
为什么要用熔断 前面我们讲过限流保证服务的可用性,不被突如其来的流量打爆.但是两种情况是限流解决不了的. 如果我们服务只能处理1000QPS,但是有10wQPS打过来,服务还是会炸.因为拒绝请求也需要 ...
- NOIP模拟50
过分的神圣,往往比恶魔更加恶质. 前言 最大的一个收获就是不要动不动就码线段树,一定要审清楚题目之后再码!! T1 一开始理解错题了,以为答案是就是 \(\dfrac{\operatorname{le ...