深入分析负载均衡情景

本文出现的内核代码来自Linux5.4.28,为了减少篇幅,我们尽量不引用代码,如果有兴趣,读者可以配合代码阅读本文。

一、有几种负载均衡的方式?

整个Linux的负载均衡器有下面的几个类型:

实际上内核的负载均衡器(本文都是特指CFS任务的)有两种,一种是为繁忙CPU们准备的periodic balancer,用于CFS任务在busy cpu上的均衡。还有一种是为idle cpu们准备的idle balancer,用于把繁忙CPU上的任务均衡到idle cpu上来。idle balancer有两种,一种是nohz idle balancer,另外一种是new idle balancer。

周期性负载均衡(periodic load balance或者tick load balance)是指在tick中,周期性的检测系统的负载均衡状况,找到系统中负载最重的domain、group和CPU,将其上的runnable任务拉到本CPU以便让系统的负载处于均衡的状态。周期性负载均衡只能在busy cpu之间均衡,要想让系统中的idle cpu“燥起来”就需要借助idle load balance。

NOHZ load balance是指其他的cpu已经进入idle,本CPU任务太重,需要通过ipi将其他idle的CPUs唤醒来进行负载均衡。为什么叫NOHZ load balance呢?那是因为这个balancer只有在内核配置了NOHZ(即tickless mode)下才会生效。如果CPU进入idle之后仍然有周期性的tick,那么通过tick load balance就能完成负载均衡了,不需要IPI来唤醒idle的cpu。和周期性均衡一样,NOHZ idle load balance也是通过busy cpu上tick驱动的,如果需要kick idle load balancer,那么就会通过GIC发送一个ipi中断给选中的idle cpu,让它代表系统所有的idle cpu们进行负载均衡。

New idle load balance比较好理解,就是在CPU上没有任务执行,马上要进入idle状态的时候,看看其他CPU是否需要帮忙,从来从busy cpu上拉任务,让整个系统的负载处于均衡状态。NOHZ load balance涉及系统中所有的idle cpu,但New idle load balance只是和即将进入idle的本CPU相关。

 

二、周期性负载均衡的大概过程为何?

当tick到来的时候,在scheduler_tick函数中会调用trigger_load_balance来触发周期性负载均衡,相关的代码如下:

整个代码非常的简单,主要的逻辑就是调用raise_softirq触发SCHED_SOFTIRQ,当然要满足均衡间隔时间的要求(后面会详述)。nohz_balancer_kick用来触发nohz idle balance的,这是后面两个章节要仔细描述的内容。上面的图片,我特地保留了函数的注释,这里看起似乎注释不对,因为这个函数不但触发的周期性均衡,也触发了nohz idle balance。然而,其实nohz idle balance本质上也是另外一种意义上的周期性负载均衡,只是因为CPU进入idle,无法产生tick,因此让能产生tick的busy CPU来帮忙触发tick balance。而实际上tick balance和nohz idle balance都是通过SCHED_SOFTIRQ的软中断来处理,最后都是执行run_rebalance_domains这个函数。

三、整个nohz idle balance的过程是怎样的?

这个问题可以拆解成两个问题:

1)系统中有多个idle的cpu,如何选择执行nohz idle balance的那个cpu?

2)怎么通知到idle的CPU,唤醒的CPU如何进行均衡?

如果不考虑功耗,那么从所有的idle cpu中选择一个就OK了,然而,在异构系统中(例如手机环境),我们要考虑更多。例如:如果大核CPU和小核CPU都处于idle状态,那么选择唤醒大核CPU还是小核CPU?大核CPU虽然算力强,但是功耗高。如果选择小核,虽然能省功耗,但是提供的算力是否足够。此外,发起idle balance请求的CPU在那个cluster?是否首选同一个cluster的cpu来执行nohz idle balance?还有cpu idle的深度如何?很多思考点,不过本文就不详述了,毕竟标准内核选择的最简单的算法:随便选择一个idle cpu(也就是idle cpu mask中的第一个)。

