Linux线程调度引起的业务问题

一、 问题现象

  1.业务组播出向报文偶尔有延迟;

  2.单播出向报文平滑

二、 分析及定位

  使用wireshark分析了组播出向报文的抓包,报文无丢包,但是IO 输出流量显示有burst和掉坑现象。

  波形和抓包文件分析如下图:

  后来在接收侧抓包,并分析日志,接收方没有出现丢包问题,但是有接收码流不足,导致收包不及时,业务不流畅。

  通过在系统内核发包udp_sendmsg函数打点,发现有时候有300ms+没有报文发出,说明发包线程被阻塞。

  下面是监控组播出向发包函数udp_sendmsg的打点记录日志:

__dev_xmit_skb:

78      send rate:  9 Mbps

79      send rate:  9 Mbps

80      send rate:  6 Mbps   ##有流量下降

diff_send_time_ms = 346      ##346毫秒无报文发送

81      send rate:  12 Mbps  ##有流量上升

82      send rate:  9 Mbps

83      send rate:  9 Mbps

84      send rate:  8 Mbps

diff_send_time_ms = 316

85      send rate:  7 Mbps   ##被发包线程削峰

86      send rate:  9 Mbps

87      send rate:  9 Mbps

  确认系统上有migration实时线程频繁调度,同时发现系统记账功能pacct在系统上写了近70G文件。

  其中一台设备上的 pacct文件:

  业务组播发包线程也是实时线程:

  关闭psacct服务后,内核migration线程没有再频繁调度,而且发包没有再出现300ms延迟(上图就是去掉psacct服务后的线程调度情况)。

经过几次抓包分析,出向流量很平稳,没有burst情况,业务阻塞现象消失。

关闭方法:

systemctl stop psacct.service

systemctl disable psacct.service

  为什么psacct服务引起了migration,进而影响了业务组播发包线程的延迟?

   一个猜测是,psacct进程写日志时造成cpu占用太高(当时psacct日志已经达到70G),触发了migration调度,而migration调度又导致业务

ForwardThread实时线程阻塞,引起发包抖动。

三、migration和被阻塞线程ForwardThread调度方式

migration线程简介

为什么存在migration线程?

在计算机系统中,资源使用需要均衡,因此在相同硬件上能够获得较好的星星。在Linux内核系统中,使用一些迁移内核线程来做这些事情。

内核怎么创建migration线程?

migration线程相关结构定义:

static struct smp_hotplug_thread cpu_stop_threads = {
    .store            = &cpu_stopper.thread,
    .thread_should_run    = cpu_stop_should_run,
    .thread_fn        = cpu_stopper_thread,
    .thread_comm        = "migration/%u",
    .create            = cpu_stop_create,
    .setup            = cpu_stop_unpark,
    .park            = cpu_stop_park,
    .pre_unpark        = cpu_stop_unpark,
    .selfparking        = true,
};

migration线程创建过程:

static int __init cpu_stop_init(void)
-->BUG_ON(smpboot_register_percpu_thread(&cpu_stop_threads));
    1)__smpboot_create_thread
        ## kthread_create_on_cpu 创建线程调度优先级为0,调度策略为SCHED_NORMAL
        tsk = kthread_create_on_cpu(smpboot_thread_fn, td, cpu, ht->thread_comm);  //register smpboot_thread_fn
            -->kthread_create_on_node
                -->sched_setscheduler_nocheck
    2)## cpu_stop_create 设置调度优先级为MAX_RT_PRIO - 1(99),调度策略为SCHED_FIFO
    ht->create(cpu); ## cpu_stop_create

系统中migration线程信息:

业务组播发包线程调度方式:

在我们的业务代码中,通过以下接口设置业务发包线程调度策略和优先级:

param.sched_priority = sched_get_priority_max(SCHED_FIFO)  ;   /* 这个优先级为99 */
ret = pthread_setschedparam(pthread_self(), SCHED_FIFO, &param);

 批注: 使用pthread_setschedparam函数设置可能会出现EPERM错误,这个又是另外一个问题了,后面单独开篇:)

系统中业务发包线程信息:

参考资料:

【migration介绍】https://www.systutorials.com/239971/migration-thread-works-inside-linux-kernel/

【Linux调度优先级】https://superuser.com/questions/203657/difference-between-nice-value-and-priority-in-the-top-output

原文地址:https://www.cnblogs.com/smith9527/p/12168508.html

时间: 2024-08-05 16:20:51

Linux线程调度引起的业务问题的相关文章

浅析Linux线程调度

