SYSCPU高是什么原因造成的?主要有两种可能性:
1.contextswitch不高,但是它在内核态旋转,导致SYSCPU高。
2.contextswitch高,超过每秒200K,有时超过1 M,过多的上下文切换导致SYSCPU高。
下面就这两种情况逐一分析。
对于某些资源,用户进程(或线程)通过执行系统调试或由于中断而进入内核。一般来说,申请这些资源的执行时间很短。当发生资源争用时,采用睡眠和唤醒机制的代价很高,所以往往采用内核态旋转的策略。
比如申请内存时没有空闲内存可用或者页面中断时,进程或线程可能会先进行内存回收,然后在内核模式下进行内存分配,但系统内存是共享资源,分配和回收时需要锁保护。当多个进程(或线程)同时回收和分配内存时,它将在内核状态下旋转。
当可用内存不足时,可能会发生这种情况。典型症状:
MySQLrunning高,但是系统qps和tps下降,系统空闲内存不足;或者当系统空闲内存充足,但启用了numa内存分配策略,部分节点空闲内存很少,系统contextswitch不高时。MySQLInnoDB的mutex和RWlock找不到等待信息。sar-B显示pgscand生成
sar-B输出中,pgscank表示内核线程kswapd回收内存,k表示内核;Pgscand表示一个用户进程或线程直接回收内存,d表示直接。
解决方案:确保系统有足够的可用内存,并且NUMA环境要求每个节点都有足够的可用内存。
因为Linux系统会尽量使用空闲内存,一个长时间运行的Linux系统通常空闲内存很少,而filecache内存很多,但是Linux并不直接提供参数来控制filecache占用多少,如何预留足够的空闲内存来满足突如其来的内存需求?
在这方面,Linux2.3.32内核增加了一个新的参数vm.extra_free_kbytes来控制空闲内存。
关于系统空闲内存有两个重要的参数:vm.min_free_kbytes和vm.extra_free_kbytes(2.6.32)。
Vm.min_free_kbytes:系统为内核保留的内存。
这个值决定了/proc/zoneinfo中区域的最小值。当系统空闲内存小于该值时,kswapd将回收内存,直到空闲内存达到/proc/zoneinfo中的高值。
当用户进程或线程分配内存或发生缺页中断时,空闲内存小于vm.min_free_kbytes,内存将被直接回收(pgscand)并在用户线程的上下文中分配。
Vm.extra_free_kbytes:系统为应用程序保留的空闲内存。
该值决定了/proc/zoneinfo中Normalzone的低值。当系统可用内存小于VM . min _ free _ kbytes VM . extra _ free _ kbytes时,kswapd将开始回收内存,直到可用内存达到/proc/zoneinfo中的高值。
这个额外的vm.extra_free_kbytes是在应用程序突然需要内存的时候使用的,避免在急需内存的时候pgscand或者kswapd不及时的回收内存。
vm.extra_free_kbytes的分配有多合适?一般需要1-2秒才能满足流量高峰期的内存需求。空闲内存减少后,kswapd进程会在后台回收内存,一般512M-2G就能满足要求。
在MySQL中,互斥和RWlock引起的contextswitch一般体现在ShowglobalStatus、ShowEngineNondButex、ShowEngineNondBatus、Performance _ Schema等。对于不同的互斥和RWlock等待,可以采取不同的优化措施。
除了MySQL的互斥和RWlock,还发现MySQL外的互斥竞争导致contextswitch高。
典型症状:
MySQLrunning高,但是系统qps和tps低,系统contextswitch很高。超过200K每秒,MySQL内存中没有互斥体和RWlock的竞争信息。时间戳字段出现在具有高SYSCPU和低USERCPU并发执行的SQL中。MySQL的time_zone设置为system
MySQL在访问每一行的时候都会做这个时区转换。转换后会释放互斥体,所有等待互斥体的线程都会被唤醒。结果,只有一个线程会成功持有互斥体,其余的会再次休眠。这将导致非常高的contextswitch但是低的qps,并且系统吞吐量将急剧下降。
解决方法:设置time_zone=' 8:00 '这样就不会访问Linux系统的时区,直接转换,避免了互斥问题。
此外,对于自旋消耗,可以使用MySQL配置变量中的innodb_spin_wait_delay和innodb_sync_spin_loops进行微调。
上一篇:两面包夹芝士是什么意思网络用语
下一篇:攻无不克战无不胜的意思解释是什么