做人呢,最紧要就系开心啦

Linux内核之进程4:CPU的负载均衡

443次阅读
没有评论

1. 线程的负载均衡

对 task_struct 做负载均衡;

分布式系统中,linux 的每个核都自动以劳动为乐,(共产主义社会)。

分别对 RT 任务和普通线程做负载均衡

RT 任务:将 n 个优先级最高的线程自动分配到 n 个核;

pull_rt_task()
push_rt_task()

负载均衡时机:(普通任务,cfs 调度)

  • 周期性负载均衡,在 时钟 tick会检查哪个核空闲,优先使空闲核工作(从负载重的核 pull 任务,或 push 任务给空闲核,每个 CPU 以劳动为乐);

  • idle 时负载均衡;某个核进入idle 状态,会主动 pull 任务执行;

  • fork 和 exec 时负载均衡;创建的新进程,会放到最闲的核去跑;

软亲和性(affinity) Linux 内核进程调度器天生就具有被称为软 CPU
亲和性(affinity)的特性,这意味着进程通常不会在处理器之间频繁迁移。这种状态正是我们希望的,因为进程迁移的频率小就意味着产生的负载小。

硬亲和性(affinity): 就是利用 linux 内核提供给用户的 API,强行将进程或者线程绑定到某一个指定的 cpu 核运行。

需要绑定 CPU 的原因:

1. 提高 cache 命中率;

2. 在一些非对称 CPU,比如 NUMA 中,防止一个 CPU 去另外一个插槽的内存读写数据;

Linux 内核之进程 4:CPU 的负载均衡

也可以用 taskset 工具设置:-a 所有线程

pidof ./a.out

Linux 内核之进程 4:CPU 的负载均衡

进程 a.out 占用 CPU800%(八核)

Linux 内核之进程 4:CPU 的负载均衡

设置只在 2 号核跑

taskset -a -p 02 554

Linux 内核之进程 4:CPU 的负载均衡

CPU 占有率降至 100%,所有线程只在 2 号核上跑;

2. 中断负载均衡

负载除了进程还有中断,执行完中断,才会去执行 task_struct 任务;

硬件中断一般比较短(linux2.6.34 后内核不支持中断嵌套),比如网卡收包,在硬中断接收完包,会调用软中断(处理 tcp/ip 包,软中断可以嵌套),软中断结束后,会调用 vtime 最小的线程;

top 命令的 hi 表示硬中断时间(isr,屏蔽中断),si 表示软中断,

Linux 内核之进程 4:CPU 的负载均衡

当网络流量大的时候,CPU 花在硬中断和软中断时间比较多,这时候需要做中断的负载均衡;

现在新网卡一般有多个队列,假如在一个 4 核的系统,网卡有 4 个队列,每个队列可以单独产生中断,硬件支持负载均衡;那么可以将一个队列绑定到一个核,这样,所有 CPU 都会参与网卡发送包服务;
Linux 内核之进程 4:CPU 的负载均衡

设定方法:将每个中断号,分别设置 affinity,绑定到指定 CPU

Linux 内核之进程 4:CPU 的负载均衡

cat /proc/interrupts |grep 'enp'

124: 0 0 0 0 0 0 0 34 415207449 PCI-MSI 1572864-edge enp3s0
Linux 内核之进程 4:CPU 的负载均衡

sudo sh -c "echo 3 > /proc/irq/124/smp_affinity"

Linux 内核之进程 4:CPU 的负载均衡

有的网卡只有一个队列:单个核抛出的软中断只能在这个核跑,那么一个队列抛出的软中断 (tcp/ip 层处理) 只能在这一个核执行,其他核会空闲;

测试:

客户端:\$ echo " 不要回答!不要回答!不要回答!" | nc 10.10.100.16 1235

服务端:\$ nc -l -p 1235

3 RPS 补丁

Google 推出了 rps 补丁,可以把 TCP/IP 协议栈的处理,均衡到多个核上去,这个技术叫 RPS;

比如我手头板子是单个网卡队列收包,默认是单核上执行

#cat /sys/class/net/eth0/queues/rx-0/rps_cpus

0

收包只在 CPU0 上执行

Linux 内核之进程 4:CPU 的负载均衡

nc -l -p 1235

监听 1235 端口收到数据时,只有 CPU0 继续增加;

多核间的 softIRQ scaling

设置 rps 在 CPU0/ 1 上均衡

echo 3 > /sys/class/net/eth0/queues/rx-0/rps_cpus

watch –d“cat /proc/softirqs | grep NET_RX”

/proc/interrupt

/proc/softirq

分别查看硬中断和软中断次数

top + 1 显示多核的负载

Linux 内核之进程 4:CPU 的负载均衡

由上可以看到 CPU0/ 1 都开始处理网络接收包

经实验得出结论

  1. 硬中断绑定的 CPU 核,一定会响应 softirqs,不管对应 rps_cpus 位设置与否;