我们定义发起nohz idle balance的CPU叫做kicker;接收请求来执行均衡操作的CPU叫做kickee。Kicker和kickee之间的交互是这样的:

1)Kicker通知kickee已经被选中执行nohz idle balance,具体是通过设定kickee cpu runqueue的nohz_flags成员来完成的。

2)Send ipi把kickee唤醒

3)Kickee被中断唤醒,执行scheduler_ipi来处理这个ipi中断。当发现其runqueue的nohz_flags成员被设定了,那么知道自己被选中,后续的流程其实和周期性均衡一样的,都是触发一次SCHED_SOFTIRQ类型的软中断

我们再强调一下:被kick的那个idle cpu并不是负责拉其他繁忙cpu上的任务到本CPU上就完事了,kickee是为了重新均衡所有idle cpu(tick被停掉)的负载,也就是说被选中的idle cpu仅仅是一个系统所有idle cpu的代表,它被唤醒是要把系统中繁忙CPU的任务均衡到系统中所有的idle cpu们。此外,在上面的步骤1中,有可能有多个kicker同时选中一个kickee,因此这里需要检测pending的请求,避免重复操作。具体的代码可以参考nohz_balancer_kick函数。

SCHED_SOFTIRQ软中断的处理函数如下:

nohz idle balance和periodic load balance都是通过SCHED_SOFTIRQ类型的软中断来完成,也就是说它们两个都是通过SCHED_SOFTIRQ注册的handler函数run_rebalance_domains来完成其功能的,那么如果一个CPU被选中做nohz idle balance,于此同时tick也到了,那么怎么处理?这个时候调度器优先处理nohz idle balance,毕竟nohz idle balance是一个全局的事情(代表系统所有idle cpu做均衡),而periodic load balance只是均衡自己的各阶sched domain。

四、什么条件下才需要唤醒idle CPU来执行NOHZ idle load balance?

在一个active的CPU上,tick会周期性到来,我们在该CPU的tick中检测是否需要触发NOHZ load balance。显然一个轻载的CPU可以“自力更生”,不需要其他idle的CPU来协助,那么如何界定一个CPU上的任务的轻和重?以至于需要冒险(功耗损失)要将其他idle的CPU唤醒?主要考虑下面几点:

  • 本CPU不能处于idle状态,且其runqueue中的任务数大于等于2(load balance主要是迁移runnable的任务,>=2保证了至少有一个可以被迁移的任务)
  • 系统中有其他的CPU处于tickless mode的idle状态
  • NOHZ load balance不宜触发的过于频繁。下一章会详细描述。
  • 本CPU runqueue有至少1个CFS任务,并且CPU的算力被大量消耗在RT task或者IRQ处理上,可以用于执行cfs的算力大大降低了,这时候也需要其他idle cpu来帮忙。
  • 在异构计算系统中,如果当前CPU上有misfit task,并且系统中有更高算力的idle cpu,那么也会发起balance,让算力更高的处理器来承接该misfit task。和提高cache命中率相比,调度器更期待任务可以获得更适合算力的CPU。

具体的代码可以参考nohz_balancer_kick函数。

五、如何控制触发nohz idle balance的频次?

虽然nohz idle balance本质上是tick balance,但是它会发IPI,会唤醒idle的cpu,带来额外的开销,所以还是要控制触发触发nohz idle balance的频次。为了方便控制触发nohz idle balance,调度器定义了一个nohz的全局变量,其数据结构如下:

nr_cpus和idle_cpus_mask这两个成员可以让调度器了解当前系统idle CPU的情况,从而选择合适的CPU来执行nohz idle balance。一个idle的cpu被kick并不总是完成负载均衡,有时候也可能是因为要更新blocked load,让系统中的CPU负载符合当前的状态。这部分不是本文的内容,不再详述。next_balance是用来控制触发nohz idle balance的时间点,这个时间点应该是和系统中所有idle cpu的rq->next_balance相关的,也就是说,如果系统中所有idle cpu都还不需要均衡,那么根本也就没有必要触发nohz idle balance,因此,在执行nohz idle balance的时候,调度器实际上会遍历idle cpu找到rq->next_balance最小的(即最近需要均衡的)赋值给nohz.next_balance。