在Linux中,线程是由进程来实现,线程就是轻量级进程( lightweight process ),因此在Linux中,线程的调度是按照进程的调度方式来进行调度的,也就是说线程是调度单元.Linux这样实现的线程的好处的之一是:线程调度直接使用进程调度就可以了,没必要再搞一个进程内的线程调度器.在Linux中,调度器是基于线程的调度策略(scheduling policy)和静态调度优先级(static scheduling priority)来决定那个线程来运行. 对于下面三种调度策略SCH

Linux 线程调度与优先级设置

转载:http://blog.csdn.net/a_ran/article/details/43759729 Linux内核的三种调度策略: 1,SCHED_OTHER 分时调度策略, 2,SCHED_FIFO实时调度策略,先到先服务.一旦占用cpu则一直运行.一直运行直到有更高优先级任务到达或自己放弃 3,SCHED_RR实时调度策略,时间片轮转.当进程的时间片用完,系统将重新分配时间片,并置于就绪队列尾.放在队列尾保证了所有具有相同优先级的RR任务的调度公平 Linux线程优先级设置   首

Linux 线程调度的优先级

Linux内核的三种调度策略: 1.SCHED_OTHER 分时调度策略 2.SCHED_FIFO实时调度策略,先到先服务.一旦占用cpu则一直运行.一直运行直到有更高优先级任务到达或自己放弃 3.SCHED_RR实时调度策略,时间片轮转.当进程的时间片用完,系统将重新分配时间片,并置于就绪队列尾.放在队列尾保证了所有具有相同优先级的RR任务的调度公平 Linux线程优先级设置: 首先,可以通过以下两个函数来获得线程可以设置的最高和最低优先级,函数中的策略即上述三种策略的宏定义: int sch

Linux 线程调度与优先级

Linux内核的三种调度策略 1,SCHED_OTHER:分时调度策略. 它是默认的线程分时调度策略,所有的线程的优先级别都是0,线程的调度是通过分时来完成的.简单地说,如果系统使用这种调度策略,程序将无法设置线程的优先级.请注意,这种调度策略也是抢占式的,当高优先级的线程准备运行的时候,当前线程将被抢占并进入等待队列.这种调度策略仅仅决定线程在可运行线程队列中的具有相同优先级的线程的运行次序. 2,SCHED_FIFO:实时调度策略,先到先服务.一旦占用cpu则一直运行.一直运行直到有更高优先

Linux 线程调度

1.线程sleep()后,会让出cpu的时间片,交由其他线程进行抢占cpu. 线程之间正常的切换是依靠时间片的. 当主线程没有结束,且其在所占有的时间片内,并没有结束自己的工作,此时,子线程将会抢占cpu时间片. 参考帖子以及下面的评论:https://blog.csdn.net/harry_lyc/article/details/6055734#reply 原文地址:https://www.cnblogs.com/xuelisheng/p/9277401.html

Linux线程调度

代码如下: 1 #include <stdio.h> 2 #include <pthread.h> 3 #include <sched.h> 4 #include <assert.h> 5 6 static int api_get_thread_policy(pthread_attr_t *attr) 7 { 8 int policy = 0; 9 int rs = 0; 10 11 rs = pthread_attr_getschedpolicy(attr

linux入门教程(六) Linux文件与目录管理

在linux中什么是一个文件的路径呢,说白了就是这个文件存在的地方,例如在上一章提到的/root/.ssh/authorized_keys 这就是一个文件的路径.如果你告诉系统这个文件的路径,那么系统就可以找到这个文件.在linux的世界中,存在着绝对路径和相对路径. 绝对路径:路径的写法一定由根目录”/”写起,例如/usr/local/mysql 这就是绝对路径. 相对路径:路径的写法不是由根目录”/”写起,例如,首先用户进入到/ 然后再进入到home ,命令为 cd /home 然后 cd

【系统知识点】linux基础&优化命令

Xshell上传下载服务器的文件: yum -y install lrzsz sysstat//安装对应软件 sz XXXX//下载 rz XXXX//上传 创建用户: Useradd vrfxie //创建用户 -c comment 指定一段注释性描述. -d 目录 指定用户主目录,如果此目录不存在,则同时使用-m选项,可以创建主目录. -g 用户组 指定用户所属的主用户组. -G 用户组,用户组 指定用户所属的附加组. -s Shell文件 指定用户的登录Shell. #可以设置为/sbin

我的Linux,我做主!

最近比较忙,一直没有更新博客的机会,今天看到这个很有吸引力的topic,就想跟大家一起聊聊,我与linux的不解之缘吧. 记得第一次听说linux,还是在上大学的时候,对于我们这些被windows"洗脑"太深人来说才知道原来世界上还有不同的操作系统,unix,unix like,linux,由于是大学的一门课程,没有太多实践的机会,老师的介绍也仅仅是照本宣科,但是那已经足够拓展了我们的视野和思路,为日后更深入的了解做了良好的铺垫,算是美好的"邂逅"吧,记得那时候业余