关于linux内核cpu进程的负载均衡

本文涉及的产品
网络型负载均衡 NLB,每月750个小时 15LCU
应用型负载均衡 ALB,每月750个小时 15LCU
传统型负载均衡 CLB,每月750个小时 15LCU
简介:
2.6内核中进程调度模块的负载均衡行为分为“拉”和“推”,推这里不考虑,关于拉均衡有一篇文章特别好,具体出处就不记得了,我当时用的百度快照,那篇文章我认为最精彩的部分就是下面摘录的这段话: 
当某个 cpu 负载过轻而另一个 cpu 负载较重时,系统会从重载 cpu 上"拉"进程过来,这个"拉"的负载平衡操作实现在 load_balance() 函数中。load_balance() 有两种调用方式,分别用于当前 cpu 不空闲和空闲两种状态,我们称之为"忙平衡"和"空闲平衡": 
无论当前 cpu 是否繁忙或空闲,时钟中断(rebalance_tick()函数中)每隔一段时间(BUSY_REBALANCE_TICK)都会启动一次 load_balance() 平衡负载,这种平衡称为"忙平衡"。 
Linux 2.6 倾向于尽可能不做负载平衡,因此在判断是否应该"拉"的时候做了很多限制: 
1.系统最繁忙的 cpu 的负载超过当前 cpu 负载的 25% 时才进行负载平衡; 
2.当前 cpu 的负载取当前真实负载和上一次执行负载平衡时的负载的较大值,平滑负载凹值; 
3.各 cpu 的负载情况取当前真实负载和上一次执行负载平衡时的负载的较小值,平滑负载峰值; 
4.对源、目的两个就绪队列加锁之后,再确认一次源就绪队列负载没有减小,否则取消负载平衡动作; 
5.源就绪队列中以下三类进程参与负载情况计算,但不做实际迁移: 
5.1.正在运行的进程 
5.2.不允许迁移到本 cpu 的进程(根据 cpu_allowed 属性) 
5.3.进程所在 cpu 上一次调度事件发生的时间(runqueue::timestamp_last_tick,在时钟中断中取值)与进程被切换下来的时间(task_struct::timestamp)之差小于某个阀值(cache_decay_ticks的nanosecond值),--该进程还比较活跃,cache 中的信息还不够凉。 
... 
以上的论述是基于2.6.2内核的,我看了那篇文章之后,感觉内核负载均衡的设计非常完美,然后我很迫切的翻起代码寻找一些蛛丝马迹,可是却没有找到明显的上面说到的东西,很是郁闷,然后我又研究了一下新内核的代码,发现了linux内核在做负载均衡的时候一个很巧妙的技巧,相比2.6.2内核只能说有过之而无不及。首先先说说负载均衡的策略,和2.6.2一样,也是尽量避免做负载均衡,除非非做不可了,因为负载均衡只是一个优化吞吐量和性能手段,它不是目的,因此没有必要让它占用太多的处理器时间,当然也没有必要提供编程接口了,机器有几个cpu,是否做负载均衡这些信息对用户是不可见的,但是用户可以通过设置一些微调参数从而影响内核负载均衡的行为,这种方式在linux中是很常见的。下面就来说一下新内核的负载均衡,linux有一个特点,如果一个特性是好的,那么即使高版本的内核也要向下兼容它,这里的兼容只是原理上,新版本的内核可能通过一种不同的方式实现这种老的理念,那么我们就在2.6.28内核中找一下2.6.2的负载均衡的影子吧。 
在新内核中,有一个函数特别有意思,就是update_cpu_load,这个函数更新了rq数据结构中的cpu_load数组字段,这个cpu_load数组在负载均衡中很重要,它代表了该队列所属cpu的负载,其实负载在cfs之前就是该cpu上运行的进程的数量,在cfs中代表当前cpu上所有的进程的权值之和,不过一个负载为何用一个数组而不仅仅是一个数字呢,这就是技巧所在,linux不仅仅根据当前这次负载均衡时的各个cpu负载来决定如何行动,linux还不丢失cpu以前的负载,因为这个涉及到缓存的热度等等cpu亲和相关的概念,但是负载均衡并不是在一个条件下触发的,它在很多条件下都会被触发,而这些条件对cpu亲和的要求并不相同,比如新创建进程的时候就不用考虑什么亲和的问题,还有如果是在运行idle的时候进行的负载均衡,那可能要考虑cpu亲和,但是考虑的程度绝对没有运行非idle进程时进行的负载均衡考虑cpu亲和的程度高,于是一个数字就不能代表这一切了,必须有个地方保留曾经的cpu负载信息,如果仅仅为了将曾经的负载信息考虑进去,那么也没有必要用一个数组,类比LRU的理论算法,用一个整数就可以了,每个时钟嘀嗒中,原来的cpu负载右移若干位,然后当前的负载加上去,负载均衡的时候用这个值作为参考进行一些变换后(因为要和当前cpu负载的单位一致,如果不变换的话,那么曾经的负载信息就会无故地加到上次时钟嘀嗒时cpu负载的低位上)和当前的cpu负载进行平滑行为就可以了,平滑行为和上述摘录的文章段落一致,我感觉比2.6.2实现的更好,因为2.6.2的实现只是用这次和上次的cpu负载信息进行平滑操作,上次以前的cpu负载信息将失效,虽然不是那么容易,但是还是可能出现大的跳跃。还没有完,上面说不能用一个数来保存cpu负载信息用于负载均衡的原因就在于还要区分不同的情况,比如空闲均衡,忙均衡或者exec均衡等,可是上面想到的那个用移位的方式保存以前的负载信息很绝妙以至于不能不用,不就是还需要保存一个情况信息吗,其实很好办,将不同的情况都用刚才的那个移位算法,每种情况保存一个数字,多种情况就成了一个数组,于是这个cpu_load数组就出来了,我估计作者就是这么想到的,另外为了省去负载均衡时和当时的cpu负载进行平滑操作时还要进行变换,在向cpu_load数组中的元素赋值的时候就做好变换,于是新的算法不用移位实现,用比例实现,也就是说按照不同的情况,也就是数组的不同元素,老的负载信息在cpu_load元素最终结果中所占的比例不同,最后我们来看看这个函数: 
static void update_cpu_load(struct rq *this_rq) 


 本文转自 dog250 51CTO博客,原文链接:http://blog.51cto.com/dog250/1273504

