Linux内核CPU使用偏高排查

问题

  • 内核cpu使用过高

观测

  • top查看负载。系统中断si和系统内核sy占用cpu偏高
top - 13:23:41 up 225 days,  9:53,  2 users,  load average: 2.80, 3.06, 2.39
Tasks: 211 total,   1 running, 210 sleeping,   0 stopped,   0 zombie
%Cpu(s): 23.4 us, 10.6 sy,  0.0 ni, 56.5 id,  0.1 wa,  0.0 hi,  9.4 si,  0.0 st
KiB Mem :  8008660 total,   203620 free,  1213136 used,  6591904 buff/cache
KiB Swap:        0 total,        0 free,        0 used.  6367804 avail Mem
  • iostat 查看磁盘io情况,正常
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          23.08    0.00   18.61    0.25    0.00   58.06

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
vda               0.00    13.00    0.00   12.00     0.00  2756.00   459.33     0.07    5.83    0.00    5.83   1.00   1.20
  • vmstat -w 1 10 查看总体资源。中断in和上下文切换cs偏高。一般而言应该是I/O调用导致的频繁上下文切换,此服务器是处理业务的,存在大量的网络调用
$ vmstat -w 1 10
procs -----------------------memory---------------------- ---swap-- -----io---- -system-- --------cpu--------
 r  b         swpd         free         buff        cache   si   so    bi    bo   in   cs  us  sy  id  wa  st
 2  0            0       206204       313168      6278648    0    0     0   455    0    0  13  11  76   0   0
 1  0            0       206784       313168      6278648    0    0     0  2756 40875 33178  24  19  57   0   0
 3  0            0       206080       313168      6278648    0    0     0  2852 39429 32818  20  19  61   0   0
 0  0            0       206852       313168      6278648    0    0     0  2756 40426 32924  24  22  53   0   0
 0  0            0       205656       313168      6278648    0    0     0  2756 40709 33823  23  18  58   0   0
 1  0            0       202956       313168      6278648    0    0     0  2764 43104 35866  24  19  56   0   0
 1  0            0       205952       313168      6278652    0    0     0  2756 41111 34041  23  18  59   0   0
 1  0            0       203988       313168      6278652    0    0     0  2832 38512 32345  21  18  61   0   0
 2  0            0       204532       313168      6278652    0    0     0  2756 41736 35027  23  20  57   0   0
 0  0            0       206172       313168      6278652    0    0     0  2864 41838 34968  22  19  59   0   0
  • 查看网络层协议调用情况。nginx和php-fpm之间的交互是采用AF_UNIX域的,剩下的AF_INET为网络访问,这个比较多
bpftrace sofamily.bt

@accept[nginx, 2, AF_INET]: 116
@accept[php-fpm, 1, AF_UNIX]: 10493

@connect[CmsGoAgent.linu, 2, AF_INET]: 6
@connect[php-fpm, 0, AF_UNSPEC]: 8
@connect[php-fpm, 10, AF_INET6]: 8
@connect[php-fpm, 1, AF_UNIX]: 190
@connect[nginx, 1, AF_UNIX]: 10574
@connect[php-fpm, 2, AF_INET]: 48323
  • 采用bpf工具
  • 查看传输层协议情况。
    • UDP使用较多,服务器没有使用UDP端口的自研应用,那么一般而言就是DNS服务了
    bpftrace soprotocol.bt
    
    @connect[systemd-cgroups, 0, IPPROTO_IP, UNIX]: 2
    @connect[CmsGoAgent.linu, 0, IPPROTO_IP, UNIX]: 3
    @connect[dbus-daemon, 0, IPPROTO_IP, UNIX]: 4
    @connect[aliyun-service, 6, IPPROTO_TCP, TCP]: 7
    @connect[ps, 0, IPPROTO_IP, UNIX]: 8
    @connect[CmsGoAgent.linu, 6, IPPROTO_TCP, TCP]: 10
    @connect[crond, 0, IPPROTO_IP, UNIX]: 10
    @connect[aliyun-service, 17, IPPROTO_UDP, UDP]: 12
    @connect[CmsGoAgent.linu, 17, IPPROTO_UDP, UDP]: 20
    @connect[php-fpm, 17, IPPROTO_UDP, UDPv6]: 95
    @connect[nginx, 6, IPPROTO_TCP, TCP]: 717
    @connect[nginx, 0, IPPROTO_IP, UNIX]: 42835
    @connect[php-fpm, 0, IPPROTO_IP, UNIX]: 43514
    @connect[php-fpm, 6, IPPROTO_TCP, TCP]: 66381
    @connect[php-fpm, 17, IPPROTO_UDP, UDP]: 127774
    
  • tcpdump 抓包查看UDP的报文。显示主要为mysql和redis的dns解析,但是redis采用的是长连接,不应该有这么多,redis由多台,但是只有一台频繁解析,这很疑惑
