深入源码分析kubernetes informer机制(三)Resync


[阅读指南]
这是该系列第三篇
基于kubernetes 1.27 stage版本
为了方便阅读,后续所有代码均省略了错误处理及与关注逻辑无关的部分。


文章目录

  • 为什么需要resync
  • resync做了什么

为什么需要resync

如果看过上一篇,大概能了解,client数据主要通过reflector 的list/watch进行同步。

回顾一下informer整体的数据同步逻辑。

  1. informer初始化时,调用list接口获取制定类型的全量资源数据,此时的resource version默认为0。假如指定资源类型为pod,那么就是获取所有pod数据
  2. list 获取到数据后,将全量数据同步到本地缓存。首次list完成后,informer后续都将通过watch来同步资源更新
  3. watcher监控到资源更新事件,将接收到的事件放入存储队列中(delta FIFO)
  4. informer 的另一个process会不断取出存储队列中的delta事件进行数据更新
  5. 缓存数据更新成功后,将数据变化通过回调函数同步至custom controller workqueue中
  6. custom controller顺序处理workqueue中的数据变更事件
    在这里插入图片描述

流程包括了三端的数据同步。

  • 首先api-server与informer中间通过sourceVersion可以保证数据的一致性
    client携带本地的sourceVersion请求api-server,api-server会将最新版本的增量变化通过事件返回给client。
    如图所示,在此期间,如果数据连接发生任何异常,informer会在重新建立watcher连接时,携带上个版本的sourceVersion,并再次更新所有的增量变化。
    在这里插入图片描述

  • 然后是本地informer与custom之间,通过workqueue来进行事件通知。
    informer的协程将FIFO队列中的事件取出更新至本地后,还会将事件同步回调至custom controller,加入到workqueue队列中。
    但是回看informer的代码,informer在处理回调事件时,并不会关注回调的结果。
    在这里插入图片描述

也就是说,如果custom controller侧的消费出现异常导致数据同步失败,informer是不知情的。

所以还需要引入别的机制来保障custom数据与本地缓存的一致性,以维持体的可靠性,也就是resync。
(当然如果controller本身也存在对比sourceVersion的逻辑,其实不需要这一机制也是可以确保数据一致的,resync相当于从框架层增加了一层保护,这篇博客有对相关的问题进行探讨)

resync做了什么

resync的逻辑非常简单,就是定时将本地缓存中所有的资源对象生成事件重新推送到FIFO中,重新触发controller的回调。
参考《Programming Kubernetes》一书中的概念,其实就是在边缘触发,水平驱动的基础上,附加了定时同步的能力。
在这里插入图片描述

具体来看下resync的代码实现。

informer在初始化时指定了resync执行间隔。

// informer创建方法
func NewIndexerInformer(
	lw ListerWatcher,
	objType runtime.Object,
	resyncPeriod time.Duration, // Resync执行周期
	h ResourceEventHandler,
	indexers Indexers,
) (Indexer, Controller) {}

// workqueue调用示例
// 0 代表不重复执行
indexer, informer := cache.NewIndexerInformer(podListWatcher, &v1.Pod{}, 0, cache.ResourceEventHandlerFuncs{...})

在informer初始化完成后,拉起一个协程进行定时resync

func (r *Reflector) ListAndWatch(stopCh <-chan struct{}) error {
	...
    
	go r.startResync(stopCh, cancelCh, resyncerrc)
	return r.watch(w, stopCh, resyncerrc)
}

该协程会按照informer配置的时间间隔定时调用存储对象的resync方法。
比较特殊的是,sharedIndexInformer类型的informer会另外有ShouldResync方法来轮询每个监听了当前资源对象的listener的是否需要进行resync操作。

func (r *Reflector) startResync(stopCh <-chan struct{}, cancelCh <-chan struct{}, resyncerrc chan error) {
	resyncCh, cleanup := r.resyncChan() // 返回一个触发resync的信号,内部实现就是一个timer
	defer func() {
		cleanup() // Call the last one written into cleanup
	}()
	for {
		select {
		case <-resyncCh:
		case <-stopCh:
			return
		case <-cancelCh:
			return
		}

        // sharedIndexInformer 中用ShouldResync()来管理各个listener的resync
		if r.ShouldResync == nil || r.ShouldResync() {
			if err := r.store.Resync(); err != nil { 
				resyncerrc <- err 
				return
			}
		}
		cleanup()
		resyncCh, cleanup = r.resyncChan()
	}
}

