ip_vs 原理解析 (三)调度器

文章目录

  • 调度器
    • 注册
    • 调度器绑定 svc
  • ip_vs_schedule 结构体
  • PE

调度器

ipvs 的 调度器(scheduler) 有很多种,这里不详细介绍各个调度器的算法,主要关注于 ipvs 流程中的调度器注册和使用。

ipvs 的调度器有 rr(轮询),wrr(加权轮询),lc(最小链接),sh(源地址散列),sed(最短预期延时) 等等

注册

每个调度器都是通过 module_init() 进行初始化

rr 调度器static struct ip_vs_scheduler ip_vs_rr_scheduler = {.name =			"rr",			/* name */.refcnt =		ATOMIC_INIT(0),.module =		THIS_MODULE,.n_list =		LIST_HEAD_INIT(ip_vs_rr_scheduler.n_list),.init_service =		ip_vs_rr_init_svc,.add_dest =		NULL,.del_dest =		ip_vs_rr_del_dest,.schedule =		ip_vs_rr_schedule,
};static int __init ip_vs_rr_init(void)
{return register_ip_vs_scheduler(&ip_vs_rr_scheduler);
}module_init(ip_vs_rr_init);

register_ip_vs_scheduler 调度函数
将调度器链接在全局链表 ip_vs_schedulers 上

调度器绑定 svc

在第一节 ipvsadm 创建 svc 时 ip_vs_bind_scheduler 会为 svc 绑定调度器

ip_vs_bind_scheduler| -- init_service       执行调度器的 init_service 函数,调度器| -- rcu_assign_pointer(svc->scheduler, scheduler) 将调度器结构赋予虚拟服务结构的 scheduler 成员

看一下 rr 的 init_service

ip_vs_rr_init_svc| -- svc->sched_data = &svc->destinations;      将 rs 链表赋予 svc 的调度器应用 data,svc->sched_data

看一下 wrr 的 init_service

static int ip_vs_wrr_init_svc(struct ip_vs_service *svc)
{struct ip_vs_wrr_mark *mark;mark = kmalloc(sizeof(struct ip_vs_wrr_mark), GFP_KERNEL);if (mark == NULL)return -ENOMEM;mark->cl = list_entry(&svc->destinations, struct ip_vs_dest, n_list);       // 后端链表mark->di = ip_vs_wrr_gcd_weight(svc);                                                  // 计算最大公约数的方法,即权重步长mark->mw = ip_vs_wrr_max_weight(svc) - (mark->di - 1);                     // 最大权重计算方法mark->cw = mark->mw;                                                                           // 当前权重svc->sched_data = mark;return 0;
}

ip_vs_schedule 结构体

接着看 ip_vs_rr_scheduler
其中的 .schedule 即调度方法,如 rr 的 ip_vs_rr_schedule

static struct ip_vs_dest *
ip_vs_rr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,struct ip_vs_iphdr *iph)
{struct list_head *p;struct ip_vs_dest *dest, *last;int pass = 0;IP_VS_DBG(6, "%s(): Scheduling...\n", __func__);spin_lock_bh(&svc->sched_lock);p = (struct list_head *) svc->sched_data;last = dest = list_entry(p, struct ip_vs_dest, n_list);do {list_for_each_entry_continue_rcu(dest,&svc->destinations,n_list) {if (!(dest->flags & IP_VS_DEST_F_OVERLOAD) &&atomic_read(&dest->weight) > 0)/* HIT */goto out;if (dest == last)goto stop;}pass++;/* Previous dest could be unlinked, do not loop forever.* If we stay at head there is no need for 2nd pass.*/} while (pass < 2 && p != &svc->destinations);stop:spin_unlock_bh(&svc->sched_lock);ip_vs_scheduler_err(svc, "no destination available");return NULL;out:svc->sched_data = &dest->n_list;spin_unlock_bh(&svc->sched_lock);IP_VS_DBG_BUF(6, "RR: server %s:%u ""activeconns %d refcnt %d weight %d\n",IP_VS_DBG_ADDR(dest->af, &dest->addr), ntohs(dest->port),atomic_read(&dest->activeconns),refcount_read(&dest->refcnt), atomic_read(&dest->weight));return dest;
}

可以看到轮询的调度算法,svc->sched_data 是当前链表中后端的指针,当调度时,将之前的后端赋值给 last,然后循环链表给 dst,如果循环到的 dst 可用,即 goto out,设置 sched_data 为当前调度到的后端的指针,然后返回当前后端。

其中的 .add_dest 和 .del_dest 即增加和删除 后端的操作,像 rr 算法添加 后端时不需要调整,但删除时需要 ip_vs_rr_del_dest。

static int ip_vs_rr_del_dest(struct ip_vs_service *svc, struct ip_vs_dest *dest)
{struct list_head *p;spin_lock_bh(&svc->sched_lock);p = (struct list_head *) svc->sched_data;/* dest is already unlinked, so p->prev is not valid but* p->next is valid, use it to reach previous entry.*/if (p == &dest->n_list)svc->sched_data = p->next->prev;spin_unlock_bh(&svc->sched_lock);return 0;
}

