erlang 调度器CPU利用率低排查

-问题起因

  近期线上一组服务中,个别节点服务器CPU使用率很低,只有其他1/4。排除业务不均,曾怀疑是系统top统计错误,从Erlang调度器的利用率调查 找到通过erlang:statistics(scheduler_wall_time) 查看服务器CPU低的机器调度器实际的CPU利用率很高接近100%,而其他机器都不到30%。

分析不同业务服务,发现只有在node 中进程数采用调度器CPU利用低这个问题。

-Whatsapp 案例 

  erlang方面能找到案例不多,幸运的发现whatsapp 给出了类似案例详细的分析:

http://highscalability.com/blog/2014/2/26/the-whatsapp-architecture-facebook-bought-for-19-billion.html

First bottleneck showed up at 425K. System ran into a lot of contention. Work stopped.

Instrumented the scheduler to measure how much useful work is being done, or sleeping, or spinning.

Under load it started to hit sleeping locks so 35-45% CPU was being used across the system but the schedulers are at 95% utilization.

whatsapp 在单机425K连接时遇到瓶颈,虚机实际只35~45%cpu却给系统造成了95%的cpu。

文中没有提到具体细节,关于scheduler:

1. +swt low  Set the scheduler wake up threshold to low because schedulers would go to sleep and would never wake up

2. 设置进程优先级为实时  Run BEAM at real-time priority so that other things like cron jobs don’t interrupt schedule. Prevents glitches that would cause backlogs of important user traffic

3. 禁用spin( patch beam)Patch to dial down spin counts so the scheduler wouldn’t spin,+ssct 1 (via patch; scheduler spin count)

-工具分析

  通过微博私信,请教了下郑思瑶,推荐VTune分析,推测是大量进程时调度器消耗过大。

  通过Intel 官方网站,填写注册信息,会立即回复邮件下载地址,并给30天试用期。

  速度很慢,建议挂着VPN下载;VTune 的linux版本命令行模式使用很简单:

tar -zxf vtune_amplifier_xe_2015.tar.gz

cd vtune_amplifier_xe_2015

./install.sh

cd /opt/intel/vtune_amplifier_xe_2015.1.0.367959/

 source amplxe-vars.sh

 amplxe-cl -collect lightweight-hotspots -run-pass-thru=--no-altstack -target-pid=1575

 amplxe-cl -report hotspots

  可直接线上执行,不影响服务正常运行,得到如下结果:

Summary
-------
Elapsed Time:       19.345
CPU Time:           182.023
Average CPU Usage:  9.155
CPI Rate:           1.501

Function                                     Module              CPU Time:Self
-------------------------------------------  ------------------  -------------
sched_spin_wait                              beam.smp                   72.754
raw_local_irq_enable                         vmlinux                    19.282
process_main                                 beam.smp                   10.476
ethr_native_atomic32_read                    beam.smp                    8.337
[email protected]0xffffffff8100af60                      vmlinux                     3.007
__pthread_mutex_lock                         libpthread-2.12.so          2.342
raw_local_irq_restore                        vmlinux                     1.973
__sched_yield                                libc-2.12.so                1.913
pthread_mutex_unlock                         libpthread-2.12.so          1.553
__audit_syscall_exit                         vmlinux                     1.192
system_call                                  vmlinux                     1.156
erts_thr_yield                               beam.smp                    1.114
handle_delayed_dealloc                       beam.smp                    0.977
update                                       beam.smp                    0.828
raw_local_irq_enable                         vmlinux                     0.780

可以看到sched_spin_wait占用了 40% 的CPU时间

#define ERTS_SCHED_SPIN_UNTIL_YIELD 100
2121 static erts_aint32_t
2122 sched_spin_wait(ErtsSchedulerSleepInfo *ssi, int spincount)
2123 {
2124     int until_yield = ERTS_SCHED_SPIN_UNTIL_YIELD;
2125     int sc = spincount;
2126     erts_aint32_t flgs;
2127
2128     do {
2129     flgs = erts_smp_atomic32_read_acqb(&ssi->flags);
2130     if ((flgs & (ERTS_SSI_FLG_SLEEPING|ERTS_SSI_FLG_WAITING))
2131         != (ERTS_SSI_FLG_SLEEPING|ERTS_SSI_FLG_WAITING)) {
2132         break;
2133     }
2134     ERTS_SPIN_BODY;
2135     if (--until_yield == 0) {
2136         until_yield = ERTS_SCHED_SPIN_UNTIL_YIELD;
2137         erts_thr_yield();
2138     }
2139     } while (--sc > 0);
2140     return flgs;
2141 }

  默认spincount = 10000,但每次都有atom 读操作,原子操作一般几十到几百CPU周期,导致这个忙等待 实际执行完的话会很长。

  同时也找到对应的配置:

  +sbwt none|very_short|short|medium|long|very_longSet scheduler busy wait threshold. Default is medium. The threshold determines how long schedulers should busy wait when running out of work before going to sleep.

启动参数:+sbwt none 即可见spin彻底关掉,而不必像whatsapp patch beam解决。

时间: 2024-11-05 00:24:01

erlang 调度器CPU利用率低排查的相关文章

MongoDB CPU 利用率高排查

