- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Linux 性能优化的全景指南,可能都在这里了由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
高并发和响应快对应着性能优化的两个核心指标:吞吐和延时 。
性能问题的本质就是系统资源已经到达瓶颈,但请求的处理还不够快,无法支撑更多的请求。性能分析实际上就是找出应用或系统的瓶颈,设法去避免或缓解它们.
对于不同的性能问题要选取不同的性能分析工具。下面是常用的Linux Performance Tools以及对应分析的性能问题类型.
平均负载 :单位时间内,系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数。它和我们传统意义上理解的CPU使用率并没有直接关系.
其中不可中断进程是正处于内核态关键流程中的进程(如常见的等待设备的I/O响应)。不可中断状态实际上是系统对进程和硬件设备的一种保护机制.
实际生产环境中将系统的平均负载监控起来,根据历史数据判断负载的变化趋势。当负载存在明显升高趋势时,及时进行分析和调查。当然也可以当设置阈值(如当平均负载高于CPU数量的70%时) 。
现实工作中我们会经常混淆平均负载和CPU使用率的概念,其实两者并不完全对等:
平均负载高时可能是 CPU 密集型进程导致,也可能是 I/O 繁忙导致。具体分析时可以结合 mpstat/pidstat 工具辅助分析负载来源.
CPU 上下文切换,就是把前一个任务的 CPU 上下文(CPU 寄存器和 PC)保存起来,然后加载新任务的上下文到这些寄存器和程序计数器,最后再跳转到程序计数器所指的位置,运行新任务。其中,保存下来的上下文会存储在系统内核中,待任务重新调度执行时再加载,保证原来的任务状态不受影响.
按照任务类型,CPU 上下文切换分为:
Linux 进程按照等级权限将进程的运行空间分为内核空间和用户空间。从用户态向内核态转变时需要通过系统调用来完成.
一次系统调用过程其实进行了两次 CPU 上下文切换:
系统调用过程中并不会涉及虚拟内存等进程用户态资源,也不会切换进程。和传统意义上的进程上下文切换不同。因此系统调用通常称为特权模式切换.
进程是由内核管理和调度的,进程上下文切换只能发生在内核态。因此相比系统调用来说,在保存当前进程的内核状态和CPU寄存器之前,需要先把该进程的虚拟内存,栈保存下来。再加载新进程的内核态后,还要刷新进程的虚拟内存和用户栈.
进程只有在调度到CPU上运行时才需要切换上下文,有以下几种场景:CPU时间片轮流分配,系统资源不足导致进程挂起,进程通过sleep函数主动挂起,高优先级进程抢占时间片,硬件中断时CPU上的进程被挂起转而执行内核中的中断服务.
线程上下文切换分为两种:
同进程的线程切换消耗资源较少,这也是多线程的优势.
中断上下文切换并不涉及到进程的用户态,因此中断上下文只包括内核态中断服务程序执行所必须的状态(CPU寄存器,内核堆栈,硬件中断参数等).
中断处理优先级比进程高,所以中断上下文切换和进程上下文切换不会同时发生.
通过 vmstat 可以查看系统总体的上下文切换情况 。
vmstat 5 #每隔5s输出一组数据 procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 1 0 0 103388 145412 511056 0 0 18 60 1 1 2 1 96 0 0 0 0 0 103388 145412 511076 0 0 0 2 450 1176 1 1 99 0 0 0 0 0 103388 145412 511076 0 0 0 8 429 1135 1 1 98 0 0 0 0 0 103388 145412 511076 0 0 0 0 431 1132 1 1 98 0 0 0 0 0 103388 145412 511076 0 0 0 10 467 1195 1 1 98 0 0 1 0 0 103388 145412 511076 0 0 0 2 426 1139 1 0 99 0 0 4 0 0 95184 145412 511108 0 0 0 74 500 1228 4 1 94 0 0 0 0 0 103512 145416 511076 0 0 0 455 723 1573 12 3 83 2 0
要查看每个进程的详细情况,需要使用pidstat来查看每个进程上下文切换情况.
pidstat -w 5 14时51分16秒 UID PID cswch/s nvcswch/s Command 14时51分21秒 0 1 0.80 0.00 systemd 14时51分21秒 0 6 1.40 0.00 ksoftirqd/0 14时51分21秒 0 9 32.67 0.00 rcu_sched 14时51分21秒 0 11 0.40 0.00 watchdog/0 14时51分21秒 0 32 0.20 0.00 khugepaged 14时51分21秒 0 271 0.20 0.00 jbd2/vda1-8 14时51分21秒 0 1332 0.20 0.00 argusagent 14时51分21秒 0 5265 10.02 0.00 AliSecGuard 14时51分21秒 0 7439 7.82 0.00 kworker/0:2 14时51分21秒 0 7906 0.20 0.00 pidstat 14时51分21秒 0 8346 0.20 0.00 sshd 14时51分21秒 0 20654 9.82 0.00 AliYunDun 14时51分21秒 0 25766 0.20 0.00 kworker/u2:1 14时51分21秒 0 28603 1.00 0.00 python3
vmstat 1 1 #新终端观察上下文切换情况 此时发现cs数据明显升高,同时观察其他指标: r列:远超系统CPU个数,说明存在大量CPU竞争 us和sy列:sy列占比80%,说明CPU主要被内核占用 in列:中断次数明显上升,说明中断处理也是潜在问题
说明运行/等待CPU的进程过多,导致大量的上下文切换,上下文切换导致系统的CPU占用率高.
pidstat -w -u 1 #查看到底哪个进程导致的问题
从结果中看出是 sysbench 导致 CPU 使用率过高,但是 pidstat 输出的上下文次数加起来也并不多。分析 sysbench 模拟的是线程的切换,因此需要在 pidstat 后加 -t 参数查看线程指标.
另外对于中断次数过多,我们可以通过 /proc/interrupts 文件读取.
watch -d cat /proc/interrupts
发现次数变化速度最快的是重调度中断(RES),该中断用来唤醒空闲状态的CPU来调度新的任务运行。分析还是因为过多任务的调度问题,和上下文切换分析一致.
某个应用的CPU使用率达到100%,怎么办?
Linux作为多任务操作系统,将CPU时间划分为很短的时间片,通过调度器轮流分配给各个任务使用。为了维护CPU时间,Linux通过事先定义的节拍率,触发时间中断,并使用全局变了jiffies记录开机以来的节拍数。时间中断发生一次该值+1. 。
CPU使用率,除了空闲时间以外的其他时间占总CPU时间的百分比。可以通过/proc/stat中的数据来计算出CPU使用率。因为/proc/stat时开机以来的节拍数累加值,计算出来的是开机以来的平均CPU使用率,一般意义不大。可以间隔取一段时间的两次值作差来计算该段时间内的平均CPU使用率。性能分析工具给出的都是间隔一段时间的平均CPU使用率,要注意间隔时间的设置.
CPU使用率可以通过top 或 ps来查看。分析进程的CPU问题可以通过perf,它以性能事件采样为基础,不仅可以分析系统的各种事件和内核性能,还可以用来分析指定应用程序的性能问题.
perf top / perf record / perf report (-g 开启调用关系的采样) 。
sudo docker run --name nginx -p 10000:80 -itd feisky/nginx sudo docker run --name phpfpm -itd --network container:nginx feisky/php-fpm ab -c 10 -n 100 http://XXX.XXX.XXX.XXX:10000/ #测试Nginx服务性能
发现此时每秒可承受请求给长少,此时将测试的请求数从100增加到10000。在另外一个终端运行top查看每个CPU的使用率。发现系统中几个php-fpm进程导致CPU使用率骤升.
接着用perf来分析具体是php-fpm中哪个函数导致该问题.
perf top -g -p XXXX #对某一个php-fpm进程进行分析
发现其中 sqrt 和 add_function 占用 CPU 过多, 此时查看源码找到原来是sqrt中在发布前没有删除测试代码段,存在一个百万次的循环导致。将该无用代码删除后发现nginx负载能力明显提升 。
sudo docker run --name nginx -p 10000:80 -itd feisky/nginx:sp sudo docker run --name phpfpm -itd --network container:nginx feisky/php-fpm:sp ab -c 100 -n 1000 http://XXX.XXX.XXX.XXX:10000/ #并发100个请求测试
实验结果中每秒请求数依旧不高,我们将并发请求数降为5后,nginx负载能力依旧很低.
此时用top和pidstat发现系统CPU使用率过高,但是并没有发现CPU使用率高的进程.
出现这种情况一般时我们分析时遗漏的什么信息,重新运行top命令并观察一会。发现就绪队列中处于Running状态的进行过多,超过了我们的并发请求次数5. 再仔细查看进程运行数据,发现nginx和php-fpm都处于sleep状态,真正处于运行的却是几个stress进程.
下一步就利用pidstat分析这几个stress进程,发现没有任何输出。用ps aux交叉验证发现依旧不存在该进程。说明不是工具的问题。再top查看发现stress进程的进程号变化了,此时有可能时以下两种原因导致:
可以通过pstree来查找 stress 的父进程,找出调用关系.
pstree | grep stress
发现是php-fpm调用的该子进程,此时去查看源码可以看出每个请求都会调用一个stress命令来模拟I/O压力。之前top显示的结果是CPU使用率升高,是否真的是由该stress命令导致的,还需要继续分析。代码中给每个请求加了verbose=1的参数后可以查看stress命令的输出,在中断测试该命令结果显示stress命令运行时存在因权限问题导致的文件创建失败的bug.
此时依旧只是猜测,下一步继续通过perf工具来分析。性能报告显示确实时stress占用了大量的CPU,通过修复权限问题来优化解决即可.
RRunning/Runnable,表示进程在CPU的就绪队列中,正在运行或者等待运行; 。
DDisk Sleep,不可中断状态睡眠,一般表示进程正在跟硬件交互,并且交互过程中不允许被其他进程中断; 。
ZZombie,僵尸进程,表示进程实际上已经结束,但是父进程还没有回收它的资源; 。
SInterruptible Sleep,可中断睡眠状态,表示进程因为等待某个事件而被系统挂起,当等待事件发生则会被唤醒并进入R状态; 。
IIdle,空闲状态,用在不可中断睡眠的内核线程上。该状态不会导致平均负载升高; 。
TStop/Traced,表示进程处于暂停或跟踪状态(SIGSTOP/SIGCONT, GDB调试); 。
XDead,进程已经消亡,不会在top/ps中看到.
对于不可中断状态,一般都是在很短时间内结束,可忽略。但是如果系统或硬件发生故障,进程可能会保持不可中断状态很久,甚至系统中出现大量不可中断状态,此时需注意是否出现了I/O性能问题.
僵尸进程一般多进程应用容易遇到,父进程来不及处理子进程状态时子进程就提前退出,此时子进程就变成了僵尸进程。大量的僵尸进程会用尽PID进程号,导致新进程无法建立.
sudo docker run --privileged --name=app -itd feisky/app:iowait ps aux | grep '/app'
可以看到此时有多个app进程运行,状态分别时Ss+和D+。其中后面s表示进程是一个会话的领导进程,+号表示前台进程组.
其中进程组表示一组相互关联的进程,子进程是父进程所在组的组员。会话指共享同一个控制终端的一个或多个进程组.
用top查看系统资源发现:1)平均负载在逐渐增加,且1分钟内平均负载达到了CPU个数,说明系统可能已经有了性能瓶颈;2)僵尸进程比较多且在不停增加;3)us和sys CPU使用率都不高,iowait却比较高;4)每个进程CPU使用率也不高,但有两个进程处于D状态,可能在等待IO.
分析目前数据可知:iowait过高导致系统平均负载升高,僵尸进程不断增长说明有程序没能正确清理子进程资源.
用dstat来分析,因为它可以同时查看CPU和I/O两种资源的使用情况,便于对比分析.
dstat 1 10 #间隔1秒输出10组数据
可以看到当wai(iowait)升高时磁盘请求read都会很大,说明iowait的升高和磁盘的读请求有关。接下来分析到底时哪个进程在读磁盘.
之前 Top 查看的处于 D 状态的进程号,用 pidstat -d -p XXX 展示进程的 I/O 统计数据。发现处于 D 状态的进程都没有任何读写操作。在用 pidstat -d 查看所有进程的 I/O统计数据,看到 app 进程在进行磁盘读操作,每秒读取 32MB 的数据。进程访问磁盘必须使用系统调用处于内核态,接下来重点就是找到app进程的系统调用.
报错没有权限,因为已经时 root 权限了。所以遇到这种情况,首先要检查进程状态是否正常。ps 命令查找该进程已经处于Z状态,即僵尸进程.
这种情况下top pidstat之类的工具无法给出更多的信息,此时像第5篇一样,用 perf record -d 和 perf report 进行分析,查看app进程调用栈.
看到 app 确实在通过系统调用 sys_read() 读取数据,并且从 new_sync_read 和 blkdev_direct_IO 看出进程时进行直接读操作,请求直接从磁盘读,没有通过缓存导致iowait升高.
通过层层分析后,root cause 是 app 内部进行了磁盘的直接I/O。然后定位到具体代码位置进行优化即可.
上述优化后 iowait 显著下降,但是僵尸进程数量仍旧在增加。首先要定位僵尸进程的父进程,通过pstree -aps XXX,打印出该僵尸进程的调用树,发现父进程就是app进程.
查看app代码,看看子进程结束的处理是否正确(是否调用wait()/waitpid(),有没有注册SIGCHILD信号的处理函数等).
碰到iowait升高时,先用dstat pidstat等工具确认是否存在磁盘I/O问题,再找是哪些进程导致I/O,不能用strace直接分析进程调用时可以通过perf工具分析.
对于僵尸问题,用pstree找到父进程,然后看源码检查子进程结束的处理逻辑即可.
根据不同的性能指标来找合适的工具:
先运行几个支持指标较多的工具,如 top/vmstat/pidstat,根据它们的输出可以得出是哪种类型的性能问题。定位到进程后再用 strace/perf 分析调用情况进一步分析。如果是软中断导致用 /proc/softirqs.
大多数计算机用的主存都是动态随机访问内存(DRAM),只有内核才可以直接访问物理内存。Linux内核给每个进程提供了一个独立的虚拟地址空间,并且这个地址空间是连续的。这样进程就可以很方便的访问内存(虚拟内存).
虚拟地址空间的内部分为内核空间和用户空间两部分,不同字长的处理器地址空间的范围不同。32位系统内核空间占用1G,用户空间占3G。64位系统内核空间和用户空间都是128T,分别占内存空间的最高和最低处,中间部分为未定义.
并不是所有的虚拟内存都会分配物理内存,只有实际使用的才会。分配后的物理内存通过内存映射管理。为了完成内存映射,内核为每个进程都维护了一个页表,记录虚拟地址和物理地址的映射关系。页表实际存储在CPU的内存管理单元MMU中,处理器可以直接通过硬件找出要访问的内存.
当进程访问的虚拟地址在页表中查不到时,系统会产生一个缺页异常,进入内核空间分配物理内存,更新进程页表,再返回用户空间恢复进程的运行.
MMU以页为单位管理内存,页大小4KB。为了解决页表项过多问题Linux提供了多级页表和HugePage的机制.
用户空间内存从低到高是五种不同的内存段:
malloc 对应到系统调用上有两种实现方式:
前者的缓存可以减少缺页异常的发生,提高内存访问效率。 但是由于内存没有归还系统,在内存工作繁忙时,频繁的内存分配/释放会造成内存碎片.
后者在释放时直接归还系统,所以每次mmap都会发生缺页异常.
在内存工作繁忙时,频繁内存分配会导致大量缺页异常,使内核管理负担增加.
上述两种调用并没有真正分配内存,这些内存只有在首次访问时,才通过缺页异常进入内核中,由内核来分配 。
内存紧张时,系统通过以下方式来回收内存:
echo -16 > /proc/$(pidof XXX)/oom_adj
free来查看整个系统的内存使用情况 。
top/ps来查看某个进程的内存使用情况 。
怎样理解内存中的Buffer和Cache?
buffer是对磁盘数据的缓存,cache是对文件数据的缓存,它们既会用在读请求也会用在写请求中 。
如何利用系统缓存优化程序的运行效率 。
缓存命中率是指直接通过缓存获取数据的请求次数,占所有请求次数的百分比。命中率越高说明缓存带来的收益越高,应用程序的性能也就越好.
安装bcc包后可以通过cachestat和cachetop来监测缓存的读写命中情况.
安装pcstat后可以查看文件在内存中的缓存大小以及缓存比例 。
#首先安装Go export GOPATH=~/go export PATH=~/go/bin:$PATH go get golang.org/x/sys/unix go ge github.com/tobert/pcstat/pcstat
dd if=/dev/sda1 of=file bs=1M count=512 #生产一个512MB的临时文件 echo 3 > /proc/sys/vm/drop_caches #清理缓存 pcstat file #确定刚才生成文件不在系统缓存中,此时cached和percent都是0 cachetop 5 dd if=file of=/dev/null bs=1M #测试文件读取速度 #此时文件读取性能为30+MB/s,查看cachetop结果发现并不是所有的读都落在磁盘上,读缓存命中率只有50%。 dd if=file of=/dev/null bs=1M #重复上述读文件测试 #此时文件读取性能为4+GB/s,读缓存命中率为100% pcstat file #查看文件file的缓存情况,100%全部缓存
cachetop 5 sudo docker run --privileged --name=app -itd feisky/app:io-direct sudo docker logs app #确认案例启动成功 #实验结果表明每读32MB数据都要花0.9s,且cachetop输出中显示1024次缓存全部命中
但是凭感觉可知如果缓存命中读速度不应如此慢,读次数时1024,页大小为4K,五秒的时间内读取了1024*4KB数据,即每秒0.8MB,和结果中32MB相差较大。说明该案例没有充分利用缓存,怀疑系统调用设置了直接I/O标志绕过系统缓存。因此接下来观察系统调用.
strace -p $(pgrep app) #strace 结果可以看到openat打开磁盘分区/dev/sdb1,传入参数为O_RDONLY|O_DIRECT
这就解释了为什么读32MB数据那么慢,直接从磁盘读写肯定远远慢于缓存。找出问题后我们再看案例的源代码发现flags中指定了直接IO标志。删除该选项后重跑,验证性能变化.
对应用程序来说,动态内存的分配和回收是核心又复杂的一个逻辑功能模块。管理内存的过程中会发生各种各样的“事故”:
虚拟内存分布从低到高分别是只读段,数据段,堆,内存映射段,栈五部分。其中会导致内存泄漏的是:
内存泄漏的危害比较大,这些忘记释放的内存,不仅应用程序自己不能访问,系统也不能把它们再次分配给其他应用。内存泄漏不断累积甚至会耗尽系统内存.
预先安装systat,docker,bcc 。
sudo docker run --name=app -itd feisky/app:mem-leak sudo docker logs app vmstat 3
可以看到free在不断下降,buffer和cache基本保持不变。说明系统的内存一致在升高。但并不能说明存在内存泄漏。此时可以通过memleak工具来跟踪系统或进程的内存分配/释放请求 。
/usr/share/bcc/tools/memleak -a -p $(pidof app)
从 memleak 输出可以看到,应用在不停地分配内存,并且这些分配的地址并没有被回收。通过调用栈看到是 fibonacci 函数分配的内存没有释放。定位到源码后查看源码来修复增加内存释放函数即可.
系统内存资源紧张时通过内存回收和OOM杀死进程来解决。其中可回收内存包括:
对于程序自动分配的堆内存,也就是我们在内存管理中的匿名页,虽然这些内存不能直接释放,但是 Linux 提供了 Swap 机制将不常访问的内存写入到磁盘来释放内存,再次访问时从磁盘读取到内存即可.
Swap本质就是把一块磁盘空间或者一个本地文件当作内存来使用,包括换入和换出两个过程:
很多情况下系统剩余内存较多,但 SWAP 依旧升高,这是由于处理器的 NUMA 架构.
在NUMA架构下多个处理器划分到不同的 Node,每个Node都拥有自己的本地内存空间。在分析内存的使用时应该针对每个Node单独分析 。
numactl --hardware #查看处理器在Node的分布情况,以及每个Node的内存使用情况
内存三个阈值可以通过 /proc/zoneinfo 来查看,该文件中还包括活跃和非活跃的匿名页/文件页数.
当某个Node内存不足时,系统可以从其他Node寻找空闲资源,也可以从本地内存中回收内存。通过/proc/sys/vm/zone_raclaim_mode来调整.
在实际回收过程中Linux根据 /proc/sys/vm/swapiness 选项来调整使用Swap的积极程度,从 0-100,数值越大越积极使用 Swap,即更倾向于回收匿名页;数值越小越消极使用 Swap,即更倾向于回收文件页.
注意:这只是调整 Swap 积极程度的权重,即使设置为0,当剩余内存+文件页小于页高阈值时,还是会发生 Swap.
说明剩余内存和缓冲区的波动变化正是由于内存回收和缓存再次分配的循环往复。有时候 Swap 用的多,有时候缓冲区波动更多。此时查看 swappiness 值为60,是一个相对中和的配置,系统会根据实际运行情况来选去合适的回收类型.
进程内存指标 。
缺页异常 。
根据不同的性能指标来找合适的工具:
内存分析工具包含的性能指标:
通常先运行几个覆盖面比较大的性能工具,如 free,top,vmstat,pidstat 等 。
常见的优化思路:
vmstat 命令是最常见的 Linux/Unix 监控工具,可以展现给定时间间隔的服务器的状态值,包括服务器的 CPU 使用率,内存使用,虚拟内存交换情况,IO读写情况。可以看到整个机器的 CPU,内存,IO 的使用情况,而不是单单看到各个进程的 CPU 使用率和内存使用率(使用场景不一样).
vmstat 2 procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 1 0 0 1379064 282244 11537528 0 0 3 104 0 0 3 0 97 0 0 0 0 0 1372716 282244 11537544 0 0 0 24 4893 8947 1 0 98 0 0 0 0 0 1373404 282248 11537544 0 0 0 96 5105 9278 2 0 98 0 0 0 0 0 1374168 282248 11537556 0 0 0 0 5001 9208 1 0 99 0 0 0 0 0 1376948 282248 11537564 0 0 0 80 5176 9388 2 0 98 0 0 0 0 0 1379356 282256 11537580 0 0 0 202 5474 9519 2 0 98 0 0 1 0 0 1368376 282256 11543696 0 0 0 0 5894 8940 12 0 88 0 0 1 0 0 1371936 282256 11539240 0 0 0 10554 6176 9481 14 1 85 1 0 1 0 0 1366184 282260 11542292 0 0 0 7456 6102 9983 7 1 91 0 0 1 0 0 1353040 282260 11556176 0 0 0 16924 7233 9578 18 1 80 1 0 0 0 0 1359432 282260 11549124 0 0 0 12576 5495 9271 7 0 92 1 0 0 0 0 1361744 282264 11549132 0 0 0 58 8606 15079 4 2 95 0 0 1 0 0 1367120 282264 11549140 0 0 0 2 5716 9205 8 0 92 0 0 0 0 0 1346580 282264 11562644 0 0 0 70 6416 9944 12 0 88 0 0 0 0 0 1359164 282264 11550108 0 0 0 2922 4941 8969 3 0 97 0 0 1 0 0 1353992 282264 11557044 0 0 0 0 6023 8917 15 0 84 0 0 # 结果说明 - r 表示运行队列(就是说多少个进程真的分配到CPU),我测试的服务器目前CPU比较空闲,没什么程序在跑,当这个值超过了CPU数目,就会出现CPU瓶颈了。这个也和top的负载有关系,一般负载超过了3就比较高,超过了5就高,超过了10就不正常了,服务器的状态很危险。top的负载类似每秒的运行队列。如果运行队列过大,表示你的CPU很繁忙,一般会造成CPU使用率很高。 - b 表示阻塞的进程,这个不多说,进程阻塞,大家懂的。 - swpd 虚拟内存已使用的大小,如果大于0,表示你的机器物理内存不足了,如果不是程序内存泄露的原因,那么你该升级内存了或者把耗内存的任务迁移到其他机器。 - free 空闲的物理内存的大小,我的机器内存总共8G,剩余3415M。 - buff Linux/Unix系统是用来存储,目录里面有什么内容,权限等的缓存,我本机大概占用300多M - cache cache直接用来记忆我们打开的文件,给文件做缓冲,我本机大概占用300多M(这里是Linux/Unix的聪明之处,把空闲的物理内存的一部分拿来做文件和目录的缓存,是为了提高 程序执行的性能,当程序使用内存时,buffer/cached会很快地被使用。) - si 每秒从磁盘读入虚拟内存的大小,如果这个值大于0,表示物理内存不够用或者内存泄露了,要查找耗内存进程解决掉。我的机器内存充裕,一切正常。 - so 每秒虚拟内存写入磁盘的大小,如果这个值大于0,同上。 - bi 块设备每秒接收的块数量,这里的块设备是指系统上所有的磁盘和其他块设备,默认块大小是1024byte,我本机上没什么IO操作,所以一直是0,但是我曾在处理拷贝大量数据(2-3T)的机器上看过可以达到140000/s,磁盘写入速度差不多140M每秒 - bo 块设备每秒发送的块数量,例如我们读取文件,bo就要大于0。bi和bo一般都要接近0,不然就是IO过于频繁,需要调整。 - in 每秒CPU的中断次数,包括时间中断 - cs 每秒上下文切换次数,例如我们调用系统函数,就要进行上下文切换,线程的切换,也要进程上下文切换,这个值要越小越好,太大了,要考虑调低线程或者进程的数目,例如在apache和nginx这种web服务器中,我们一般做性能测试时会进行几千并发甚至几万并发的测试,选择web服务器的进程可以由进程或者线程的峰值一直下调,压测,直到cs到一个比较小的值,这个进程和线程数就是比较合适的值了。系统调用也是,每次调用系统函数,我们的代码就会进入内核空间,导致上下文切换,这个是很耗资源,也要尽量避免频繁调用系统函数。上下文切换次数过多表示你的CPU大部分浪费在上下文切换,导致CPU干正经事的时间少了,CPU没有充分利用,是不可取的。 - us 用户CPU时间,我曾经在一个做加密解密很频繁的服务器上,可以看到us接近100,r运行队列达到80(机器在做压力测试,性能表现不佳)。 - sy 系统CPU时间,如果太高,表示系统调用时间长,例如是IO操作频繁。 - id 空闲CPU时间,一般来说,id + us + sy = 100,一般我认为id是空闲CPU使用率,us是用户CPU使用率,sy是系统CPU使用率。 - wt 等待IO CPU时间
pidstat 主要用于监控全部或指定进程占用系统资源的情况,如CPU,内存、设备IO、任务切换、线程等.
使用方法:
# 统计CPU pidstat -u 1 10 03:03:33 PM UID PID %usr %system %guest %CPU CPU Command 03:03:34 PM 0 2321 3.96 0.00 0.00 3.96 0 ansible 03:03:34 PM 0 7110 0.00 0.99 0.00 0.99 4 pidstat 03:03:34 PM 997 8539 0.99 0.00 0.00 0.99 5 java 03:03:34 PM 984 15517 0.99 0.00 0.00 0.99 5 java 03:03:34 PM 0 24406 0.99 0.00 0.00 0.99 5 java 03:03:34 PM 0 32158 3.96 0.00 0.00 3.96 2 ansible
# 统计内存 pidstat -r 1 10 Average: UID PID minflt/s majflt/s VSZ RSS %MEM Command Average: 0 1 0.20 0.00 191256 3064 0.01 systemd Average: 0 1007 1.30 0.00 143256 22720 0.07 AliYunDun Average: 0 6642 0.10 0.00 6301904 107680 0.33 java Average: 997 7326 10.89 0.00 13468904 8395848 26.04 java Average: 0 7795 348.15 0.00 108376 1233 0.00 pidstat Average: 997 8539 0.50 0.00 8242256 2062228 6.40 java Average: 987 9518 0.20 0.00 6300944 1242924 3.85 java Average: 0 10280 3.70 0.00 807372 8344 0.03 aliyun-service Average: 984 15517 0.40 0.00 6386464 1464572 4.54 java Average: 0 16066 236.46 0.00 2678332 71020 0.22 cmagent Average: 995 20955 0.30 0.00 6312520 1408040 4.37 java Average: 995 20956 0.20 0.00 6093764 1505028 4.67 java Average: 0 23936 0.10 0.00 5302416 110804 0.34 java Average: 0 24406 0.70 0.00 10211672 2361304 7.32 java Average: 0 26870 1.40 0.00 1470212 36084 0.11 promtail
pidstat -T ALL -r -p 20955 1 10 03:12:16 PM UID PID minflt/s majflt/s VSZ RSS %MEM Command 03:12:17 PM 995 20955 0.00 0.00 6312520 1408040 4.37 java 03:12:16 PM UID PID minflt-nr majflt-nr Command 03:12:17 PM 995 20955 0 0 java
原文地址:https://mp.weixin.qq.com/s?__biz=MzA4Nzg5Nzc5OA==&mid=2651710148&idx=1&sn=8d015f31a3f819c39df11cd57f12601b&utm_source=tuicool&utm_medium=referral 。
最后此篇关于Linux 性能优化的全景指南,可能都在这里了的文章就讲到这里了,如果你想了解更多关于Linux 性能优化的全景指南,可能都在这里了的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
比较代码: const char x = 'a'; std::cout > (0C310B0h) 00C3100B add esp,4 和 const i
您好,我正在使用 Matlab 优化求解器,但程序有问题。我收到此消息 fmincon 已停止,因为目标函数值小于目标函数限制的默认值,并且约束满足在约束容差的默认值范围内。我也收到以下消息。警告:矩
处理Visual Studio optimizations的问题为我节省了大量启动和使用它的时间 当我必须进行 J2EE 开发时,我很难回到 Eclipse。因此,我还想知道人们是否有任何提示或技巧可
情况如下:在我的 Excel 工作表中,有一列包含 1-name 形式的条目。考虑到数字也可以是两位数,我想删除这些数字。这本身不是问题,我让它工作了,只是性能太糟糕了。现在我的程序每个单元格输入大约
这样做有什么区别吗: $(".topHorzNavLink").click(function() { var theHoverContainer = $("#hoverContainer");
这个问题已经有答案了: 已关闭11 年前。 Possible Duplicate: What is the cost of '$(this)'? 我经常在一些开发人员代码中看到$(this)引用同一个
我刚刚结束了一个大型开发项目。我们的时间紧迫,因此很多优化被“推迟”。既然我们已经达到了最后期限,我们将回去尝试优化事情。 我的问题是:优化 jQuery 网站时您要寻找的最重要的东西是什么。或者,我
所以我一直在用 JavaScript 编写游戏(不是网络游戏,而是使用 JavaScript 恰好是脚本语言的游戏引擎)。不幸的是,游戏引擎的 JavaScript 引擎是 SpiderMonkey
这是我在正在构建的页面中使用的 SQL 查询。它目前运行大约 8 秒并返回 12000 条记录,这是正确的,但我想知道您是否可以就如何使其更快提出可能的建议? SELECT DISTINCT Adve
如何优化这个? SELECT e.attr_id, e.sku, a.value FROM product_attr AS e, product_attr_text AS a WHERE e.attr
我正在使用这样的结构来测试是否按下了所需的键: def eventFilter(self, tableView, event): if event.type() == QtCore.QEven
我正在使用 JavaScript 从给定的球员列表中计算出羽毛球 double 比赛的所有组合。每个玩家都与其他人组队。 EG。如果我有以下球员a、b、c、d。它们的组合可以是: a & b V c
我似乎无法弄清楚如何让这个 JS 工作。 scroll function 起作用但不能隐藏。还有没有办法用更少的代码行来做到这一点?我希望 .down-arrow 在 50px 之后 fade out
我的问题是关于用于生产的高级优化级联样式表 (CSS) 文件。 多么最新和最完整(准备在实时元素中使用)的 css 优化器/最小化器,它们不仅提供删除空格和换行符,还提供高级功能,如删除过多的属性、合
我读过这个: 浏览器检索在 中请求的所有资源开始呈现 之前的 HTML 部分.如果您将请求放在 中section 而不是,那么页面呈现和下载资源可以并行发生。您应该从 移动尽可能多的资源请求。
我正在处理一些现有的 C++ 代码,这些代码看起来写得不好,而且调用频率很高。我想知道我是否应该花时间更改它,或者编译器是否已经在优化问题。 我正在使用 Visual Studio 2008。 这是一
我正在尝试使用 OpenGL 渲染 3 个四边形(1 个背景图,2 个 Sprite )。我有以下代码: void GLRenderer::onDrawObjects(long p_dt) {
我确实有以下声明: isEnabled = false; if(foo(arg) && isEnabled) { .... } public boolean foo(arg) { some re
(一)深入浅出理解索引结构 实际上,您可以把索引理解为一种特殊的目录。微软的SQL SERVER提供了两种索引:聚集索引(clustered index,也称聚类索引、簇集索引)和非聚集索引(no
一、写在前面 css的优化方案,之前没有提及,所以接下来进行总结一下。 二、具体优化方案 2.1、加载性能 1、css压缩:将写好的css进行打包,可以减少很多的体积。 2、css单一样式:在需要下边
我是一名优秀的程序员,十分优秀!