CPU负载均衡之调度概念理解
前言
首先来回答一个问题:为什么需要调度?
- 有很多task,只有一个CPU,大家都想先运行,如果没有管理人员,起冲突怎么办?
- task是无限的,CPU的能力是有限的,有限的资源无法满足无限的需求的时候?
所以所谓调度,就是针对于资源和需求的管理,是一种资源管理工具,设置规则,让所有task根据规则来决定谁先谁后;
正文开始前首先show一张图介绍本文内容:
1. 概念说明
1.1 task
什么是task?就是需求者!对于Linux来讲,调度的单位是进程,则需求者的具象化就是进程;
TASK状态:
// 基于linux 4.9 路径:/incude/linux/sched.h
/** Task state bitmask. NOTE! These bits are also* encoded in fs/proc/array.c: get_task_state().** We have two separate sets of flags: task->state* is about runnability, while task->exit_state are* about the task exiting. Confusing, but this way* modifying one set can't modify the other one by* mistake.*/
#define TASK_RUNNING 0
#define TASK_INTERRUPTIBLE 1
#define TASK_UNINTERRUPTIBLE 2
#define __TASK_STOPPED 4
#define __TASK_TRACED 8
/* in tsk->exit_state */
#define EXIT_DEAD 16
#define EXIT_ZOMBIE 32
#define EXIT_TRACE (EXIT_ZOMBIE | EXIT_DEAD)
/* in tsk->state again */
#define TASK_DEAD 64
#define TASK_WAKEKILL 128
#define TASK_WAKING 256
#define TASK_PARKED 512
#define TASK_NOLOAD 1024
#define TASK_NEW 2048
#define TASK_STATE_MAX 4096
1.2 scheduler
什么是scheduler? 就是管理者!在Linux中有scheduler和scheduler_tick两种调度器;
1.3 res
管理的内容是什么?CPU资源,在Linux中CPU资源被划分为时间片,则一个CPU也是一个可拆分的资源;
1. 时间片长短如何决定?根据优先级
2. 时间片的基准来自于哪里?依赖于定时中断,根据系统频率,软件配置HZ,则一个tick为1/HZ,系统中定义HZ为100、250、1000等
- 假设主频为1G,则时间片为us级别
1.3.1 jiffies
记录自系统启动以来产生的tick总数,每次时钟中断产生时,jiffies + 1;
系统中将其初始化为:-300 * HZ(用于检测不对jiffies做溢出检测的缺陷code)
HZ在kernel被初始化为:#define HZ 100 /include/uapi/asm-generic/param.h
如果有指定CONFIG_HZ 则会修改这个tick数,按照这个来计算HZ为100,也就是说一个tick数为10ms
(这里最好还是直接查看机器中的定义:/proc/config.gz中可以看到config_gz=250)对应code中在/kernel/kernel/Kconfig.hz这里配置默认为250HZ(测试修改这里为1000HZ后失败);
2. 调度原理
2.1 一般我们考虑有哪些方式:
如果要管理一个队列,有哪些排队的方式?
类似于:排队管理是动态调整的,比如1号最急,那就直接把1号拍到第一个,再比如10号已经排了半个月了,那就把10号的位置往前提提;
首先我们从原理上考虑有哪些调度算法?
- 先进先出的策略,First Come,First Served(FCFS)
- 严格按照时间片划分,时间片轮转RR(Round-Robin)
- 找到消耗时间最短的任务,SJF(Short Job First,短作业优先)
- 就绪状态等待CPU调度的时间长则提升优先级的方式(避免耗时久的任务无法被调度)
- 存储多个队列(按照优先级)划分:
- 在可抢占的情况下可能存在低优先级的任务永远无法被调度,而且可能出现:现在这个低优先级task和某个高优先级task共享资源,则可能导致无法被释放):
- 采用优先级继承,出现上述情况时,直接继承高优先级,处理完成;
- 设置临界区优先级上限,则进入临界区的进程都临时使用该优先级;
- 禁止中断;
- 在可抢占的情况下可能存在低优先级的任务永远无法被调度,而且可能出现:现在这个低优先级task和某个高优先级task共享资源,则可能导致无法被释放):
- 是否可以被抢占
2.2 衡量指标
name | 说明 |
---|---|
吞吐量 (Throughput) | 每单位时间完成的进程数目 |
周转时间TT (Turnaround Time) | 每个进程从提出请求到运行完成的时间 |
响应时间RT(Response Time) | 从提出请求到第一次回应的时间 |
CPU利用率(CPU Utilization) | CPU做有效工作的时间比例 |
等待时间(Waiting time) | 每个进程在就绪队列(ready queue)中等待的时间 |
针对于不同的应用场景,上述指标之间是冲突的:
- 提高响应速度(时间片短),则会频繁切换,影响吞吐率;
- 前台任务和后台任务关注点不同,前台注重响应速度,后台注重吞吐量
- 消耗CPU多的和IO受限的:
- IO bound,task中存在大量的IO操作,CPU一直在等待IO,IO性能限制,成为block点;
- CPU bound,task中存在大量消耗CPU算力的操作,则CPU一直在忙,资源不足,成为block点;
3. linux中的实现
3.1 runqueue
task队列如何管理?每个CPU维护一个结构,将所有的task添加到对应queue中
- runqueue:
变量 | 含义 |
---|---|
nr_running | 运行队列链表中可运行进程的数量 |
cpu_load | 基于运行队列中进程的平均数量的CPU负载因子 |
nr_switchs | CPU执行进程切换的次数 |
nr_uninterruptible | 先前在运行队列链表中而现在在睡眠状态,且不可打断 |
nr_iowait | 先前在运行队列的链表,现在在等待磁盘IO操作 |
- 如何保证效率:
- 每个CPU有一个runqueue;
- 对于task-running状态的进程,按照优先级划分为140个list,这样按照优先级直接取最早的就可以了;(对比之前需要遍历所有task,然后计算出最高优先级,效率高很多)
- 由于有CPU hotplug的功能,如果现在CPU3 offline的话,该CPU上本来排队的task要如何迁移?
- CPU HOTPLUG即热插拔,是指在不需要关机的情况下,动态开关其中某一个或者多个core的技术;
- 对应关闭的core上的runqueue中task_running队列要迁移到其他仍在online状态的CPU上;
- 排列顺序存在算法补偿;
3.2 策略
- 优先级划分:
- SCHED_RR:实时进程,按照时间片划分,则添加到可运行队列
- SCHED_FIFO:实时进程,调度CPU使用时,会将该进程放在队列中当前位置,即除非有更高优先级打断他,否则他就可以一直执行到task结束;
- 实时进程优先级为0~100,也就是说实时进程一定比普通进程优先级高,实时进程永远是running task;
- 实时进程如何退出?
- 被更高优先级的实时进程抢占;
- 自己进入其他状态:
- 进入sleep wait:interruptible、uninterruptible
- 停止 stop状态
- sched_yield,自己放弃掉
- 基于RR策略,时间片用完了;
- SCHED_NORMAL:普通分时进程
- 静态优先级:100~139,值越小,优先级越低;继承自父进程,可通过函数修改(nice、setpriority);
- 静态优先级与时间片分配的长短有关:(140-静态优先级)* 系数
- 系数与优先级大小有关:100 ~ 120 系数为20 ,120 ~ 140 系数为5;
- 动态优先级:根据静态优先级和bonus计算,即TASK在就绪状态等待CPU调度的时间越久,优先级增加越多(bonus 0~10)
如果按照上述的方式进行,则可能存在一种情况,很多低优先级的case一直得不到调度,所以这里就变得更加复杂了:维护一种活动进程一种过期进程,即用完时间片后加入禁止运行队列;
- 静态优先级与时间片分配的长短有关:(140-静态优先级)* 系数
- 当然这里只是描述的处理思路,与实际的实现还要更复杂一些,还要考虑到交互、后台批处理等的差异,这个策略叫做O(1)
- 缺陷:
- 严格依赖于优先级;
- 根据优先级划分时间片,而非根据task的所需时间;
- 静态优先级:100~139,值越小,优先级越低;继承自父进程,可通过函数修改(nice、setpriority);
3.2.2 CFS
Linux经过几个版本的更新,O(1)逐步优化为了:完全公平策略(CFS)
- 引入virtual runtime的机制(本质为实际CPU耗时),替代原来的优先级;
- runtime值,新创建task的runtime值并非是0,而是当前所有task中的min_runtime,这样既可以保证新加入的task优先执行,也可以保证老进程不因为runtime差距过大一直得不到运行;
- sleep状态的进程runtime值保持不变?不是,在唤醒时会做一定补偿,这样其他task的值增大后,就会优先处理sleep的task(唤醒后);
- runtime值可以无穷小么?系统中定义了最小值,如果比这个小,则无法被抢走CPU;
- 采用红黑树的存储,可以满足快速找到;
- 优先级计算时间片影响因子,即低优先级的virtual runtime和高优先级的virtual runtime所代表的实际运行时间不同;
- 设置一个调度周期时间,则保证所有task在一个周期内有一次调度;
- 负载跟踪策略:
- PELT:Per-Entity Load Tracking
- WALT:Window-Assisted Load Tracking
3.3 图示总结schedule相关关系
CPU负载均衡之调度概念理解相关推荐
- LVS负载均衡集群概念
LVS负载均衡集群概念 一.群集的含义 集群.群集 由多台主机构成,但对外,只表现为一个整体,只提供一个访问入口(域名或IP),相当于一台大型计算机. 1.群集存在的必要 互联网应用中,随着站点对硬件 ...
- 负载均衡原理与实践详解 第三篇 服务器负载均衡的基本概念-网络基础
负载均衡原理与实践详解 第三篇 服务器负载均衡的基本概念-网络基础 系列文章: 负载均衡详解第一篇:负载均衡的需求 负载均衡详解第二篇:服务器负载均衡的基本概念-网络基础 负载均衡详解第三篇:服务器负 ...
- Nginx入门简介和反向代理、负载均衡、动静分离理解
场景 Nginx简介 Nginx ("engine x")是一个高性能的 HTTP 和反向代理服务器 特点是占有内存少,并发能力强,事实上 nginx 的并发能力确实在同类型的网页 ...
- 查看linux cpu负载均衡,关于linux内核cpu进程的负载均衡
2.6内核中进程调度模块的负载均衡行为分为"拉"和"推",推这里不考虑,关于拉均衡有一篇文章特别好,具体出处就不记得了,我当时用的百度快照,那篇文章我认为最精彩 ...
- 一文读懂 | CPU负载均衡实现
在<一文读懂 | 进程怎么绑定 CPU>这篇文章中介绍过,在 Linux 内核中会为每个 CPU 创建一个可运行进程队列,由于每个 CPU 都拥有一个可运行进程队列,那么就有可能会出现每个 ...
- linux内核死锁检测机制 | oenhan,Linux内核CPU负载均衡机制 | OenHan
还是神奇的进程调度问题引发的,参看Linux进程组调度机制分析,组调度机制是看清楚了,发现在重启过程中,很多内核调用栈阻塞在了double_rq_lock函数上,而double_rq_lock则是lo ...
- SLB负载均衡的概念
目录 一:SLB的概念 1.1什么是负载均衡? 1.2负载均衡SLB发展过程 1.3负载均衡的主要作用 二:阿里云负载均衡SLB 2.1阿里云负载均衡SLB的优点 2.2负载均衡SLB应用场景 2.3 ...
- linux进程网络均衡,linux多CPU进程负载均衡解析
在linux中,支持对称smp的处理器模型,在多处理器的情况下,每个处理器都有自己的一个运行队列,这样就存在着分配不均的情况,有的cpu运行队列很多进程,导致一直很忙,有的cpu运行队列可能很少的进程 ...
- 简单的几句话让你理解”什么是备份、容灾、集群、负载均衡”
关于容灾.备份.集群.负载均衡这类概念,很多朋友都容易混淆,到底它们之间有什么区别?今天小编我就给大家分别介绍一下,让大家有个深刻的理解 ! 一.备份概念的理解 "备份"只是将数据 ...
- linux在多核处理器上的负载均衡原理
原文出处:http://donghao.org/uii/ [原理] 现在互联网公司使用的都是多CPU(多核)的服务器了,Linux操作系统会自动把任务分配到不同的处理器上,并尽可能的保持负载均衡.那L ...
最新文章
- 网络工程师_记录的一些真题_2005下半年上午
- pip安装库包遇到错误:TypeError: expected str, bytes or os.PathLike object, not int 的解决方法
- Ring3下实现进程保护,不用hook
- 第5章 Python 数字图像处理(DIP) - 图像复原与重建16 - 约束最小二乘方滤波、几何均值滤波
- linux--切换ipython解释器到python3
- C++ 指向子类的指针转型为指向父类类型指针之后指向的对象地址不变
- 二值图像中封闭孔洞的高效填充算法(附源码)。
- HDU 1556【线段树区间更新】
- flex align-center:center多行垂直方向居中 align-items:center垂直方向单行居中
- 《物联网框架ServerSuperIO教程》-19.设备驱动和OPC Client支持mysql、oracle、sqlite、sqlserver的持久化。v3.6.4版本发布...
- 编写一个应用程序,给出汉字“你”“我”“他”在Unicode表中的位置。
- SecureCRT安装与使用
- C语言求解圆周率近似值
- 中国电力电子行业前景方向预测及投资规划建议报告2022-2028年版
- c语言鸡兔同笼的程序,C语言:鸡兔同笼问题
- YOLOv1的pytorch复现版本,博主亲自测试完整复现。
- 给交换机console接口设置密码
- 【STL MAP】热血格斗场
- php组合图片代码,使用php shell命令合并图片的代码
- 是地价决定房价还是房价决定地价