load对进程判断失效

背景

随着容器化的普及,越来越多的服务开始用容器管理,这个排查问题的方式和传统物理机有了区别。容器可以做cpu的绑定。走单独cpu的进程队列。不能直接看到进程跑的慢,load高就判定为排队的影响。

观察load

传统的方式,我们可以选择nonvoluntary_ctxt_switches的数据来作为进程切换的衡量方式,这个值越大,被切换除去的概率越大。我们下面做个实验。 云机器2core。 第一组实验我们启动sysbench来看看单个的运行。

shell 复制代码
  sysbench --threads=10 --time=300 threads run

我们观测进程的nonvoluntary_ctxt_switches指标

bash 复制代码
cat /proc/3121954/status | grep ctxt
voluntary_ctxt_switches:	2
nonvoluntary_ctxt_switches:	0

因为机器上就这么一个业务进程,可以看到没有非自愿的上下文切换。

第二组实验我们启动2个sysbench程序。再来观测nonvoluntary_ctxt_switches

bash 复制代码
cat /proc/3132823/status |grep ctxt
voluntary_ctxt_switches:	4
nonvoluntary_ctxt_switches:	3

可以看到指标上涨了。但是不多。因为任务执行很快,cpu给的时间片是充足的,这个案例能更好的说明load的影响。 我们来观测load

lua 复制代码
load average: 10.44, 5.01, 2.10

基于这个情况来看,我们的程序肯定是跑的慢了。 这里展示一下2组数据的吞吐。

第一组实验

yaml 复制代码
Throughput:
    events/s (eps):                      688.9522
    time elapsed:                        300.0107s
    total number of events:              206693

第二组实验

yaml 复制代码
Throughput:
    events/s (eps):                      340.3187
    time elapsed:                        300.0100s
    total number of events:              102099

结果符合预期,这也是我们之前排查问题的思路。我们接下来观测一下cpu绑定之后的结果。

cpu绑定

目前core有限,我们来模拟1个线程和100个线程的案例,先来看看1个线程和100个线程跑的结果。没绑定的情况。

这是单独跑的结果。

yaml 复制代码
Throughput:
    events/s (eps):                      1147.2537
    time elapsed:                        30.0003s
    total number of events:              34418

这是机器还有100个线程跑的结果

yaml 复制代码
Throughput:
    events/s (eps):                      803.9569
    time elapsed:                        30.0004s
    total number of events:              24119

可以看到数据是有下滑的。

lua 复制代码
load average: 5.26, 1.91, 0.91

load是超过2了,说明cpu已经开始排队了。 我们开始针对2个进程做隔离。这里简单来模拟直接使用cgroup。cgroup0绑定cpu0,cgroup1绑定cpu1。我们再来看结果。然后1个线程的使用cpu0跑,100个线程的使用cpu1来跑

lua 复制代码
load average: 3.41, 1.40, 0.89

load还是超过2,说明排队。

yaml 复制代码
Throughput:
    events/s (eps):                      1074.8552
    time elapsed:                        30.0003s
    total number of events:              32246
    

再来看这个结果,基本持平。 通过这个案例说明cpu绑定之后,排队之后,进程的运行并不受到load的影响。

解决方案

从上面来看,在隔离技术之下,load高并不一定带来影响。那我们应该如何去判断进程有没有被影响呢。我们想想load排队的本质cpu的调度,我们可以从cpu调度的角度,来进行分析。我们来试试观测1个线程的调度指标。

这是没有隔离的数据

rust 复制代码
     usecs               : count     distribution
         0 -> 1          : 0        |                                        |
         2 -> 3          : 25519    |********                                |
         4 -> 7          : 117937   |****************************************|
         8 -> 15         : 7792     |**                                      |
        16 -> 31         : 737      |                                        |
        32 -> 63         : 238      |                                        |
        64 -> 127        : 44       |                                        |
       128 -> 255        : 66       |                                        |
       256 -> 511        : 34       |                                        |
       512 -> 1023       : 38       |                                        |
      1024 -> 2047       : 22       |                                        |
      2048 -> 4095       : 1        |                                        |

这里有隔离的数据

rust 复制代码
     usecs               : count     distribution
         0 -> 1          : 0        |                                        |
         2 -> 3          : 61472    |****************************************|
         4 -> 7          : 47169    |******************************          |
         8 -> 15         : 2488     |*                                       |
        16 -> 31         : 538      |                                        |
        32 -> 63         : 131      |                                        |
        64 -> 127        : 41       |                                        |
       128 -> 255        : 46       |                                        |
       256 -> 511        : 44       |                                        |
       512 -> 1023       : 41       |                                        |
      1024 -> 2047       : 39       |                                        |
      2048 -> 4095       : 3        |                                        |

可以看到调度分布是不一样的。隔离了之后调度的时间花费更少一些。

总结

在有容器隔离的环境下,load高并不一定会带来影响,一个一个来排查有没有设置隔离,相对比较麻烦,这里可以切换成cpu调度的观测,目前overhead还是比较高的,不适合长期开启,适合短期排查问题。

相关推荐
拾贰_C22 分钟前
【SpringBoot】前后端联动实现条件查询操作
java·spring boot·后端
catchadmin2 小时前
PHP 快速集成 ChatGPT 用 AI 让你的应用更聪明
人工智能·后端·chatgpt·php
callJJ6 小时前
从 0 开始理解 Spring 的核心思想 —— IoC 和 DI(2)
java·开发语言·后端·spring·ioc·di
你的人类朋友8 小时前
JWT的组成
后端
北风朝向9 小时前
Spring Boot参数校验8大坑与生产级避坑指南
java·spring boot·后端·spring
canonical_entropy10 小时前
一份关于“可逆计算”的认知解码:从技术细节到哲学思辨的完整指南
后端·低代码·deepseek
趙卋傑10 小时前
项目发布部署
linux·服务器·后端·web
数据知道11 小时前
Go基础:Go语言能用到的常用时间处理
开发语言·后端·golang·go语言
不爱编程的小九九12 小时前
小九源码-springboot048-基于spring boot心理健康服务系统
java·spring boot·后端
龙茶清欢12 小时前
Spring Boot 应用启动组件加载顺序与优先级详解
java·spring boot·后端·微服务