具体执行nohz idle balance非常简单,遍历系统所有的idle cpu,调用rebalance_domains来完成该cpu上的各个level的sched domain的负载均衡。具体的代码可以参考nohz_idle_balance函数。

 资料直通车:Linux内核源码技术学习路线+视频教程内核源码

学习直通车:Linux内核源码内存调优文件系统进程管理设备驱动/网络协议栈

六、做new idle load balance需要考虑哪些因素?

目前调度器做new idle load balance主要考虑两个因素:当前cpu的cache状态和当前的整机负载情况。如果该CPU平均idle时间非常短,那么当CPU重新回来执行的任务的时候,CPU cache还是热的,如果从其他CPU上拉取任务,那么这些新的任务会破坏其他任务的cache,从而影响过去任务的性能,同时也有功耗的增加。整机负载的影响记录在root domain中的overload成员中,所谓overload就是指满足下面的条件:

  • 大于1个runnable task,即该CPU上有等待执行的任务
  • 只有一个正在运行的任务,但是是misfit task

满足上面的条件我们称这个CPU是overload状态的,如果系统中至少有一个CPU是overload状态,那么我们认为系统是overload状态的。如果系统没有overload,那么也就没有必要做new idle load balance了。

上面是从CPU视角做的决定,降低了new idlebalance的次数,此外,调度器也从sched domain的角度进行检查,进一步避免了无效new idlebalance发生的次数。首先我们要明确一点:做new idle load balance是有开销的,我们辛辛苦苦找到了繁忙的CPU,从它的runqueue中拉了任务来,然而如果自己其实也没有那么闲,可能很快就有任务放置到自己的runqueue上来,这样,那些用于均衡的CPU时间其实都白白浪费了。怎么避免这个尴尬状况?我们需要两个数据:一个是当前CPU的平均idle时间,另外一个是在new idle load balance引入的开销(max_newidle_lb_cost成员)。如果CPU的平均idle时间小于max_newidle_lb_cost+本次均衡的开销,那么就不启动均衡。

为了控制cpu无效进入new idle load balance,runqueue数据结构中有下面的成员:

计算avg_idle的算法非常简单,如下:

和nohz idle balance一样,new idle balance不仅仅要处理负载均衡,同时也要负责处理blocked load的更新。如果条件不满足,该cpu不需要进行均衡,那么在进入idle状态之前,还需要看看系统中的那些idle cpu们的blocked load是否需要更新了,如果需要,那么该CPU就会执行blocked load的负载更新。其背后的逻辑是:与其在nohz idle balance过程中遍历选择一个idle CPU来做负载更新,还不如就让这个即将进入idle的cpu来处理。具体的代码可以参考newidle_balance函数。

七、对于一个sched domain而言,多久做一次负载均衡比较适合?

负载均衡执行的频次其实是在延迟和开销之间进行平衡。不同level的sched domain上负载均衡带来的开销是不一样的。在手机平台上,MC domain在inter-cluster之内进行均衡,对性能的影响小一点。但是DIE domain上的均衡需要在cluster之间迁移任务,对性能和功耗的影响都比较大一些(例如cache命中率,或者一个任务迁移到原来深度睡眠的大核CPU)。因此执行均衡的时间间隔应该是和domain的层级相关的。此外,负载状况也会影响均衡的时间间隔,在各个CPU负载比较重的时候,均衡的时间间隔可以拉大,毕竟大家都忙,让子弹先飞一会,等尘埃落定之后在执行均衡也不迟。

struct sched_domain和均衡相关的数据成员包括:

对于一个4+4的手机平台,在MC domain上,小核和大核cluster的min_interval都是4ms,而max_interval等于8ms。而在DIE domain层级上,由于CPU个数是8,其min_interval是8ms,而max_interval等于16ms。真正的均衡间隔是定义在balance_interval中,是一个不断跟随sched domain的不均衡程度而变化的值。初值一般从min_interval开始,随着不均衡的状况在变好,balance_interval会逐渐变大,从而让均衡的间隔变大,直到max_interval。