MongoDB CPU 利用率高,怎么破? 经常有用户咨询「MongoDB CPU 利用率很高,都快跑满了」,应该怎么办? 遇到这个问题,99.9999% 的可能性是「用户使用上不合理导致」,本文主要介绍从应用的角度如何排查 MongoDB CPU 利用率高的问题 Step1: 分析数据库正在执行的请求 用户可以通过 Mongo Shell 连接,并执行 db.currentOp() 命令,能看到数据库当前正在执行的操作,如下是该命令的一个输出示例,标识一个正在执行的操作.重点关注几个字段 cl

YARN的capacity调度器主要配置分析

yarn中一个基本的调度单元是队列. yarn的内置调度器: 1.FIFO先进先出,一个的简单调度器,适合低负载集群.2.Capacity调度器,给不同队列(即用户或用户组)分配一个预期最小容量,在每个队列内部用层次化的FIFO来调度多个应用程序.3.Fair公平调度器,针对不同的应用(也可以为用户或用户组),每个应用属于一个队列,主旨是让每个应用分配的资源大体相当.(当然可以设置权重),若是只有一个应用,那集群所有资源都是他的. 适用情况:共享大集群.队列之间有较大差别. capacity调度

记一次erlang 节点CPU严重波动排查过程

新服务上线后观察到,CPU在10 ~ 70%间波动严重,但从每秒业务计数器看业务处理速度很平均. 接下来是排查步骤: 1. dstat -tam 大概每10s一个周期,网络流量开始变得很小,随后突然增大,CPU也激增. 网络流量变化和从性能计数器结果上并不符合,服务相关业务较为复杂,先找出那个业务占用网络流量. 2. iftop 找出流量最大的几个目标IP,并且周期的流量变为0随后激增. 通过IP 知道是外部http接口地址,因为接口调用是异步进行的,性能计算是执行开始记录的,而不是结束记录,因

朴素的UNIX之-调度器细节

0.多进程调度的本质 我们都知道UNIX上有一个著名的nice调用,何谓nice,当然是"好"了,常规的想法是nice值越大越好,实际上,nice值越好,自己的优先级越低,那么为何不用badness呢? 事实上,如果我们理解了操作系统多进程调度系统是一个"利他"系统,这个问题就不是个问题了.nice当然还是好,不是对自己好,而是对别人好.利他系统 是一个人人为我我为人人的系统,类似还有TCP流量控制和拥塞控制,人类的宗教社会组织等等,利他系统都有一个负反馈机制,让波

Linux调度器 - deadline调度器

一.概述 实时系统是这样的一种计算系统:当事件发生后,它必须在确定的时间范围内做出响应.在实时系统中,产生正确的结果不仅依赖于系统正确的逻辑动作,而且依赖于逻辑动作的时序.换句话说,当系统收到某个请求,会做出相应的动作以响应该请求,想要保证正确地响应该请求,一方面逻辑结果要正确,更重要的是需要在最后期限(deadline)内作出响应.如果系统未能在最后期限内进行响应,那么该系统就会产生错误或者缺陷.在多任务操作系统中(如Linux),实时调度器(realtime scheduler)负责协调实时

# IT明星不是梦 # kubernetes调度器学习基础概览

scheudler是kubernetes中的核心组件,负责为用户声明的pod资源选择合适的node,同时保证集群资源的最大化利用,这里先介绍下资源调度系统设计里面的一些基础概念 基础任务资源调度 基础的任务资源调度通常包括三部分: 角色类型 功能 node node负责具体任务的执行,同时对包汇报自己拥有的资源 resource manager 汇总当前集群中所有node提供的资源,供上层的scheduler的调用获取,同时根据node汇报的任务信息来进行当前集群资源的更新 scheduler

kubernetes调度及调度器性能调优

kubernetes调度器在kubernetes中,调度指的是将新生成的pod调度到合适的Node节点上,然后Node上对应的kubelet才能运行pod. 1.调度概述调度器通过kubernetes的watch机制来发现新生成的且未调度到Node上的pod.调度器会将发现的每一个未调度的pod调度到合适的Node上运行,调度器会使用以下所述的调度原则来做出调度选择. 2.kube-schedulerkube-sceduler时kubernetes集群中默认调度器,并且是集群控制面的一部分,ku

Linux 调度器发展简述

引言 进程调度是操作系统的核心功能.调度器只是是调度过程中的一部分,进程调度是非常复杂的过程,需要多个系统协同工作完成.本文所关注的仅为调度器,它的主要工作是在所有 RUNNING 进程中选择最合适的一个.作为一个通用操作系统,Linux 调度器将进程分为三类: 交互式进程 此类进程有大量的人机交互,因此进程不断地处于睡眠状态,等待用户输入.典型的应用比如编辑器 vi.此类进程对系统响应时间要求比较高,否则用户会感觉系统反应迟缓. 批处理进程 此类进程不需要人机交互,在后台运行,需要占用大量的系

Linux IO 调度器

Linux IO Scheduler(Linux IO 调度器) 每个块设备或者块设备的分区,都对应有自身的请求队列(request_queue),而每个请求队列都可以选择一个I/O调度器来协调所递交的request.I/O调度器的基本目的是将请求按照它们对应在块设备上的扇区号进行排列,以减少磁头的移动,提高效率.每个设备的请求队列里的请求将按顺序被响应.实际上,除了这个队列,每个调度器自身都维护有不同数量的队列,用来对递交上来的request进行处理,而排在队列最前面的request将适时被移