# 53为dns端口
tcpdump -c 100000 port 53 > tcpdump.out
# head tcpdump.out
13:10:54.525159 IP server001.40657 > 100.100.2.136.domain: 49971+ A? mysql.test001.com. (61)
13:10:54.525248 IP 100.100.2.136.domain > server001.40657: 49971* 1/0/0 A 172.17.191.188 (77)
13:10:54.525301 IP server001.58239 > 100.100.2.136.domain: 41535+ AAAA? mysql.test001.com. (61)

# cat tcpdump.out|awk '{print $8,$9}'|sort |uniq -c|sort -rn
36020 mysql.test001.com. (61)
24197 (140)
18010 A 172.17.191.188
 6430 mysql.test002. (61)
 5938 redis.test001. (61)
 3215 A 172.17.191.191
 2969 A 172.17.191.192
 1486 es.test001. (68)
  743 A 172.17.142.150
  • 排查代码发现只有一处采用了短连接,但是那是专供脚本使用的,采用单例,如果有大量的dns解析,那么应该每台redis服务器的DNS解析都会不少。改为长连接,上线测试了一下,redis的DNS解析没有降低,不是代码的问题,还原代码。
  • 采用tcpdump抓包redis 解析很多的服务器内容看看效果。先找到ip,抓指定ip的包,看到了PHPREDIS_SESSION,这就不奇怪了,phpsession使用redis存储的(dns解析最多的那台redis服务器),是短连接,所以会有大量的dns解析查询。
# grep -B3 'redis.test001' tcpdump.out|head -10
...
13:10:54.535689 IP server001.40281 > 100.100.2.136.domain: 59941+ A? redis.test001. (61)
13:10:54.535805 IP 100.100.2.136.domain > server001.40281: 59941* 1/0/0 A 172.17.191.192 (77)
...

tcpdump -c 100  dst host 172.17.191.192 and port 6379 -xx
...
14:03:10.361710 IP server001.57342 > 172.17.191.192.6379: Flags [P.], seq 37:100, ack 6, win 229, length 63: RESP "GET" "PHPREDIS_SESSION:k3cr2f5mooqsddd9vlbj6pqv2e"
  • 对于Mysql的解析很多,这是框架的问题,首先mysql采用的短连接,而且每一次建立请求的时候都会建立Mysql连接,但是数据其实从redis缓存就获取到了。解决办法是修改mysql连接机制,还是使用短连接,但是MySQL建立需要在要查询SQL时才建立,而不是每一个获取数据都建立MySQL连接,因为很多请求其实数据直接来源于redis。
  • 减少无效TCP连接建立,也就减少了一部分的系统调用,从而降低负载。
  • 把mysql的无效连接取消后,中断和进程上下文切换有所下降20%,CPU变化不是特别明显,load有所下降,3.5->2.5

小包请求问题

  • 问题是由于大量的小数据包导致的内核CPU消耗,系统存在大量的redis请求,网络包很小,例如统计信息等。解决办法就是减少小包获取,尽量合并请求,一次获取多条数据。
  • 负载均衡服务器每个包大小在1000B以上,而work1的包大小在200B左右,内核消耗明显是work1偏高。
  • perf分析
  • 小包
  • 大包
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux系统CPU使用率过高可能是由于多种原因引起的,以下是一些常见的解决方法: 1. 查找占用CPU资源过高的进程或服务:可以使用top、htop或ps等命令查看当前系统的进程和其CPU占用情况,找到占用CPU较高的进程或服务。 2. 结束不必要的进程:根据上一步的结果,将占用CPU较高且不必要的进程或服务通过kill命令结束掉。可以使用kill -9 <进程ID>命令强制结束进程。 3. 调整CPU调度策略:可以通过nice和renice命令调整进程的优先级,即调整进程的CPU使用权。更高的进程优先级会占用更多的CPU资源。 4. 检查系统负载情况:通过uptime或top命令查看系统负载情况,如果系统负载过高,说明系统资源紧张,可能需要增加硬件资源或升级服务器。 5. 优化代码或服务:如果是自己开发的应用程序或服务导致CPU占用过高,可以对代码进行优化,减少不必要的循环或对数据库的频繁访问等。 6. 升级内核和软件:对于一些已知存在性能问题的内核或软件,可以考虑升级到更稳定与高效的版本。 7. 考虑使用更高性能的硬件:如果系统CPU使用率一直很高,可能是因为硬件性能不足,可以考虑升级CPU或增加内存。 总之,解决Linux系统CPU使用率过高的问题需要根据具体情况来进行分析和解决,可以通过查找占用资源过高的进程、优化代码或服务、调整系统配置等方式来减少CPU负载。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值