相关实践学习
小试牛刀,一键部署电商商城
SAE 仅需一键,极速部署一个微服务电商商城,体验 Serverless 带给您的全托管体验,一起来部署吧!
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
目录
打赏
0
0
0
0
344
分享
相关文章
Linux内核中的线程和进程实现详解
了解进程和线程如何工作,可以帮助我们更好地编写程序,充分利用多核CPU,实现并行计算,提高系统的响应速度和计算效能。记住,适当平衡进程和线程的使用,既要拥有独立空间的'兄弟',也需要在'家庭'中分享和并行的成员。对于这个世界,现在,你应该有一个全新的认识。
107 67
schedule:原来还可以这样让进程让出 CPU?
文章主要讲述通过模拟时钟中断和调度事件来优化和测试虚拟机监控器(VMM)的方法,包括流程设计、寄存器状态的保存与恢复、硬件中断处理规范等细节。
schedule:原来还可以这样让进程让出 CPU?
Linux 内核源码分析---proc 文件系统
`proc`文件系统是Linux内核中一个灵活而强大的工具,提供了一个与内核数据结构交互的接口。通过本文的分析,我们深入探讨了 `proc`文件系统的实现原理,包括其初始化、文件的创建与操作、动态内容生成等方面。通过对这些内容的理解,开发者可以更好地利用 `proc`文件系统来监控和调试内核,同时也为系统管理提供了便利的工具。
63 16
【YashanDB 知识库】如何避免 yasdb 进程被 Linux OOM Killer 杀掉
本文来自YashanDB官网,探讨Linux系统中OOM Killer对数据库服务器的影响及解决方法。当内存接近耗尽时,OOM Killer会杀死占用最多内存的进程,这可能导致数据库主进程被误杀。为避免此问题,可采取两种方法:一是在OS层面关闭OOM Killer,通过修改`/etc/sysctl.conf`文件并重启生效;二是豁免数据库进程,由数据库实例用户借助`sudo`权限调整`oom_score_adj`值。这些措施有助于保护数据库进程免受系统内存管理机制的影响。
|
1月前
|
Linux 进程前台后台切换与作业控制
进程前台/后台切换及作业控制简介: 在 Shell 中,启动的程序默认为前台进程,会占用终端直到执行完毕。例如,执行 `./shella.sh` 时,终端会被占用。为避免不便,可将命令放到后台运行,如 `./shella.sh &`,此时终端命令行立即返回,可继续输入其他命令。 常用作业控制命令: - `fg %1`:将后台作业切换到前台。 - `Ctrl + Z`:暂停前台作业并放到后台。 - `bg %1`:让暂停的后台作业继续执行。 - `kill %1`:终止后台作业。 优先级调整:
61 5
Intel Linux 内核测试套件-LKVS介绍 | 龙蜥大讲堂104期
《Intel Linux内核测试套件-LKVS介绍》(龙蜥大讲堂104期)主要介绍了LKVS的定义、使用方法、测试范围、典型案例及其优势。LKVS是轻量级、低耦合且高代码覆盖率的测试工具,涵盖20多个硬件和内核属性,已开源并集成到多个社区CICD系统中。课程详细讲解了如何使用LKVS进行CPU、电源管理和安全特性(如TDX、CET)的测试,并展示了其在实际应用中的价值。
Ubuntu20.04搭建嵌入式linux网络加载内核、设备树和根文件系统
使用上述U-Boot命令配置并启动嵌入式设备。如果配置正确,设备将通过TFTP加载内核和设备树,并通过NFS挂载根文件系统。
190 15
如何找出Java进程占用CPU高的元凶
本文记录了一次Java进程CPU占用率过高的问题和排查思路。
深入探索Linux内核的内存管理机制
本文旨在为读者提供对Linux操作系统内核中内存管理机制的深入理解。通过探讨Linux内核如何高效地分配、回收和优化内存资源,我们揭示了这一复杂系统背后的原理及其对系统性能的影响。不同于常规的摘要,本文将直接进入主题,不包含背景信息或研究目的等标准部分,而是专注于技术细节和实际操作。
Linux操作系统的内核优化与性能调优####
本文深入探讨了Linux操作系统内核的优化策略与性能调优方法,旨在为系统管理员和高级用户提供一套实用的指南。通过分析内核参数调整、文件系统选择、内存管理及网络配置等关键方面,本文揭示了如何有效提升Linux系统的稳定性和运行效率。不同于常规摘要仅概述内容的做法,本摘要直接指出文章的核心价值——提供具体可行的优化措施,助力读者实现系统性能的飞跃。 ####

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等