2. 当 rps_cpus 位设置时,对应 CPU 核会响应 softirqs;

RPS 原理:由单一 CPU 核响应硬件中断,将大量网络接收包,通过多核间中断方式分发给其他空闲核,如下网络图清晰说明情况

Linux 内核之进程 4:CPU 的负载均衡

上图引用自https://blog.csdn.net/dog250/article/details/46705657

4.linux 不是硬实时系统:

硬实时:满足可预期,非一定越快越好,强调的是截止期限的可预期性;

Linux 内核之进程 4:CPU 的负载均衡

Linux 内核之进程 4:CPU 的负载均衡

Linux 的设计决定了她不是硬实时系统,有些情况 (比如 spin_lock) 不可抢占,其不可预期,是软实时系统;

用什么系统由场景决定,并非硬实时一定优于软实时。

Linux 的抢占算法演变,越新的内核支持抢占越多;

Linux 内核之进程 4:CPU 的负载均衡

Linux 的 CPU 消耗主要分以下几种:

Linux 内核之进程 4:CPU 的负载均衡

内核态的 spin_lock,是自旋锁,用户态不是;

1,2,3 都不可抢占,所以 linux 不是一个硬实时系统,硬实时系统要求任何时刻都可以抢占

Linux 内核之进程 4:CPU 的负载均衡

T3 时刻唤醒一个更高优先级 RT 线程,
RT 线程只能到 T5 时刻 (硬中断,软中断都执行完,并且释放 spin_lock 之后) 才能抢占,等待时间是未知的。

要解决 linux 硬实时性,需要打 rt 补丁,

补丁不在 mainline 中,维护网站;

https://wiki.linuxfoundation.org/realtime/start

https://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-stable-rt.git/

rt 补丁

将所有中断线程化,

去掉软中断,

spin_lock 改成 mutex 实现,即系统中只有上图第 4 类进程,任何线程都可以被抢占;

使延迟变为可预期,即成为硬实时系统。

不是每一个内核版本都有相应 rt 补丁。

rt 可以将 linux 延迟做到 100us 量级(1G CPU),同时吞吐会下降。

打上补丁后如下图

Linux 内核之进程 4:CPU 的负载均衡

Server: 不抢占

Desktop: kernel 不抢占

Low-Latency Destktop:手机用,kernel 也抢占

Real-Time:完全抢占;

调度器实时后,linux 还不一定实时,有无数内存坑,比如内存管理部分,ROW,写内存时发现内存尚未分配,此时无法保持实时性。

其他方法:

同时运行两个系统,实时任务放在 RTOS 跑,非实时任务放在 Linux 跑。

比如单反,一般用两个系统,传统拍照用实时系统,涉及网络相关任务放在 linux,利用 linux 强大的网络协议栈。

5.Deadline 调度算法

https://elinux.org/images/f/fe/Using_SCHED_DEADLINE.pdf

如下场景需求,系统有两个任务,核电站任务要求运行 1 /2s, 洗衣机要求运行 20ms/200ms;

Linux 内核之进程 4:CPU 的负载均衡

用传统 RT 或 CFS 调度算法,必须设置洗衣机优先级更高才能满足需求。(核电站优先级更高将独占 CPU 超过 0.5s,
下一个周期无法满足 CPU 需求)
Linux 内核之进程 4:CPU 的负载均衡

但当系统有多个任务,比如核电站要求 800ms 周期内必须跑 500ms,洗碗机要求 300/900ms,
洗衣机要求 100/800ms:

Linux 内核之进程 4:CPU 的负载均衡

总的 CPU 消耗是小于 100% 的。但是按照传统 RR 算法,无法满足调度需求;

Linux 内核之进程 4:CPU 的负载均衡

Linux 提供了一个 Rate Monotonic Scheduling:

Deadline 调度算法思想:当产生一个调度点的时候,DL 调度器总是选择其 Deadline 距离当前时间点最近的那个任务并调度它执行,谁更紧急,谁先跑;

Deadline 需要设置三个参数,周期 Period,Deadline, Runtime

Linux 内核之进程 4:CPU 的负载均衡

deadline 调度器虽然可以保证每个 RT 任务在 deadline 之前完成,但是并不能保证每一个任务的最小响应时间。

内核实例,sched-deadline.c

设置允许普通用户修改 app 调度策略

sudo setcap 'cap_sys_nice=eip' ./a.out

pidof ./a.out

sudo chrt -d -T 1000000 -P 3000000 -D 2000000 0 pid

sudo chrt -p pid

$ sudo chrt -p 6276

chrt: unknown scheduling policy

pid 6276's current scheduling policy: pid 6276's current scheduling priority: 0

chrt 版本太低,未支持显示 deadline 参数;

Deadline 在 top 显示 rt 进程,

正文完
 
admin
版权声明:本站原创文章,由 admin 2022-01-04发表,共计3434字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)