resync只做一件事,将本地缓存里的资源对象全部重新添加到FIFO队列中,再触发contronller处理一次。
不过,为了避免与最新的变更发生冲突,FIFO队列中已有delta且还没有处理的资源对象,不会被重新添加。

func (f *DeltaFIFO) Resync() error {
	f.lock.Lock()
	defer f.lock.Unlock()

	if f.knownObjects == nil {
		return nil
	}

    // f.knownObjects 可以获取到本地缓存中所有资源对象的列表
	keys := f.knownObjects.ListKeys()
	for _, k := range keys {
        // 过滤掉已经有新的事件在队列中等待处理的资源对象
        // 把所有资源对象以resync类型添加到队列中
		if err := f.syncKeyLocked(k); err != nil {
			return err
		}
	}
	return nil
}

参考:
https://www.kubernetes.org.cn/2693.html
https://github.com/cloudnativeto/sig-kubernetes/issues/11
https://www.cnblogs.com/WisWang/p/13897782.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/76601.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

B树和B+树区别

B树和B树的区别 B树 B树被称为平衡树&#xff0c;在B树中&#xff0c;一个节点可以有两个以上的子节点。B树的高度为log M N。在B树中&#xff0c;数据按照特定的顺序排序&#xff0c;最小值在左侧&#xff0c;最大值在右侧。 B树是一种平衡的多分树&#xff0c;通常我们说m阶…

Unity-Linux部署WebGL项目MIME类型添加

在以往的文章中有提到过使用IIS部署WebGL添加MIME类型使WebGL项目在浏览器中能够正常加载&#xff0c;那么如果咱们做的是商业项目&#xff0c;往往是需要部署在学校或者云服务器上面的&#xff0c;大部分情况下如果项目有接口或者后台管理系统&#xff0c;后台基本都会使用Lin…

arcgis pro 3.0.2 安装及 geemap

arcgis pro 3.0.2 安装及 geemap arcgis pro 3.0.2 安装 arcgis pro 3 版本已经很多了&#xff0c;在网上找到资源就可以进行安装 需要注意的是&#xff1a;有的文件破解文件缺少&#xff0c;导致破解不成功。 能够新建地图就是成功了&#xff01; geemap安装 1.需要进行环…

FL Studio 21最新for Windows-21.1.0.3267中文解锁版安装激活教程及更新日志

FL Studio 21最新版本for Windows 21.1.0.3267中文解锁版是最新强大的音乐制作工具。它可以与所有类型的音乐一起创作出令人惊叹的音乐。它提供了一个非常简单且用户友好的集成开发环境&#xff08;IDE&#xff09;来工作。这个完整的音乐工作站是由比利时公司 Image-Line 开发…

Flutter源码分析笔记:Widget类源码分析

Flutter源码分析笔记 Widget类源码分析 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at: https://jclee95.blog.csdn.netEmail: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.csdn.net/qq_28550263/article/details/132259681 【介绍】&#x…

Spring源码深度解析一(IOCDI)

1. Spring架构设计 Spring框架是一个分层架构&#xff0c;他包含一系列的功能要素&#xff0c;并被分为大约20个模块 2. 设计理念 Spring是面向Bean的编程&#xff08;BOP&#xff1a;Bean Oriented Programming&#xff09;&#xff0c;Bean在Spring中才是真正的主角。Bean在…

物联网工程应用实训室建设方案

一、物联网工程应用系统概述 1.1物联网工程定义 物联网工程&#xff08;Internet of Things Engineering&#xff09;是一种以信息技术&#xff08;IT&#xff09;来改善实体世界中人们生活方式的新兴学科&#xff0c;它利用互联网技术为我们的日常生活活动提供服务和增益&am…

CI+JUnit5并发单测机制创新实践

目录 一. 现状问题 二. 分析原因 三. 采取措施 四. 实践步骤 五. 效能提升 资料获取方法 一. 现状问题 针对现如今高并发场景的业务系统&#xff0c;“并发问题” 终归是必不可少的一类&#xff08;占比接近10%&#xff09;&#xff0c;每次出现问题和事故后&#xff0c…

年至年的选择仿elementui的样式

组件&#xff1a;<!--* Author: liuyu liuyuxizhengtech.com* Date: 2023-02-01 16:57:27* LastEditors: wangping wangpingxizhengtech.com* LastEditTime: 2023-06-30 17:25:14* Description: 时间选择年 - 年 --> <template><div class"yearPicker"…

