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可以提供可复用的运行环境.灵活的资源配置. ...
随机推荐
- C++11 shared_ptr智能指针(超级详细)
在实际的 C++ 开发中,我们经常会遇到诸如程序运行中突然崩溃.程序运行所用内存越来越多最终不得不重启等问题,这些问题往往都是内存资源管理不当造成的.比如: 有些内存资源已经被释放,但指向它的指针并没 ...
- Fancytree实例
一.实例 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> ...
- 【多线程】不懂什么是 Java 中的锁?看看这篇你就明白了!
本文来源:Java建设者 原文地址:https://mp.weixin.qq.com/s/GU42BjM5jY2CEMVD_PAZBQ Java 锁分类 Java 中的锁有很多,可以按照不同的功能.种 ...
- 在ubuntu18.04上部署项目时遇到的问题总结
因为在实验室中,有几台空闲的机子,我便选了一台准备做一个本地的服务器,因为买的阿里云学生机和之前用于FQ的机子感觉都不太顺手,阿里的学生机配置稍低,FQ用的服务器延迟太高.开始在centos和ubun ...
- Visual Studio 2022 预览版3 最新功能解说
我们很高兴地宣布Visual Studio 2022 的第三个预览版问世啦!预览版3 提供了更多关于个人和团队生产力.现代开发和持续创新等主题的新功能.在本文中,我们将重点介绍Visual Studi ...
- Ubuntu 16.04LTS下eclipse连接mysql
第一部分:打开eclipse,新建一个web工程,新建一个类db_test.java(jdbc连接mysql的原理自行百度) import java.sql.*; public class db_te ...
- 移动端动画——requestAnimationFrame
window.requestAnimationFrame() 告诉浏览器--你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画.该方法需要传入一个回调函数作为参数,该回调函数会 ...
- netty系列之:搭建自己的下载文件服务器
目录 简介 文件的content-type 客户端缓存文件 其他HTTP中常用的处理 文件内容展示处理 文件传输进度 总结 简介 上一篇文章我们学习了如何在netty中搭建一个HTTP服务器,讨论了如 ...
- Python中管理数据库
前言:Python中是利用MySQL模块和数据库之间建立联系. MySQLdb 是用于Python链接Mysql数据库的接口,它实现了 Python 数据库 API 规范 V2.0,基于 MySQL ...
- 使用 IDEA 配合 Dockerfile 部署 SpringBoot 工程
准备 SpringBoot 工程 新建 SpringBoot 项目,默认的端口是 8080 ,新建 Controller 和 Mapping @RestController public class ...