在删除的 后端是当前调度的后端时的情况,这个时候将当前调度的后端改为当前节点在链表的前一个,这样后续调度时也能正常调度到当前节点的下一个。

像 wrr 添加 dst,删除 dst,更新 dst,都需要 ip_vs_wrr_dest_changed,这是由于权重变更后,有可能最大权重,最大公约数都会变化,需要更新整个 svc->sched_data。由此看出,后端的变化会即时更新调度算法。

PE

持久化引擎,当前 ip_vs 只有一种 sip 即源 ip 策略

	.ct_match =		ip_vs_sip_ct_match,
static bool ip_vs_sip_ct_match(const struct ip_vs_conn_param *p,struct ip_vs_conn *ct){bool ret = false;if (ct->af == p->af &&ip_vs_addr_equal(p->af, p->caddr, &ct->caddr) &&/* protocol should only be IPPROTO_IP if* d_addr is a fwmark */ip_vs_addr_equal(p->protocol == IPPROTO_IP ? AF_UNSPEC : p->af,p->vaddr, &ct->vaddr) &&ct->vport == p->vport &&ct->flags & IP_VS_CONN_F_TEMPLATE &&ct->protocol == p->protocol &&ct->pe_data && ct->pe_data_len == p->pe_data_len &&!memcmp(ct->pe_data, p->pe_data, p->pe_data_len))ret = true;IP_VS_DBG_BUF(9, "SIP template match %s %s->%s:%d %s\n",ip_vs_proto_name(p->protocol),IP_VS_DEBUG_CALLID(p->pe_data, p->pe_data_len),IP_VS_DBG_ADDR(p->af, p->vaddr), ntohs(p->vport),ret ? "hit" : "not hit");return ret;
}

在 Kubernetes 中,service 的 sessionAffinity: ClientIP 利用了该特性,在 timeout 时间内,同一个 源 ip 的访问会调度到同一个 后端。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux C 获取主机网卡名及 IP 的几种方法

在进行 Linux 网络编程时&#xff0c;经常会需要获取本机 IP 地址&#xff0c;除了常规的读取配置文件外&#xff0c;本文罗列几种个人所知的编程常用方法&#xff0c;仅供参考&#xff0c;如有错误请指出。 方法一&#xff1a;使用 ioctl() 获取本地 IP 地址 Linux 下可以使用…

【Spring框架】SpringBoot统一功能处理

目录 用户登录权限校验用户登录拦截器排除所有静态资源练习&#xff1a;登录拦截器拦截器实现原理 统一异常处理统一数据返回格式为什么需要统⼀数据返回格式&#xff1f;统⼀数据返回格式的实现 用户登录权限校验 用户登录拦截器 1.自定义拦截器 package com.example.demo.…

shell centos 7 一键部署 KVM软件脚本

这个脚本有限地方还需要完善下 设计思路&#xff1a; 1、创建检查内核函数 check_kernel() 2、创建升级内核函数 update_kernel() 3、创建检查是否支持虚拟化函数 check_virtual() 4、创建检查操作系统函数 check_system() 5、创建检查网络函数 check_network() 6…

MicroPython ESP32网页实时更新DHT11数据显示

MicroPython ESP32网页实时更新DHT11数据显示 &#x1f4cc;相关篇《MicroPython ESP32 读取DHT11温湿度传感器数据》&#x1f4cd;《【Micropython esp32/8266】网页点灯控制示例》 ✨本例综合以上两篇文章内容实现&#xff1a;在本地网页中显示DHT11温度传感器数据。可以做到…

【Clion 2】使用技巧

一、TODO: 说明&#xff1a; 有时需要标记部分代码以供将来参考&#xff1a; 优化和改进的领域、可能的更改、要讨论的问题等等。 支持&#xff1a; TODO和FIXME小写和大写。这些模式可以在任何受支持的文件类型的行注释和块注释内使用。 创建TODO项 在要添加注释的代码行中…

大数据课程F3——HIve的基本操作

文章作者邮箱&#xff1a;yugongshiyesina.cn 地址&#xff1a;广东惠州 ▲ 本章节目的 ⚪ 掌握HIve的基本SQL语句和注意问题&#xff1b; ⚪ 掌握HIve的表结构&#xff1b; ⚪ 掌握HIve的数据类型&#xff1b; ⚪ 掌握HIve的基础函数和窗口函数&#xff1b; …

认识 SQL

文章目录 1.简介2.SQL 的组成3.SQL 是如何工作的&#xff1f;4.五种子语言5.SQL 注释参考文献 1.简介 SQL&#xff08;Structured Query Language&#xff0c;结构化查询语言&#xff09;是一种用于管理和操作关系型数据库的标准化查询语言。它是一种特定域语言&#xff08;DS…

Python web实战之 Django 的 MVC 设计模式详解

技术栈&#xff1a;Python、Django、HTML、CSS、JavaScript。 概要 在 Web 开发中&#xff0c;MVC&#xff08;Model-View-Controller&#xff09;模式是一种非常常见的设计模式&#xff0c;它可以帮助我们更好地管理代码&#xff0c;提高代码的可维护性。今天就介绍如何使用 …