Vue2(组件开发)

目录 前言一&#xff0c;组件的使用二&#xff0c;插槽slot三&#xff0c;refs和parent四&#xff0c;父子组件间的通信4.1&#xff0c;父传子 &#xff1a;父传子的时候&#xff0c;通过属性传递4.2&#xff0c;父组件监听自定义事件 五&#xff0c;非父子组件的通信六&#x…

【算法题】螺旋矩阵II (求解n阶Z形矩阵)

一、问题的提出 n阶Z形矩阵的特点是按照之(Z)字形的方式排列元素。n阶Z形矩阵是指矩阵的大小为nn&#xff0c;其中n为正整数。 题目描述 一个 n 行 n 列的螺旋(Z形)矩阵如图1所示&#xff0c;观察并找出填数规律。 图1 7行7列和8行8列的螺旋(Z形)矩阵 现在给出矩阵大小 n&…

基于MIV的神经网络变量筛选

1.案例背景 一般神经网络中所包含的网络输人数据是研究者根据专业知识和经验预先选择好的,然而在许多实际应用中,由于没有清晰的理论依据,神经网络所包含的自变量即网络输入特征难以预先确定,如果将一些不重要的自变量也引入神经网络,会降低模型的精度,因此选择有意义的自变量特…

驱动 - 20230816

练习 1.编写LED灯的驱动&#xff0c;可以控制三个灯&#xff0c;应用程序中编写控制灯的逻辑&#xff0c;要使用自动创建设备节点机制 驱动头文件 ledHead.h #ifndef __HEAD_H__ #define __HEAD_H__#define PHY_GPIOE_MODER 0X50006000 #define PHY_GPIOE_ODR 0X50006014 #d…

leetcode228. 汇总区间

题目 给定一个 无重复元素 的 有序 整数数组 nums 。 返回 恰好覆盖数组中所有数字 的 最小有序 区间范围列表 。也就是说&#xff0c;nums 的每个元素都恰好被某个区间范围所覆盖&#xff0c;并且不存在属于某个范围但不属于 nums 的数字 x 。 列表中的每个区间范围 [a,b]…

MySQL入门学习教程(三)

上一章给大家说的是数据库的视图&#xff0c;存储过程等等操作&#xff0c;这章主要讲索引&#xff0c;以及索引注意事项&#xff0c;如果想看前面的文章&#xff0c;url如下&#xff1a; MYSQL入门全套(第一部)MYSQL入门全套(第二部) 索引简介 索引是对数据库表中一个或多个…

自动化安装系统(一)

系统安装过程 加载boot loader加载启动安装菜单加载内核和initrd文件加载根系统运行anaconda的安装向导 安装光盘中与安装相关的文件 安装autofs启动后会自动出现/misc目录。 在虚拟机设置中添加CD/DVD&#xff0c;使用系统ISO文件&#xff0c;登录系统后mount /dev/cdrom …

【Linux】进程的基本属性|父子进程关系

个人主页&#xff1a;&#x1f35d;在肯德基吃麻辣烫 我的gitee&#xff1a;Linux仓库 个人专栏&#xff1a;Linux专栏 分享一句喜欢的话&#xff1a;热烈的火焰&#xff0c;冰封在最沉默的火山深处 文章目录 前言进程属性1.进程PID和PPID2.fork函数创建子进程1&#xff09;为什…

【深入了解PyTorch】PyTorch模型解释性和可解释性:探索决策过程与预测结果的奥秘

【深入了解PyTorch】PyTorch模型解释性和可解释性:探索决策过程与预测结果的奥秘 PyTorch模型解释性和可解释性:探索决策过程与预测结果的奥秘1. 引言2. 梯度可视化3. 特征重要性分析4. 结论PyTorch模型解释性和可解释性:探索决策过程与预测结果的奥秘 在机器学习和深度学习…

【Docker】Docker使用之容器技术发展史

&#x1f3ac; 博客主页&#xff1a;博主链接 &#x1f3a5; 本文由 M malloc 原创&#xff0c;首发于 CSDN&#x1f649; &#x1f384; 学习专栏推荐&#xff1a;LeetCode刷题集 &#x1f3c5; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff0…

嵌入式学习之字符串

通过今天的学习&#xff0c;我主要提高了对sizeof 和 strlen、puts()、gets()、strcmp 、strncmp、strstr、strtok的理解。重点对sizeof的使用有了更加深刻的理解