从Linux源码分析负载均衡过程

整理代码基于Linux源码v5.12.13,后面的代码解释是我在本地ppt上直接截图贴上来的,可能有点糊。

有问题可以留言或者漂流瓶联系我。。。

调度域 & 调度组

Linux调度域主要分为三层,可以理解为下一层的调度域(domain)成为新的调度组(group)合并入上一层的调度域。

简单看一下调度域结构体里面的几个属性,后面会用得到:

1. parent/child :父/子调度域

2. last_balance :上次balance的时间

3. balance_interval :balance时间间隔

CPU runqueue

每个cpu都会有一个运行队列,其上存储着在当前CPU上处于就绪和运行状态的进程。

其上的进程包含三个种类的队列,按照优先级顺序分别为dl,rt 和 cfs。

其余的结构体内包含信息如图所示,只列出了和本文相关的部分变量。

负载均衡整体流程

这部分简要介绍一下负载均衡的整体流程,不会涉及到具体代码细节。

如果只是想知道一下流程,那么看完这一段就可以直接左上角了。

1. 调度器的初始化:会对每个cpu的runqueue内容进行初始化,包括调度域,下次调度时间等等,初始化过程中会给rq结构体的next_balance赋予初值,用于后续判断是否需要进行负载均衡,该值在后续执行负载均衡函数调用之后会进行更新。

2. 定时器中断处理函数调用scheduler_tick函数,此函数是所有调度子函数的父函数,是大多数调度函数的源,在此函数内会调用trigger_load_balance函数触发负载均衡的流程。

3. 在trigger_load_balance函数内会判断是否已经到达当前cpu的rq的负载均衡时间点(next_balance),如果达到就会提交一个软中断。处理软中断时会调用相应的软中断处理函数,当前cpu就成为负载均衡的dst_cpu。

4. 在软中断处理函数中会调用函数rebalance_domains,在函数内部会对当前cpu的相关调度域进行遍历(遍历它及它的父调度域),对比是否达到了当前调度域(domain)的负载均衡时间点,从而决定是否需要真正进行负载均衡。

5. 然后在该调度域中找到最忙的调度组,在此调度组中找到最忙的cpu队列,此cpu即为负载均衡的src_cpu。

6. 接下来,就是将src cpu上的一部分负载拉取到dst cpu上即可。

具体代码调用流程

这部分会详细贴出整个负载均衡过程中函数的调用流程,对于关键的部分使用红色边框圈起来并进行了介绍。代码的截图基本上都保留对应的文件名称和代码行数,感兴趣的可以去内核源码看一看。

调度初始化:sched_init

在start_kernel中对调度器进行初始化的函数就是sched_init,初始化过程中会给next_balance赋予初值,用于后续判断是否需要进行负载均衡,该值在后续执行负载均衡函数调用之后会进行更新。

定时器调用scheduler_tick

scheduler_tick()是所有调度子函数的父函数,而其是由Linux时间子系统的tick_device调用。tick_device是一个周期性定时器,定时时间为1个tick,当触发中断后,会在中断处理函数中,调用scheduler_tick()。

而打开了tickless,即动态tick后,那么就会切换至oneshot模式,并负责调用scheduler_tick()。

注:定时器运行在单触发模式(one-shot mode),与周期模式(periodic mode)运行的定时器不同,周期模式运行的定时器,只要对它进行一次初始化操作,以后定时器就会周期的产生中断,不再需要额外的对定时器进行编程操作;而当定时器运行于单触发模式下时,每当定时器产生一次中断后就不再运行,系统再根据当前任务对时间的要求计算出定时器下一次应该产生中断的时间间隔,然后再对定时器进行编程,使它能在系统要求的将来某一时刻产生中断。在单触发模式下,定时器的定时精度能达到微秒级。不过需要注意的是,由于每次中断后都要计算下一次中断的时间,而且还要对定时器进行编程,这两个操作会降低系统的性能。

scheduler_tick

scheduler_tick 是所有调度子函数的父函数,是大多数调度函数的源。

trigger_load_balance

CPU对应的运行队列数据结构中记录了下一次周期性负载均衡的时间,当超过这个时间点后,将触发SCHED_SOFTIRQ软中断来进行负载均衡。

本质上就是判断一下当前的jiffies是不是已经比rq->next_balance值大,如果值大的话,会进一步调用raise_softirq提交一个软中断。提交的过程很简单,就是把SCHED_SOFTIRQ对应的位置位,处理软中断时检查是否位,如果置位调用相应的软中断处理函数。

关于 cpu_active ,我简单查了一下,不确定正确性:

When CPU entered 1st step, i.e. the CPU_DOWN_PREPARE, the scheduler marks it as not 'active', but it's still 'online' at the moment. Scheduler could not migrate any task to it at this time. After the CPU is totally removed, it's not 'online' anymore

软中断处理函数

没啥好说的,就是两步调用。

rebalance_domains

load_balance

先列出load_balance函数的总体流程,之后涉及到的关键函数会在之后进行详细介绍。

以上就是负载均衡执行的整体流程了。

下面简要介绍一下其中涉及到的几个函数的具体实现。

should_we_balance

该函数主要用于判断当前cpu是否需要进行负载均衡:

首先需要明确一点的是,负载均衡执行到当前cpu时,是判断当前cpu是否需要执行负载均衡从其他cpu处pull task过来,或者可以说,dst_cpu在这一轮操作中是确定的,就是当前cpu。

而should_we_balance则是用于判断当前cpu需不需要进行负载均衡。

有几种情况:

1. 如果当前cpu状态为NEWLY IDLE,即目前CPU上没有可运行的task,准备进入idle 的状态,此时需要做load balance。

2. 否则寻找当前cpu所在的调度组上的第一个空闲的cpu,然后判断这个空闲的cpu和dst_cpu(即当前cpu)是否是同一个cpu,如果是,则需要进行负载均衡,否则不需要。

3. 如果没有idle cpu的话,就判断当前cpu是否是其所在调度组的第一个cpu,如果是,则需要进行负载均衡,否则不需要。

find_businest_group

该函数的主要作用就是找到调度域内最忙的调度组。

介绍该函数之前先简单看一下两个数据结构,具体作用图里已经很清楚了哈。

然后,find_businest_group函数总体流程大致如下:

接下来简要介绍一下,其中的update_sd_lb_stats函数

update_sd_lb_stats

统计各个group的负载,并得到最businest的group

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容