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还是比较高的,不适合长期开启,适合短期排查问题。

相关推荐
yuren_xia1 小时前
Spring Boot中保存前端上传的图片
前端·spring boot·后端
JohnYan4 小时前
Bun技术评估 - 04 HTTP Client
javascript·后端·bun
shangjg34 小时前
Kafka 的 ISR 机制深度解析:保障数据可靠性的核心防线
java·后端·kafka
青莳吖5 小时前
使用 SseEmitter 实现 Spring Boot 后端的流式传输和前端的数据接收
前端·spring boot·后端
我的golang之路果然有问题6 小时前
ElasticSearch+Gin+Gorm简单示例
大数据·开发语言·后端·elasticsearch·搜索引擎·golang·gin
mldong7 小时前
我的全栈工程师之路:全栈学习路线分享
前端·后端
噼里啪啦啦.8 小时前
SpringBoot统一功能处理
java·spring boot·后端
考虑考虑8 小时前
JPA自定义sql参数为空和postgresql遇到问题
spring boot·后端·spring
橘子青衫9 小时前
Java多线程编程:深入探索线程同步与互斥的实战策略
java·后端·性能优化
shengjk19 小时前
一文搞懂 python __init__.py 文件
后端