前端性能优化的利器 ——— 浅谈JavaScript中的防抖和节流

防抖和节流函数是工作中两种常用的前端性能优化函数&#xff0c;今天我就来总结一下什么是防抖和节流&#xff0c;并详细说明一下如何在工作中应用防抖和节流函数 什么是防抖和节流? 在 JavaScript 中&#xff0c;防抖&#xff08;debounce&#xff09;和节流&#xff08;thr…

RTT(RT-Thread)线程管理(1.2W字详细讲解)

目录 RTT线程管理 线程管理特点 线程工作机制 线程控制块 线程属性 线程状态之间切换 线程相关操作 创建和删除线程 创建线程 删除线程 动态创建线程实例 启动线程 初始化和脱离线程 初始化线程 脱离线程 静态创建线程实例 线程辅助函数 获得当前线程 让出处…

数组中的第K个最大元 O(N)

给定整数数组 nums 和整数 k&#xff0c;请返回数组中第 k 个最大的元素。 请注意&#xff0c;你需要找的是数组排序后的第 k 个最大的元素&#xff0c;而不是第 k 个不同的元素。 你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例 1: 输入: [3,2,1,5,6,4], k 2…

[腾讯云Cloud Studio实战训练营]无门槛使用GPT+Cloud Studio辅助编程完成Excel自动工资结算

目录 前言一、Cloud Studio产品介绍1.1 注册Cloud Studio 二、项目实验2.1 选择合适的开发环境2.2 实验项目介绍2.3 实验步骤三、总结 前言 chatgpt简单介绍: ChatGPT是一种基于GPT的自然语言处理模型&#xff0c;专门用于生成对话式文本。它是OpenAI于2021年发布的&#xff0…

突破传统监测模式:业务状态监控HM的新思路 | 京东云技术团队

一、传统监控系统的盲区&#xff0c;如何打造业务状态监控。 在系统架构设计中非常重要的一环是要做数据监控和数据最终一致性&#xff0c;关于一致性的补偿&#xff0c;已经由算法部的大佬总结过就不再赘述。这里主要讲如何去补偿&#xff1f;补偿的方案哪些&#xff1f;这就…

TCP/IP协议

TCP/IP 是一类协议系统&#xff0c;它是用于网络通信的一套协议集合 物理层 所谓的物理层&#xff0c;是指光纤、电缆或者电磁波等真实存在的物理媒介。这些媒介可以传送物理信号&#xff0c;比如亮度、电压或者振幅。对于数字应用来说&#xff0c;我们只需要两种物理信号来分别…

加强 Kubernetes 能力:利用 CRD 定义多版本资源的实现方式

姚灿武&#xff0c;Rancher 中国研发工程师&#xff0c;拥有 7 年云计算领域经验&#xff0c;热衷开源技术&#xff0c;在云原生相关技术领域拥有丰富的开发和实践经验。 CRD&#xff0c;即自定义资源定义&#xff08;Custom Resource Definition&#xff09;&#xff0c;是 Ku…

leetcode 435. 无重叠区间

2023.8.3 本题和引爆气球 这题非常类似&#xff0c;利用同样的思路可以解决&#xff0c;代码如下&#xff1a; class Solution { public:static bool cmp(vector<int>& a , vector<int>& b){if(a[0] b[0]) return a[1] < b[1];return a[0] < b[0];…

SpringBoot复习:(16)TomcatStarter

直接在idea里运行SpringBoot程序时&#xff0c;内嵌的tomcat容器会调用TomcatStarter这个类的onStartup方法。TomcatStarter继承自ServletContainerInitializer 其onStartup方法会调用ServletContextInitializer&#xff08;不是ServletContainerInitializer)的onStartup方法.…

Unity 引擎做残影效果——3、顶点偏移方式

Unity实现残影效果 大家好&#xff0c;我是阿赵。 继续讲Unity引擎的残影做法。这次的残影效果和之前两种不太一样&#xff0c;是通过顶点偏移来实现的。 具体的效果是这样&#xff1a; 与其说是残影&#xff0c;这种效果更像是移动速度很快时造成的速度线&#xff0c;所以在移…

C# 开发规范

控件命名规则 控件名简写 控件名简写LabellblTextBoxtxtButtonbtnLinkButtonlnkbtnImageButtonimgbtnDropDownListddlListBoxlstDataGriddgDataListdlCheckBoxchkCheckBoxListchklsRadioButtonrdoRadioButtonListrdoltImageimgPanelpnlCalendecldAdRotatorarTabletblRequiredF…

Flink On Yarn模式部署与验证

session运行模式 该模式下分为2步&#xff0c;即使用yarn-session.sh申请资源&#xff0c;然后 flink run提交任务。 1、申请资源yarn-session.sh #在server1执行命令 /usr/local/flink-1.13.5/bin/yarn-session.sh -tm 1024 -n 2 -s 1 -d #申请2个CPU、2g内存 # -tm 表示每个…