八、结束语

周期性均衡和nohz idle balance都是SCHED类型的软中断触发,最后都调用了rebalance_domains来执行该CPU上各个level的sched domain的均衡,具体在某个sched domain执行均衡的函数是load_balance函数。对于new idle load balance,也是遍历该CPU上各个level的sched domain执行均衡动作,调用的函数仍然是load_balance。因此,无论哪一种均衡,最后都万法归宗来到load_balance。由于篇幅原因,本文不再详细分析load_balance的逻辑,想要了解细节且听下回分解吧。

原文作者:内核工匠

 

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

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

相关文章

【TI毫米波雷达笔记】UART串口外设配置及驱动(以IWR6843AOP为例)

【TI毫米波雷达笔记】UART串口外设初始化配置及驱动(以IWR6843AOP为例) 最基本的工程建立好以后 需要给SOC进行初始化配置 int main (void) {//刷一下内存memset ((void *)L3_RAM_Buf, 0, sizeof(L3_RAM_Buf));int32_t errCode; //存放SOC初…

同态比较算法

参考文献: [PS73] Paterson M S, Stockmeyer L J. On the number of nonscalar multiplications necessary to evaluate polynomials[J]. SIAM Journal on Computing, 1973, 2(1): 60-66.[IZ21] Iliashenko I, Zucca V. Faster homomorphic comparison operations …

redis7高级篇3 数据量亿级别的统计分析(hyperloglog,bitmap,geo)

一 亿级别统计分类 1.1 统计分类 1.聚合统计:统计多个集合聚合的结果,也就是多个集合之间交并差的统计。 2.排序统计:在需要展示最新列表,排行榜等场景时,如果数据更新频繁或者需要分页时,建议使用zset12…

滚珠螺杆导程对精度有影响吗?

滚珠螺杆的导程也称螺距,即螺杆每旋转一周螺母直线运动的距离,导程与直线速度有关,在输入转速一定的情况下,导程越大速度越快。正常来说,选择导程时,尽量选5和10最好。 很多人一直觉得导程会影响滚珠螺杆的…

【安卓】自定义View实现画板涂鸦等功能

一、实现效果 二、代码 1、MainActivity.class package com.lsl.mydrawingboarddemo;import androidx.appcompat.app.AppCompatActivity; import androidx.core.content.ContextCompat;import android.os.Bundle; import android.os.Handler; import android.view.View; impo…

73 # 发布自己的 http-server 到 npm

1、添加 .npmignore 文件,忽略不需要的文件 public2、去官网https://www.npmjs.com/检查自己的包名是否被占用 3、切换到官方源,然后检查确认 nrm use npm nrm ls4、登录 npm 账号 npm login5、发布 npm publish6、查看发布情况,发布成功…

npm 卸载 vuecli后还是存在

运行了npm uninstall vue-cli -g,之后是up to date in,然后vue -V,版本号一直都在,说明没有卸载掉 1、执行全局卸载命令 npm uninstall vue-cli -g 2、删除vue原始文件 查看文件位置,找到文件删掉 where vue 3、再…

山西电力市场日前价格预测【2023-08-27】

日前价格预测 预测明日(2023-08-27)山西电力市场全天平均日前电价为318.11元/MWh。其中,最高日前电价为356.66元/MWh,预计出现在19: 15。最低日前电价为273.48元/MWh,预计出现在04: 30。 价差方向预测 1: 实…

Jenkins的定时任务配置

jenkins配置定时任务位置(点击日程表的问好可查看语法配置) jenkins的定时任务的参数 # 定时任务参数(每个参数之间使用tab键或空格分隔)MINUTE HOUR DOM MONTH DOW 参数解释取值范围 MINUTE 分钟0-59HOUR小时0-23DOM一月的天数1-31MONTH月份1-12DOW 一周的天数0…

实验七 Linux 内核移植

【实验目的】 掌握 Linux 内核配置和编译的基本方法 【实验环境】 ubuntu 14.04 发行版FS4412 实验平台交叉编译工具:arm-none-linux-gnueabi- 【注意事项】 实验步骤中以“$”开头的命令表示在 ubuntu 环境下执行,以“#”开头的命令表 示在开发板下…

PHP 安装Composer,vue前端依赖包

电脑安装Composer 官网下载:https://getcomposer.org/Composer-Setup.exe 后端安装: 检查是否安装依赖: 安装Composer install 或 Composer i 前端安装: yarn install 安装依赖

vr内容编辑软件降低了虚拟现实项目开发门槛

VR虚拟场景编辑器是一种专门用于创建、修改和设计虚拟场景的工具。它利用vr虚拟现实技术,让用户可以在三维空间中直接对场景进行操作和编辑。这种编辑器的出现,使得用户可以更加直观、自由地进行场景设计和制作,为诸多领域带来了新的可能性。…

Linux(基础篇一)

Linux基础篇 Linux基础篇一1. Linux文件系统与目录结构1.1 Linux文件系统1.2 Linux目录结构 2. VI/VIM编辑器2.1 vi/vim是什么2.2 模式间的转换2.3 一般模式2.4 插入模式2.4.1 进入编辑模式2.4.2 退出编辑模式 2.5 命令模式 3. 网络配置3.1 网络连接模式3.2 修改静态ip3.3 配置…

AI夏令营第三期用户新增挑战赛学习笔记

1、数据可视化 1.数据探索和理解:数据可视化可以帮助我们更好地理解数据集的特征、分布和关系。通过可视化数据,我们可以发现数据中的模式、异常值、缺失值等信息,从而更好地了解数据的特点和结构。2.特征工程:数据可视化可以帮助…

WPF基础入门-Class5-WPF命令

WPF基础入门 Class5-WPF命令 1、xaml编写一个button&#xff0c;Command绑定一个命令 <Grid><ButtonWidth"100"Height"40" Command"{Binding ShowCommand}"></Button> </Grid>2、编写一个model.cs namespace WPF_Le…

033 - date 和 time

date类型&#xff1a; 该DATE类型用于具有日期部分但没有时间部分的值。MySQL检索并DATE以 格式显示 值 。支持的范围是 到。 YYYY-MM-DD1000-01-019999-12-31 -- 创建表&#xff0c;字段类型是date&#xff1a; create table test_date01 (a date); -- 正确格式插入数据 in…

OceanMind海睿思签约常州市建筑科学研究院,打造检验检测行业数字化转型标杆

近日&#xff0c;中新赛克海睿思 与 中国知名综合性建筑研究和科技创新型高科技企业——常州市建筑科学研究院集团股份有限公司&#xff08;以下简称“建科股份”&#xff09;达成深度战略合作&#xff0c;为建科股份提供行业领先的数据工程建设服务&#xff0c;携手推进检验检…

java八股文面试[JVM]——双亲委派模型

1.当AppClassLoader去加载一个class时&#xff0c;它首先不会自己去尝试加载这个类&#xff0c;而是把类加载请求委托给父加载器ExtClassLoader去完成。 2.当ExtClassLoader去加载一个class时&#xff0c;它首先也不会去尝试加载这个类&#xff0c;而是把类加载请求委托给父加载…

python面试题--1

目录 python面试题 1&#xff09;什么是Python&#xff1f;使用Python有什么好处&#xff1f; 2&#xff09;什么是PEP 8&#xff1f; 3&#xff09;什么是序列化和非序列化&#xff1f; 4&#xff09;如何解释Python&#xff1f; 5&#xff09;如何在Python中内存管理&a…

2023年国赛 高教社杯数学建模思路 - 案例:退火算法

文章目录 1 退火算法原理1.1 物理背景1.2 背后的数学模型 2 退火算法实现2.1 算法流程2.2算法实现 建模资料 ## 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 退火算法原理 1.1 物理背景 在热力学上&a…