Linux 성능 전반에 걸친 튜닝 경험 요약

풀어 주다: 2023-08-03 14:59:49
앞으로
1165명이 탐색했습니다.

Part1Linux 성능 최적화

1성능 최적화

성능 지표

높음 동시성과 빠른 응답은 성능 최적화의 두 가지 핵심 지표에 해당합니다. 처리량Latency

Linux 성능 전반에 걸친 튜닝 경험 요약
사진 출처: www.ctq6.cn
  • Application loadAngle: 제품 터미널의 사용자 경험에 직접적인 영향을 미칩니다
  • System resourcesAngle: 리소스 사용량, satur 이온 성능 문제의 본질은 시스템 리소스가 병목 현상에 도달했지만 요청 처리가 더 많은 요청을 지원할 만큼 빠르지 않다는 것입니다. 성능 분석은 실제로 애플리케이션이나 시스템의 병목 현상을 찾아 이를 피하거나 완화하려고 노력하는 것입니다.
    • 애플리케이션 및 시스템 성능을 평가하기 위한 지표 선택
    • 애플리케이션 및 시스템에 대한 성능 목표 설정
    • 성능 벤치마크 수행
    • 병목 현상을 찾기 위한 성능 분석
    • 성능 모니터링 및 경고

    다양한 성능 문제의 경우 다양한 성능 분석 도구를 선택해야 합니다. 다음은 일반적으로 사용되는 Linux 성능 도구와 해당 유형의 성능 문제를 분석한 것입니다.

    Linux 성능 전반에 걸친 튜닝 경험 요약
    사진: www.ctq6.cn

    "평균 부하"를 어떻게 이해해야 할까요?

    평균 부하: 실행 가능한 상태와 중단 불가능한 상태의 시스템 평균 프로세스 단위 시간 수는 활성 프로세스의 평균 수입니다. 우리가 전통적으로 이해한 것처럼 CPU 사용량과 직접적인 관련이 없습니다.

    무정전 프로세스는 커널 상태에서 중요한 프로세스(예: 장치를 기다리는 일반적인 I/O 응답)에 있는 프로세스입니다. 무정전 상태는 실제로 프로세스 및 하드웨어 장치에 대한 시스템의 보호 메커니즘입니다.

    합리적인 평균 부하는 얼마인가요?

    실제 생산 환경에서 시스템의 평균 부하를 모니터링하고 과거 데이터를 바탕으로 부하 변화 추세를 판단합니다. 부하가 확실히 증가하는 경향이 있는 경우 적시에 분석 및 조사를 수행합니다. 물론 임계값을 설정할 수도 있습니다(예: 평균 부하가 CPU 수의 70%보다 높은 경우)

    실제 작업에서는 평균 부하와 CPU 사용량의 개념을 혼동하는 경우가 많습니다. 둘은 완전히 동일하지 않습니다:

    • CPU 집약적인 프로세스, 다량의 CPU 사용량으로 인해 평균 로드가 증가합니다. 이때 두 프로세스는 일관됩니다.
    • I/O 집약적인 프로세스, I/O를 기다리는 프로세스도 이로 인해 평균 부하가 증가하므로 CPU 사용량이 반드시 높은 것은 아닙니다
    • CPU 스케줄링을 기다리는 프로세스 수가 많으면 평균 부하도 증가하게 됩니다.

    CPU의 평균 부하가 높으면 CPU가 집중적인 프로세스나 바쁜 I/O로 인해 발생할 수 있습니다. 특정 분석 중에 mpstat/pidstat 도구를 결합하여 로드 소스 분석을 지원할 수 있습니다

    2CPU

    CPU 컨텍스트 스위칭(1부)

    CPU 컨텍스트 스위칭은 이전 작업의 CPU 컨텍스트(CPU 레지스터 및 PC)를 저장한 후 새로운 작업을 로드하는 것입니다. 이러한 레지스터와 프로그램 카운터에 대한 컨텍스트를 지정하고 마지막으로 프로그램 카운터가 가리키는 위치로 점프하여 새 작업을 실행합니다. 그중 저장된 컨텍스트는 시스템 커널에 저장되었다가 작업 일정이 변경될 때 다시 로드되어 원래 작업 상태가 영향을 받지 않도록 합니다.

    작업 유형에 따라 CPU 컨텍스트 전환은 다음과 같이 구분됩니다.

    • 프로세스 컨텍스트 스위치
    • 스레드 컨텍스트 스위치
    • 인터럽트 컨텍스트 스위치

    프로세스 컨텍스트 스위치

    Lin ux 프로세스는 레벨 권한을 따르고 프로세스의 실행 공간을 나눕니다. 커널 공간과 사용자 공간으로 나뉜다. 사용자 모드에서 커널 모드로의 전환은 시스템 호출을 통해 완료되어야 합니다.

    시스템 호출 프로세스는 실제로 두 개의 CPU 컨텍스트 전환을 수행합니다.

    • CPU 레지스터의 사용자 모드 명령어 위치가 먼저 저장되고, CPU 레지스터가 커널 모드 명령어의 위치로 업데이트되며, 커널 작업을 실행하기 위해 커널 상태로 점프합니다. 시스템 호출이 끝나면 CPU 레지스터는 원래 상태로 돌아갑니다. 사용자 모드 데이터를 저장한 후 사용자 공간으로 전환하여 계속 실행합니다.
    • 시스템 호출 프로세스에는 가상 메모리와 같은 프로세스 사용자 모드 리소스가 포함되지 않으며 프로세스를 전환하지도 않습니다. 이는 전통적인 의미의 프로세스 컨텍스트 전환과는 다릅니다. 따라서
      시스템 호출을 종종 특권 모드 스위치
    • 라고 합니다.

    프로세스는 커널에 의해 관리되고 예약되며 프로세스 컨텍스트 전환은 커널 모드에서만 발생할 수 있습니다. 따라서 시스템 호출과 비교하여 현재 프로세스의 커널 상태와 CPU 레지스터를 저장하기 전에 프로세스의 가상 메모리와 스택을 먼저 저장해야 합니다. 새로운 프로세스의 커널 상태를 로딩한 후에는 해당 프로세스의 가상 메모리와 사용자 스택을 새로 고쳐야 합니다.

    프로세스는 CPU에서 실행되도록 예약된 경우에만 컨텍스트를 전환하면 됩니다. 다음과 같은 시나리오가 있습니다. CPU 시간 분할이 차례로 할당되고, 시스템 리소스가 부족하여 프로세스가 중단되고, 프로세스가 적극적으로 중단됩니다. 절전 기능 및 우선 순위가 높은 프로세스 선점 시간 조각, 하드웨어가 중단되면 CPU의 프로세스가 일시 중지되고 대신 커널에서 인터럽트 서비스를 실행합니다.

    스레드 컨텍스트 전환

    스레드 컨텍스트 전환은 두 가지 유형으로 나뉩니다.

    • 전면 및 후면 스레드는 전환 중에 가상 메모리 리소스가 변경되지 않고 그대로 유지됩니다. , 레지스터 등을 전환해야 합니다.
    • 전면 및 후면 스레드는 서로 다른 프로세스에 속하며 이는 프로세스 컨텍스트 전환과 동일합니다.

    동일한 프로세스에서 스레드를 전환하면 리소스를 덜 소모하는데, 이는 멀티스레딩의 장점이기도 합니다.

    인터럽트 컨텍스트 전환

    인터럽트 컨텍스트 전환에는 프로세스의 사용자 상태가 포함되지 않으므로 인터럽트 컨텍스트에는 커널 상태 인터럽트 서비스 프로그램 실행에 필요한 상태만 포함됩니다(CPU 레지스터, 커널 스택, 하드웨어 인터럽트 매개변수 등).

    프로세스보다 인터럽트 처리 우선순위가 높기 때문에 인터럽트 컨텍스트 전환과 프로세스 컨텍스트 전환이 동시에 발생하지 않습니다

    Docker+K8s+Jenkins 주류 기술 종합 영상 정보

    CPU 컨텍스트 전환(2부)

    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
    로그인 후 복사
    • cs(컨텍스트 스위치) 초당 컨텍스트 스위치 수
    • in(인터럽트) 초당 인터럽트 수
    • r(runnning 또는 runnable) 준비 대기열의 길이, 실행 및 대기 CPU의 프로세스 수
    • b (차단됨) 무중단 절전 상태의 프로세스 수

    각 프로세스의 세부 정보를 보려면 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
    로그인 후 복사
    • cswch 每秒自愿上下文切换次数 (进程无法获取所需资源导致的上下文切换)
    • nvcswch 每秒非自愿上下文切换次数 (时间片轮流等系统强制调度)
    vmstat 1 1    #首先获取空闲系统的上下文切换次数
    sysbench --threads=10 --max-time=300 threads run #模拟多线程切换问题
    
    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负载能力明显提升

    系统的CPU使用率很高,为什么找不到高CPU的应用?

    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进程的进程号变化了,此时有可能时以下两种原因导致:

    • 进程不停的崩溃重启(如段错误/配置错误等),此时进程退出后可能又被监控系统重启;
    • 短时进程导致,即其他应用内部通过exec调用的外面命令,这些命令一般只运行很短时间就结束,很难用top这种间隔较长的工具来发现

    可以通过pstree来查找 stress的父进程,找出调用关系。

    pstree | grep stress
    로그인 후 복사

    发现是php-fpm调用的该子进程,此时去查看源码可以看出每个请求都会调用一个stress命令来模拟I/O压力。之前top显示的结果是CPU使用率升高,是否真的是由该stress命令导致的,还需要继续分析。代码中给每个请求加了verbose=1的参数后可以查看stress命令的输出,在中断测试该命令结果显示stress命令运行时存在因权限问题导致的文件创建失败的bug。

    此时依旧只是猜测,下一步继续通过perf工具来分析。性能报告显示确实时stress占用了大量的CPU,通过修复权限问题来优化解决即可.

    시스템에 무정전 프로세스와 좀비 프로세스가 많은 경우 어떻게 해야 하나요?

    프로세스 상태

    • R 실행 중/실행 가능, 프로세스가 CPU의 준비 대기열에 있고 실행 중이거나 실행 대기 중임을 나타냅니다.
    • D 디스크 절전, 중단 불가능한 상태 절전, 일반적으로 나타냅니다. 프로세스 하드웨어와 상호 작용하고 있으며 상호 작용 중에 다른 프로세스에 의해 중단될 수 없습니다.
    • Z 좀비 프로세스인 좀비는 프로세스가 실제로 종료되었지만 상위 프로세스가 회수되지 않았음을 의미합니다.
    • S Sleep 상태를 중단할 수 있는 Interruptible Sleep은 이벤트를 기다리고 있기 때문에 프로세스가 시스템에 의해 일시 중지되는 것을 의미합니다. R 상태;
    • I 유휴 상태, 무정전 커널 스레드에서 사용됩니다.该状态不会导致平均负载升高;
    • T Stop/Traced,表示进程处于暂停或跟踪状态(SIGSTOP/SIGCONT, GDB调试);
    • X Dead,进程已经消亡,不会在top/ps中看到。

    对于不可中断状态,一般都是在很短时间内结束,可忽略。但是如果系统或硬件发生故障,进程可能会保持不可中断状态很久,甚至系统中出现大量不可中断状态,此时需注意是否出现了I/O性能问题。

    僵尸进程一般多进程应用容易遇到,父进程来不及处理子进程状态时子进程就提前退出,此时子进程就变成了僵尸进程。大量的僵尸进程会用尽PID进程号,导致新进程无法建立。

    磁盘O_DIRECT问题

    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进程的系统调用。

    sudo strace -p XXX #对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를 사용하여 좀비 프로세스의 호출 트리를 인쇄하고 상위 프로세스가 앱 프로세스인지 확인합니다.

    앱 코드를 확인하여 하위 프로세스의 끝이 올바르게 처리되었는지 확인하세요(wait()/waitpid()가 호출되는지, SIGCHILD 신호 처리 함수가 등록되어 있는지 등).

    iowait가 증가하면 먼저 dstat 및 pidstat와 같은 도구를 사용하여 디스크 I/O 문제가 있는지 확인한 다음 strace를 사용할 수 없는 경우 어떤 프로세스가 I/O를 일으키는지 알아보세요. 프로세스 호출을 직접 분석하려면 perf 도구를 사용하여 분석할 수 있습니다.

    좀비 문제의 경우 pstree를 사용하여 상위 프로세스를 찾은 후 소스 코드를 보고 하위 프로세스 종료에 대한 처리 로직을 확인합니다.

    CPU 성능 지표

    • CPU 사용량

      • 사용자 모드(사용자) 및 낮은 우선순위 사용자 모드(nice)를 포함한 사용자 CPU 사용량 이 표시기가 너무 높으면 애플리케이션이 사용 중임을 나타냅니다.
      • 시스템 CPU 사용량. , CPU는 커널 모드가 실행되는 시간의 비율입니다(중단 제외). 높은 표시는 커널이 상대적으로 사용 중임을 나타냅니다.
      • CPU 사용량이 I/O를 기다리고 있음을 나타냅니다. /O 시스템과 하드웨어 장치 간의 상호 작용 시간은 비교적 깁니다.
      • 소프트/하드 인터럽트 CPU 사용량, 높은 표시기는 시스템에 많은 수의 인터럽트가 있음을 나타냅니다.
      • CPU/게스트 훔치기 CPU는 가상 머신이 차지하는 CPU의 백분율을 나타냅니다.
    • Average load

      이상적으로 평균 로드는 논리적 CPU 수와 동일합니다. 즉, 각 CPU가 완전히 활용된다는 의미입니다. 그보다 크면 시스템 부하가 크다는 뜻입니다.

    • Process Context Switch

      자원을 확보할 수 없는 경우의 자발적 전환과 시스템이 스케줄링을 강제할 때의 비자발적 전환을 포함합니다. 컨텍스트 전환 자체는 Linux의 정상적인 작동을 보장하는 핵심 기능입니다. 과도한 전환은 레지스터에서 원래 실행 중인 프로세스의 CPU 시간을 소모합니다. 커널 및 가상 메모리와 기타 데이터 저장 및 복구. 또한, 공개 계정 프로그래머 샤오러의 백스테이지를 검색해 '인터뷰 질문'에 답하고 깜짝 선물 패키지를 받아가세요.

    • CPU 캐시 적중률

      CPU 캐시 재사용률이 높을수록 성능이 좋아집니다. 그 중 L1/L2는 싱글 코어에서 흔히 사용되며, L3는 멀티에서 사용됩니다. -코어

    성능 도구

    • 평균 부하 사례
      • 먼저 가동 시간을 사용하여 시스템 평균 부하를 확인하세요
      • mpstat 및 pid 사용 부하를 판단하여 각각을 확인합니다. 프로세스당 CPU 및 CPU 사용량을 알아보세요.
    • 컨텍스트 전환 사례
      • 먼저 vmstat를 사용하여 시스템 컨텍스트 전환과 인터럽트 시간을 확인하세요
      • pidstat를 사용하여 프로세스의 자발적 및 비자발적 컨텍스트 전환을 관찰하세요
      • 마지막으로 pidstat를 통해 스레드의 컨텍스트 전환을 관찰합니다
    • 프로세스 CPU 사용량이 많은 사례
      • 먼저 top을 사용하여 시스템과 프로세스의 CPU 사용량을 확인하고 위치를 찾습니다. the process
      • 그런 다음 perf top을 사용하여 프로세스 호출 체인을 관찰하고 특정 기능을 찾습니다.
    • 시스템 CPU 사용량이 높은 경우
      • 먼저 top을 사용하여 CPU를 확인합니다. 시스템 및 프로세스 사용량, top/ pidstat도 CPU 사용량이 높은 프로세스를 찾을 수 없습니다
      • 최고 출력을 다시 검사하세요
      • CPU 사용량이 낮지만 Running 상태인 프로세스부터 시작하세요
      • perf 기록/보고서에서 수명이 짧은 프로세스 발견(execsnoop 도구)
    • 무정전 및 좀비 프로세스 사례
      • 첫 번째로 top을 사용하여 iowait 증가를 관찰하고 많은 수의 프로세스를 발견했습니다. 무정전 및 좀비 프로세스 프로세스
      • strace는 프로세스 시스템 호출을 추적할 수 없음
      • perf 분석 호출 체인에서 근본 원인이 디스크 직접 I/O에서 비롯된 것으로 확인됨
    • 소프트 인터럽트 사례
      • 상위 관찰 시스템 소프트 인터럽트 CPU 사용량이 높습니다
      • /proc/softirqs를 확인하여 빠르게 변화하는 속도로 여러 소프트 인터럽트를 찾으세요
      • sar 명령에서 발견한 것은 네트워크 패킷 문제
      • tcpdump는 네트워크 프레임의 유형과 소스를 찾아내고 SYN FLOOD 공격의 원인을 결정합니다.

    다양한 성능 지표를 기반으로 올바른 도구 찾기:

    Linux 성능 전반에 걸친 튜닝 경험 요약
    사진 출처: www. ctq6.cn

    프로덕션 환경에서 개발자는 종종 새로운 도구 패키지를 설치할 권한이 없으며 시스템에 이미 설치된 도구의 사용을 최대화할 수 있습니다. 따라서 어떤 지표 분석이 주류인지 이해해야 합니다. 도구를 제공할 수 있습니다.

    Linux 성능 전반에 걸친 튜닝 경험 요약
    출처: www.ctq6.cn

    먼저 top/vmstat/pidstat와 같은 더 많은 표시기를 지원하는 여러 도구를 실행해 보면 어떤 유형의 성능 문제인지 확인할 수 있습니다. 프로세스를 찾은 후 추가 분석을 위해 strace/perf를 사용하여 호출 상황을 분석합니다. 소프트 인터럽트로 인해 발생한 경우 /proc/softirqs

    를 사용하세요.
    Linux 성능 전반에 걸친 튜닝 경험 요약
    사진 출처: www.ctq6.cn

    CPU 최적화

    • 애플리케이션 최적화

      • 컴파일러 최적화: 컴파일 단계에서 gcc -O2 동시 처리 기능과 같은 최적화 옵션을 활성화합니다. (폴링을 이벤트 알림으로 대체)
      • 다중 프로세스 대신 다중 스레드: 컨텍스트 전환 비용을 줄입니다.
      • 캐시 활용: 프로그램 처리 속도 향상
      • 시스템 최적화
        • CPU 바인딩: 프로세스를 1/여러 CPU에 바인딩하고, CPU 캐시 적중률을 향상시키며, CPU 스케줄링으로 인한 컨텍스트 전환을 줄입니다.
        • CPU 독점: CPU 선호도 프로세스를 할당하는 메커니즘
        • nice를 사용하여 비핵심 애플리케이션의 우선순위를 적절하게 줄입니다.
        • 프로세스에 대한 리소스 표시 설정: cgroups는 애플리케이션 자체의 문제로 인한 소진을 방지하기 위해 사용량 상한을 설정합니다. 시스템 리소스
        • NUMA 최적화: CPU는 가능한 한 로컬 메모리에 액세스합니다
        • 인터럽트 로드 밸런싱: irpbalance, 인터럽트 처리 프로세스를 각 CPU에 자동으로 로드 밸런싱
      • TPS, 차이점과 QPS 및 시스템 처리량에 대한 이해

        • QPS(TPS)

        • 동시 횟수

        • 응답 시간

          QPS(TPS)=동시 횟수/평균 응답 시간

        • 사용자 요청 서버

        • 서버의 내부 처리

        • 서버가 클라이언트로 돌아갑니다

          QPS는 TPS와 유사하지만 페이지 방문이 TPS를 형성하지만 페이지 요청에는 여러 요청이 포함될 수 있습니다. 계산될 수 있는 서버 여러 개의 QPS

        • QPS(초당 쿼리 수) 쿼리 속도, 서버가 초당 응답할 수 있는 쿼리 수를 입력하세요.

        • TPS(초당 트랜잭션), 소프트웨어 테스트 결과

        • 몇 가지 중요한 매개변수를 포함한 시스템 처리량:

      3Memory

      Linux 메모리 작동 방식

      메모리 매핑

      대부분의 컴퓨터에서 사용하는 주 메모리는 DRAM(동적 랜덤 액세스 메모리)입니다. 물리적 메모리에 직접 접근합니다. Linux 커널은 각 프로세스에 대해 독립적인 가상 주소 공간을 제공하며 이 주소 공간은 연속적입니다. 이런 방식으로 프로세스는 메모리(가상 메모리)에 쉽게 접근할 수 있습니다.

      가상 주소 공간의 내부는 커널 공간과 사용자 공간의 두 부분으로 나누어집니다. 단어 길이가 다른 프로세서의 주소 공간 범위는 다릅니다. 32비트 시스템 커널 공간은 1G를 차지하고 사용자 공간은 3G를 차지합니다. 64비트 시스템의 커널 공간과 사용자 공간은 모두 128T로 각각 메모리 공간의 가장 높은 부분과 가장 낮은 부분을 차지하고 중간 부분은 정의되지 않습니다.

      모든 가상 메모리에 실제 메모리가 할당되는 것은 아니며 실제 사용되는 메모리에만 할당됩니다. 할당된 물리적 메모리는 메모리 매핑을 통해 관리됩니다. 메모리 매핑을 완성하기 위해 커널은 각 프로세스별로 페이지 테이블을 유지하여 가상 주소와 물리적 주소 간의 매핑 관계를 기록합니다. 페이지 테이블은 실제로 CPU의 메모리 관리부인 MMU에 저장되며, 프로세서는 하드웨어를 통해 접근할 메모리를 직접 찾아낼 수 있다.

      프로세스가 액세스한 가상 주소를 페이지 테이블에서 찾을 수 없으면 시스템은 페이지 폴트 예외를 생성하고 커널 공간에 들어가 물리적 메모리를 할당한 다음 프로세스 페이지 테이블을 업데이트한 다음 사용자 공간으로 돌아갑니다. 프로세스 작업을 재개합니다.

      MMU는 4KB의 페이지 크기로 페이지 단위로 메모리를 관리합니다. 너무 많은 페이지 테이블 항목 문제를 해결하기 위해 Linux는 다단계 페이지 테이블HugePage 메커니즘을 제공합니다.

      가상 메모리 공간 분배

      사용자 공간 메모리는 낮은 것부터 높은 것까지 다섯 가지 메모리 세그먼트로 나뉩니다.

      • 읽기 전용 세그먼트 코드 및 상수 등. 위쪽으로 성장
      • 파일 매핑 동적 라이브러리, 공유 메모리 등은 높은 주소에서 시작하여 아래쪽으로 성장합니다.
      • Stack로컬 변수 및 함수 호출 컨텍스트 등을 포함하여 크기 스택의 고정입니다.일반적으로 8MB

      메모리 할당 및 재활용

      allocation

      malloc은 시스템 호출의 두 가지 구현 방법에 해당합니다.

      • brk() 작은 메모리 블록(<128K)의 경우 힙의 최상위 위치를 이동하여 할당합니다. 메모리는 해제된 후 즉시 반환되지 않고 캐시됩니다.
      • **mmap()** 큰 메모리 블록(>128K)의 경우 메모리 매핑을 사용하여 직접 할당합니다. 즉, 파일 매핑 세그먼트에서 사용 가능한 메모리 할당을 찾습니다.

      전자의 캐시는 페이지 폴트 예외 발생을 줄이고 메모리 액세스 효율성을 향상시킬 수 있습니다. 그러나 메모리가 시스템에 반환되지 않기 때문에 메모리 할당/해제를 자주 수행하면 메모리가 사용 중일 때 메모리 조각화가 발생합니다.

      후자는 해제되면 시스템에 직접 반환되므로 mmap이 발생할 때마다 페이지 폴트 예외가 발생합니다. 메모리 작업이 바쁜 경우 메모리를 자주 할당하면 페이지 오류 예외가 많이 발생하여 커널 관리 부담이 증가합니다.

      위의 두 호출은 실제로 메모리를 할당하지 않습니다. 이러한 메모리는 처음 액세스하고 커널에 의해 할당될 때 페이지 오류 예외를 통해서만 커널에 들어갑니다

      재활용

      메모리가 부족하면 시스템은 다음과 같은 방법으로 메모리를 회수합니다.

      • 캐시 재활용: LRU 알고리즘은 가장 최근에 사용된 메모리 페이지를 회수합니다. 재활용 메모리 액세스: 스왑 파티션을 통해 자주 사용하지 않는 메모리를 디스크에 기록

      • 프로세스 종료: OOM 커널 보호 메커니즘(프로세스에서 소비하는 메모리가 클수록 oom_score도 커지고 더 많은 CPU를 차지할수록 oom_score는 더 작아집니다. /proc를 수동으로 전달하여 oom_adj를 조정할 수 있습니다.

        echo -16 > /proc/$(pidof XXX)/oom_adj
        로그인 후 복사

      如何查看内存使用情况

      free来查看整个系统的内存使用情况

      top/ps来查看某个进程的内存使用情况

      • VIRT 프로세스의 가상 메모리 크기
      • RES상주 메모리의 크기, 즉 스왑 및 공유 메모리를 제외한 프로세스에서 실제로 사용하는 물리적 메모리 크기
      • SHR 공유 메모리 크기, 다른 프로세스와 공유되는 메모리, 로드된 동적 링크 라이브러리 및 프로그램 코드 세그먼트
      • %MEM 전체 시스템 메모리에서 프로세스가 사용하는 물리적 메모리의 비율

      메모리 버퍼와 캐시를 이해하는 방법은 무엇입니까?

      버퍼는 디스크 데이터의 캐시이고 캐시는 파일 데이터의 캐시이며 읽기 요청과 쓰기 요청 모두에 사용됩니다.

      시스템 캐시를 사용하여 프로그램의 운영 효율성을 최적화하는 방법

      캐시 적중률

      캐시 적중률은 캐시를 통해 직접 데이터를 얻기 위한 요청 횟수를 말하며 전체 요청의 비율을 차지합니다. 적중률이 높을수록 캐시가 가져오는 이점이 높아지고 애플리케이션 성능이 향상됩니다.

      bcc 패키지를 설치한 후, 캐시 통계 및 캐시탑을 통해 캐시 읽기 및 쓰기 적중을 모니터링할 수 있습니다.

      安装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缓存加速

      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%全部缓存
      로그인 후 복사

      O_DIRECT选项绕过系统缓存

      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标志。删除该选项后重跑,验证性能变化。

      메모리 누수, 어떻게 찾아서 처리하나요?

      애플리케이션의 경우 동적 메모리 할당 및 재활용은 핵심적이고 복잡한 논리 기능 모듈입니다. 기억을 관리하는 과정에서 다양한 '사고'가 발생하게 됩니다:

      • 할당된 메모리가 제대로 회수되지 않아 누수 발생
      • 할당된 메모리 경계 밖의 주소에 접근하여 프로그램이 비정상적으로 종료되었습니다

      메모리 할당 및 재활용

      가상 메모리의 분포는 낮은 것부터 높은 것까지 읽기 전용 세그먼트, 데이터 세그먼트, 힙, 메모리 매핑 세그먼트, 스택 5개 부분입니다. 그중 메모리 누수를 일으킬 수 있는 항목은 다음과 같습니다.

      • 힙: 프로그램이 종료되지 않는 한 애플리케이션 자체에서 할당 및 관리되며 이러한 힙 메모리는 시스템에서 자동으로 해제되지 않습니다.
      • 메모리 매핑 세그먼트: 공유 메모리가 프로그램에 의해 자동으로 할당되고 관리되는 동적 링크 라이브러리 및 공유 메모리를 포함합니다. 애플리케이션 자체적으로 액세스할 수 없으며 시스템이 이를 다른 애플리케이션에 다시 할당할 수 없습니다. 메모리 누수는 누적되고 시스템 메모리도 소진됩니다.

      메모리 누수를 감지하는 방법systat, docker, bcc 사전 설치

      sudo docker run --name=app -itd feisky/app:mem-leak
      sudo docker logs app
      vmstat 3
      로그인 후 복사

      可以看到free在不断下降,buffer和cache基本保持不变。说明系统的内存一致在升高。但并不能说明存在内存泄漏。此时可以通过memleak工具来跟踪系统或进程的内存分配/释放请求。另外,搜索公众号Linux就该这样学后台回复“git书籍”,获取一份惊喜礼包。

      /usr/share/bcc/tools/memleak -a -p $(pidof app)
      로그인 후 복사

      从memleak输出可以看到,应用在不停地分配内存,并且这些分配的地址并没有被回收。通过调用栈看到是fibonacci函数分配的内存没有释放。定位到源码后查看源码来修复增加内存释放函数即可.

      为什么系统的Swap变高

      系统内存资源紧张时通过内存回收和OOM杀死进程来解决。其中可回收内存包括:

      • 재활용 가능한 리소스인 캐시/버퍼는 보통 파일 관리에서 파일 페이지라고 부릅니다
        • 더티 페이지는 애플리케이션에서 fsync를 통해 디스크에 동기화
        • 하여 전달됩니다. 시스템으로 넘어가면 커널 스레드 pdflush가 더티 페이지 새로 고침을 담당합니다
        • 응용 프로그램에 의해 수정되었으며 당분간 디스크에 기록되지 않은 데이터(더티 페이지)를 기록해야 합니다. 먼저 디스크에 저장한 다음 메모리를 해제할 수 있습니다
      • 매핑을 통해 얻은 파일 매핑 페이지를 해제하고 다음에 액세스할 때 파일에서 다시 읽을 수도 있습니다. 프로그램은 메모리 관리의 익명 페이지입니다. 이러한 메모리는 직접 해제할 수 없지만 Linux는 자주 액세스하지 않는 메모리를 디스크에 기록하여 메모리를 해제한 다음 액세스할 때 디스크에서 메모리를 읽는 스왑 메커니즘을 제공합니다. 다시.

        스왑 원리

        스왑의 본질은 스왑 인 및 스왑 아웃의 두 가지 프로세스를 포함하여 디스크 공간 또는 로컬 파일을 메모리로 사용하는 것입니다.

        • 스왑 아웃: 메모리 프로세스에서 일시적으로 사용되지 않습니다. 데이터가 디스크에 저장되고 이 메모리가 해제됩니다.
        • 교체: 프로세스가 메모리에 다시 액세스하면 디스크에서 메모리로 읽어옵니다.

        Linux는 여부를 어떻게 측정합니까? 메모리 리소스가 부족합니까?

        • 직접 메모리 회수 새로운 대용량 블록 메모리 할당을 요청했지만 남은 메모리가 부족합니다. 이때 시스템은 메모리의 일부를 회수합니다.

        • kswapd0 커널 스레드는 정기적으로 메모리를 회수합니다. 메모리 사용량을 측정하기 위해 페이지_분, 페이지_로우, 페이지_하이의 세 가지 임계값을 정의하고 이를 기반으로 메모리 재활용 작업을 수행합니다.

          • 남은 메모리 < Pages_min, 프로세스에 사용 가능한 메모리가 소진되었습니다. 커널만 메모리를 할당할 수 있습니다.

          • pages_min < 남은 메모리 < kswapd0은 남은 메모리 > Pages_high
          • pages_low < 남은 메모리 < Pages_high까지 메모리 재활용을 수행하지만, 새로운 메모리 요청은 충족될 수 있습니다
          • 剩余内存 > pages_high,说明剩余内存较多,无内存压力

            pages_low = pages_min 5 / 4 pages_high = pages_min 3 / 2

        NUMA 与 SWAP

        很多情况下系统剩余内存较多,但SWAP依旧升高,这是由于处理器的NUMA架构。

        在NUMA架构下多个处理器划分到不同的Node,每个Node都拥有自己的本地内存空间。在分析内存的使用时应该针对每个Node单独分析

        numactl --hardware #查看处理器在Node的分布情况,以及每个Node的内存使用情况
        로그인 후 복사

        内存三个阈值可以通过/proc/zoneinfo来查看,该文件中还包括活跃和非活跃的匿名页/文件页数。

        노드에 메모리가 부족하면 시스템은 다른 노드에서 사용 가능한 리소스를 찾거나 로컬 메모리에서 메모리를 회수할 수 있습니다. /proc/sys/vm/zone_raclaim_mode를 통해 조정하세요.

        • 0은 다른 노드에서 무료 리소스를 찾을 수 있음을 의미하고 로컬 영역에서도 메모리를 회수할 수 있음을 의미합니다.
        • 1, 2, 4는 로컬 메모리만 회수된다는 의미이고, 2는 로컬 메모리만 회수된다는 의미입니다. 더티 데이터를 반환하여 메모리를 회수할 수 있습니다. 4는 스왑을 사용하여 메모리를 회수할 수 있음을 나타냅니다.

        swappiness

        Linux는 /proc/sys/vm/swapiness 옵션에 따라 Swap 사용의 활성도를 0에서 100까지 조정합니다. 값이 클수록 더 적극적입니다. 즉, 익명 페이지를 재활용하는 경우에는 값이 작을수록 Swap을 더 수동적으로 사용합니다. 즉, 파일 페이지를 재활용할 가능성이 높아집니다.

        注意:这只是调整Swap积极程度的权重,即使设置为0,当剩余内存+文件页小于页高阈值时,还是会发生Swap。

        Swap升高时如何定位分析

        free #首先通过free查看swap使用情况,若swap=0表示未配置Swap
        #先创建并开启swap
        fallocate -l 8G /mnt/swapfile
        chmod 600 /mnt/swapfile
        mkswap /mnt/swapfile
        swapon /mnt/swapfile
        
        free #再次执行free确保Swap配置成功
        
        dd if=/dev/sda1 of=/dev/null bs=1G count=2048 #模拟大文件读取
        sar -r -S 1  #查看内存各个指标变化 -r内存 -S swap
        #根据结果可以看出,%memused在不断增长,剩余内存kbmemfress不断减少,缓冲区kbbuffers不断增大,由此可知剩余内存不断分配给了缓冲区
        #一段时间之后,剩余内存很小,而缓冲区占用了大部分内存。此时Swap使用之间增大,缓冲区和剩余内存只在小范围波动
        
        停下sar命令
        cachetop5 #观察缓存
        #可以看到dd进程读写只有50%的命中率,未命中数为4w+页,说明正式dd进程导致缓冲区使用升高
        watch -d grep -A 15 ‘Normal’ /proc/zoneinfo #观察内存指标变化
        #发现升级内存在一个小范围不停的波动,低于页低阈值时会突然增大到一个大于页高阈值的值
        로그인 후 복사

        说明剩余内存和缓冲区的波动变化正是由于内存回收和缓存再次分配的循环往复。有时候Swap用的多,有时候缓冲区波动更多。此时查看swappiness值为60,是一个相对中和的配置,系统会根据实际运行情况来选去合适的回收类型.

        시스템 메모리 문제를 빠르고 정확하게 찾는 방법

        메모리 성능 표시기

        시스템 메모리 표시기

        • 사용된 메모리/남은 메모리
        • 공유 메모리(tmpfs 구현)
        • 사용 가능한 메모리: 남은 메모리와 회수 가능한 메모리 포함
        • 캐시 : 디스크 읽기 파일 페이지 캐시 , 슬래브 할당자의 재활용 가능한 부분
        • 버퍼: 원시 디스크 블록의 임시 저장, 디스크에 기록될 데이터 캐시

        프로세스 메모리 표시기

        • 가상 메모리: 최대 5개
        • 상주 메모리: 스왑 및 공유 메모리를 제외한 프로세스에서 실제로 사용하는 물리적 메모리
        • 공유 메모리: 다른 프로세스와 공유되는 메모리 및 코드 동적 링크 라이브러리 및 프로그램 세그먼트
        • 스왑 메모리: Swap을 통해 메모리를 디스크로 교체합니다. Linux 중국어 커뮤니티를 팔로우하세요

        페이지 누락 예외

        • 는 물리적 메모리에서 직접 할당할 수 있습니다. 보조 페이지 누락 예외
        • 에는 디스크 IO 개입(예: 스왑)이 필요하고 기본 페이지 누락 예외가 있습니다. 이때는 메모리 액세스가 훨씬 느려집니다

        메모리 성능 도구

        다양한 성능 지표를 기반으로 올바른 도구를 찾으세요.

        Linux 성능 전반에 걸친 튜닝 경험 요약
        사진: www.ctq6.cn

        메모리 분석 도구에 포함된 성능 지표:

        Linux 성능 전반에 걸친 튜닝 경험 요약
        사진: www.ctq6.cn

        빠른 분석 방법 기억 성능 병목 현상

        일반적으로 free, top, vmstat, pidstat 등과 같이 상대적으로 적용 범위가 넓은 여러 성능 도구를 먼저 실행합니다.

        • 먼저 free 및 top을 사용하여 시스템의 전체 메모리 사용량을 확인하세요
        • 그런 다음 vmstat 및 pidstat를 사용하여 일정 기간 동안의 추세를 확인하여 메모리 문제 유형을 확인하세요
        • 마지막으로 메모리 할당 분석, 캐시/버퍼 분석, 특정 프로세스의 메모리 사용량 분석 등 상세한 분석을 수행합니다.

        일반적인 최적화 아이디어:

        • Swap을 비활성화하는 것이 가장 좋습니다. 꼭 활성화해야 한다면 swappiness 값을 줄여보세요.
        • 메모리 풀, HugePage 등을 사용할 수 있습니다.
        • 캐시와 버퍼를 최대한 활용하여 데이터에 접근하세요. 예를 들어 스택을 사용하여 캐시해야 하는 데이터를 저장할 메모리 공간을 명시적으로 선언하거나 Redis 외부 캐시 구성 요소를 사용하여 데이터 액세스
        • cgroups 및 기타 방법을 사용하여 메모리 사용량을 제한합니다.
        • /proc/pid/oom_adj 핵심 애플리케이션의 oom_score를 조정하여 OOM에 의해 핵심 애플리케이션이 종료되지 않도록 하세요. 메모리가 부족합니다
        vmstat 사용법에 대한 자세한 설명

        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 使用详解

        pidstat主要用于监控全部或指定进程占用系统资源的情况,如CPU,内存、设备IO、任务切换、线程等。

        使用方法:

        • pidstat -d 간격 시간은 각 프로세스의 IO 사용량을 계산합니다.
        • pidstat -u 간격 시간은 각 프로세스의 CPU 통계를 계산합니다.
        • pidstat -r 간격 시간은 각 프로세스의 메모리를 계산합니다. 프로세스 사용 정보
        • pidstat -w 간격 시간 각 프로세스의 컨텍스트 전환을 계산합니다
        • p PID PID를 지정
        1.
        pidstat -d 1 10
        
        03:02:02 PM   UID       PID   kB_rd/s   kB_wr/s kB_ccwr/s  Command
        03:02:03 PM     0       816      0.00    918.81      0.00  jbd2/vda1-8
        03:02:03 PM     0      1007      0.00      3.96      0.00  AliYunDun
        03:02:03 PM   997      7326      0.00   1904.95    918.81  java
        03:02:03 PM   997      8539      0.00      3.96      0.00  java
        03:02:03 PM     0     16066      0.00     35.64      0.00  cmagent
        
        03:02:03 PM   UID       PID   kB_rd/s   kB_wr/s kB_ccwr/s  Command
        03:02:04 PM     0       816      0.00   1924.00      0.00  jbd2/vda1-8
        03:02:04 PM   997      7326      0.00  11156.00   1888.00  java
        03:02:04 PM   997      8539      0.00      4.00      0.00  java
        로그인 후 복사
        • UID
        • PID
        • kB_rd/s: 每秒进程从磁盘读取的数据量 KB 单位 read from disk each second KB
        • kB_wr/s: 每秒进程向磁盘写的数据量 KB 单位 write to disk each second KB
        • kB_ccwr/s: 每秒进程向磁盘写入,但是被取消的数据量,This may occur when the task truncates some dirty pagecache.
        • iodelay: Block I/O delay, measured in clock ticks
        • Command: 进程名 task name

        2、统计CPU使用情况

        # 统计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
        로그인 후 복사
        • UID
        • PID
        • %usr: 进程在用户空间占用 cpu 的百分比
        • %system: 进程在内核空间占用 CPU 百分比
        • %guest: 进程在虚拟机占用 CPU 百分比
        • %wait: 进程等待运行的百分比
        • %CPU: 进程占用 CPU 百分比
        • CPU: 处理进程的 CPU 编号
        • Command: 进程名

        3. 메모리 사용량 통계

        # 统计内存
        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
        로그인 후 복사
        • UID
        • PID
        • Minflt/s : 每秒次缺页错误次数 (minor page faults),虚拟内存地址映射成物理内存地址产生的 page fault 次数
        • Majflt/s : 每秒主缺页错误次数 (major page faults), 虚拟内存地址映射成物理内存地址时,相应 page 在 swap 中
        • VSZ virtual memory usage : 该进程使用的虚拟内存 KB 单位
        • RSS : 该进程使用的物理内存 KB 单位
        • %MEM : 内存使用率
        • Command : 该进程的命令 task name

        4、查看具体进程使用情况

        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
        로그인 후 복사

위 내용은 Linux 성능 전반에 걸친 튜닝 경험 요약의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:Linux中文社区
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