CPU 사용률은 높지만로드 평균은 낮습니다.


28

CPU 사용률은 높지만로드 평균은 매우 낮은 이상한 동작이 발생합니다.

동작은 모니터링 시스템의 다음 그래프로 가장 잘 설명됩니다.

CPU 사용량 및로드

약 11:57에서 CPU 사용률은 25 %에서 75 %로 증가합니다. 로드 평균은 크게 변경되지 않습니다.

각각 2 개의 하이퍼 스레드가있는 12 개의 코어가있는 서버를 실행합니다. OS는 이것을 24 개의 CPU로 본다.

CPU 사용률 데이터는 /usr/bin/mpstat 60 11 분마다 실행 하여 수집됩니다 . all행과 %usr열의 데이터는 위 차트에 표시되어 있습니다. 이것이 "스택 된"사용률이 아니라 CPU 당 평균 데이터를 표시한다고 확신합니다 . 차트에서 75 %의 사용률을 볼 수 있지만에서 약 2000 %의 "스택 된"CPU를 사용하는 프로세스가 표시됩니다 top.

부하 평균 수치는 /proc/loadavg각 분 에서 가져옵니다 .

uname -a 제공합니다 :

Linux ab04 2.6.32-279.el6.x86_64 #1 SMP Wed Jun 13 18:24:36 EDT 2012 x86_64 x86_64 x86_64 GNU/Linux

리눅스 dist는 Red Hat Enterprise Linux Server release 6.3 (Santiago)

우리는 머신에 상당히 많은 부하를 두어 두 개의 Java 웹 애플리케이션을 실행합니다. 머신 당 100 개의 요청을 생각합니다.

CPU 사용률 데이터를 올바르게 해석하면 CPU 사용률이 75 % 일 때 CPU가 평균 75 %의 시간 동안 프로세스를 실행하고 있음을 의미합니다. 그러나 CPU가 시간의 75 %를 사용하는 경우로드 평균이 더 높지 않아야합니까? 실행 대기열에 2-4 개의 작업 만있는 동안 어떻게 CPU가 75 % 바쁠 수 있습니까?

데이터를 올바르게 해석하고 있습니까? 이 문제의 원인은 무엇입니까?


모니터링 시스템에 정규화 된 CPU로드 (로드 / # CPU)가 표시됩니까? 일반적인 Linux CPU로드는 코어 / CPU 수가 다른 시스템에서 비교하기 어렵 기 때문에 일부 도구는 표준화 된 CPU로드를 대신 사용합니다.
Brian

각 데이터 포인트를 CPU 수로 나누는 것을 의미합니까? 우리의 경우 즉 loadavg / 24? 도움이된다면 데이터에서 그러한 차트를 쉽게 만들 수 있습니다.
K Erlandsson '12

나는 당신의 차트가 이미 그것을 보여주고 있다고 제안하고있었습니다.
Brian

아, 오해해서 미안해 좋은 설명이되었지만 불행히도 시스템 전체의 부하 평균입니다. 난 그냥 트리플 확인했다.
K Erlandsson '12

답변:


51

Linux에서 최소한로드 평균과 CPU 사용률은 실제로 두 가지입니다. 로드 평균은 일정 기간 동안 커널 실행 큐 (CPU 시간뿐만 아니라 디스크 활동)에서 대기중인 작업 수를 측정 한 것입니다. CPU 사용률은 현재 CPU 사용량을 나타내는 척도입니다. 단일 CPU 스레드가 1 분 동안 100 %로 페깅 된 최대로드는 1 분로드 평균에 "기여"될 수 있습니다. 1 분 동안 100 %의 하이퍼 스레딩 (8 개의 가상 코어)이있는 4 개의 코어 CPU는 8에 기여합니다. 1 분로드 평균

종종이 두 숫자는 서로 상관 관계가있는 패턴을 갖지만 같은 것으로 생각할 수는 없습니다. 거의 0 %의 CPU 사용률 (대기 상태에 많은 IO 데이터가 고착 된 경우)로 높은로드를 가질 수 있으며 단일 스레드 프로세스가 실행중인 경우 1 및 100 % CPU의로드를 가질 수 있습니다. 풀 틸트. 또한 짧은 기간 동안 CPU가 100 %에 가깝다는 것을 알 수 있지만 평균 메트릭이 아직 "포착되지"않았기 때문에로드는 여전히 1 미만입니다.

서버의로드가 15,000 (예 : 실제로 오타가 아님) 이상이고 CPU %가 0 %에 가까워졌습니다. Samba 공유에 문제가 있었기 때문에 많은 클라이언트가 IO 대기 상태에 빠지기 시작했습니다. CPU 활동이없는 규칙적인 높은로드 번호가 표시되면 어떤 종류의 스토리지 문제가있는 것입니다. 가상 머신에서 이는 동일한 VM 호스트에서 스토리지 자원을 위해 경쟁하는 다른 VM이 있음을 의미 할 수도 있습니다.

높은 부하도 반드시 나쁜 것은 아닙니다. 대부분의 경우 시스템이 최대 용량으로 사용 중이거나 유지할 수있는 용량을 초과했음을 의미합니다 (부하 수가 프로세서 코어 수보다 많은 경우). 내가 sysadmin으로 근무했던 곳에서 Nagios보다 기본 시스템의 부하 평균을 더 가까이에서 관찰 한 사람이있었습니다. 부하가 높을 때는 SMTP보다 훨씬 빠르게 24/7로 전화합니다. 대부분의 경우 실제로 잘못된 것은 없었지만,로드 번호를 잘못된 것으로 연결하여 매처럼 보았습니다. 확인 후 내 응답은 일반적으로 시스템이 작업을 수행하고 있다는 것입니다. 물론 이것은 부하가 15000 (동일한 서버는 아님) 이상이 된 동일한 장소 였기 때문에 때로는 무언가 잘못되었음을 의미합니다. 시스템의 목적을 고려해야합니다. 그것이 주력이라면, 부하가 당연히 높을 것으로 기대하십시오.


단일 스레드 프로세스로 1 및 100 % CPU를로드 할 수 있다는 것을 어떻게 의미합니까? 어떤 종류의 스레드에 대해 이야기하고 있습니까? 우리가 Java 프로세스를 고려하면 많은 스레드가 있지만 OS의 관점에서 스레드가 프로세스로 처리된다는 가정하에 있습니다 (결국 Linux에서 별도의 PID가 있음). 단일 멀티 스레드 Java 프로세스가로드 평균 관점에서 하나의 작업으로 만 계산되도록 할 수 있습니까?
K Erlandsson 2019

방금 자체 테스트를했는데 Java 프로세스의 스레드는 별도의 프로세스 (즉, 바쁜 대기 루프에서 10 개의 스레드를 실행하는 Java 클래스가 10에 가까운 부하를 제공하는 것처럼) 평균로드에 기여합니다. 위에서 언급 한 스레드 프로세스에 대한 설명을 부탁드립니다. 고맙습니다!
K Erlandsson 2013

멀티 스레딩이 아닌 프로세스 (즉, 한 번에 하나의 CPU 만 사용하는 프로세스)가 있다면 의미합니다. 예를 들어 사용중 루프를 실행하는 간단한 C 프로그램을 작성하는 경우 단일 스레드 만 실행되고 한 번에 하나의 CPU 만 사용합니다.
deltaray

내가 찾은 모든 정보는 스레드가 커널에서 보았을 때와 부하를 계산할 때 별도의 프로세스로 계산한다고 말합니다. 따라서 멀티 틸트 시스템에서 멀티 스레드 프로세스를 사용하여 전체 틸트에서 1로드 및 100 % CPU를 얻는 방법을 알 수 없습니다. 당신이 무슨 뜻인지 이해하도록 도와 주실 수 있습니까?
K Erlandsson

Brendan Gregg의 "리눅스로드 평균 : 수수께끼 풀기"에 대한 자세한 내용 은 필자가 필요로하는 모든 답을 가지고있었습니다.
Nickolay

24

로드는 매우기만적인 숫자입니다. 소금 한알과 함께 섭취하십시오.

매우 빠르게 연속적으로 많은 작업을 생성하여 매우 빠르게 완료되는 경우 실행 큐의 프로세스 수가 너무 작아서로드를 등록 할 수 없습니다 (커널 수는 5 초마다 한 번씩로드).

8 개의 논리 코어가있는 호스트 에서이 예제를 고려하면이 파이썬 스크립트는 많은 CPU 사용량을 최고 (약 85 %)로 등록하지만 거의로드하지 않습니다.

import os, sys

while True:
  for j in range(8):
    parent = os.fork()
    if not parent:
      n = 0
      for i in range(10000):
        n += 1
      sys.exit(0)
  for j in range(8):
    os.wait()

다른 구현으로, 이것은 wait8 그룹으로 피 합니다 (테스트를 왜곡시킵니다). 여기서 부모는 항상 자식 수를 활성 CPU 수로 유지하려고 시도하므로 첫 번째 방법보다 훨씬 더 바쁘고 더 정확할 것입니다.

/* Compile with flags -O0 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <err.h>
#include <errno.h>

#include <sys/signal.h>
#include <sys/types.h>
#include <sys/wait.h>

#define ITERATIONS 50000

int maxchild = 0;
volatile int numspawned = 0;

void childhandle(
    int signal)
{
  int stat;
  /* Handle all exited children, until none are left to handle */
  while (waitpid(-1, &stat, WNOHANG) > 0) {
    numspawned--;
  }
}

/* Stupid task for our children to do */
void do_task(
    void)
{
  int i,j;
  for (i=0; i < ITERATIONS; i++)
    j++;
  exit(0);
}

int main() {
  pid_t pid;

  struct sigaction act;
  sigset_t sigs, old;

  maxchild = sysconf(_SC_NPROCESSORS_ONLN);

  /* Setup child handler */
  memset(&act, 0, sizeof(act));
  act.sa_handler = childhandle;
  if (sigaction(SIGCHLD, &act, NULL) < 0)
    err(EXIT_FAILURE, "sigaction");

  /* Defer the sigchild signal */
  sigemptyset(&sigs);
  sigaddset(&sigs, SIGCHLD);
  if (sigprocmask(SIG_BLOCK, &sigs, &old) < 0)
    err(EXIT_FAILURE, "sigprocmask");

  /* Create processes, where our maxchild value is not met */
  while (1) {
    while (numspawned < maxchild) {
      pid = fork();
      if (pid < 0)
        err(EXIT_FAILURE, "fork");

      else if (pid == 0) /* child process */
        do_task();
      else               /* parent */
        numspawned++;
    }
    /* Atomically unblocks signal, handler then picks it up, reblocks on finish */
    if (sigsuspend(&old) < 0 && errno != EINTR)
      err(EXIT_FAILURE, "sigsuspend");
  }
}

이 동작의 이유는 알고리즘이 실제 작업을 실행하는 것 (10000까지 계산)보다 자식 프로세스를 만드는 데 더 많은 시간을 소비하기 때문입니다. 아직 생성되지 않은 작업은 '실행 가능'상태로 계산할 수 없지만 생성 된 CPU 시간에 % sys를 차지합니다.

따라서 어떤 작업을 수행하든 많은 수의 작업이 빠르게 연속적으로 생성됩니다 (스레드 또는 프로세스).


제안 해 주셔서 감사합니다. 내 질문에있는 차트는 % 사용자 시간을 보여줍니다 (CPU 시스템 시간은 제외되며 시스템 시간은 약간만 증가합니다). 어쨌든 많은 작은 작업이 설명이 될 수 있습니까? 로드 평균이 5 초마다 샘플링되면 mpstat에서 제공 한 CPU 사용률 데이터가 더 자주 샘플링됩니까?
K Erlandsson '

CPU 샘플링이 어떻게 수행되는지 익숙하지 않습니다. 커널 소스를 읽지 마십시오. 내 예제에서 % usr은 70 % +이고 % sys는 15 %입니다.
Matthew Ife

좋은 예!
Xavier Lucas

5

로드 평균이 크게 증가하지 않으면 하드웨어 사양과 처리 할 작업의 특성으로 인해 전체 처리량이 향상되어 일정 시간 동안 작업 대기열에 쌓이지 않아도됩니다.

예를 들어 평균 작업 복잡성이 너무 높거나 작업 평균 처리 시간이 너무 많은 CPU주기를 필요로하여 경합 현상이 발생하면로드 평균이 증가합니다.

업데이트 :

내 원래의 대답에는 명확하지 않을 수 있으므로 지금 명확히하고 있습니다.

하중 평균 계산의 정확한 공식은 다음과 같습니다 loadvg = tasks running + tasks waiting (for cores) + tasks blocked.

좋은 처리량을 확보 할 수 있으며 작업 처리 시간에 대한 페널티없이로드 평균 24에 가까워 질 수 있습니다. 반면에 2-4 개의 주기적 작업이 충분히 빨리 완료되지 않은 경우 (CPU주기 동안) 대기중인 작업 수가 늘어나고 결국로드 평균이 높아집니다. 발생할 수있는 또 다른 작업은 뛰어난 동기식 I / O 작업을 실행 한 다음 코어를 차단하여 처리량을 낮추고 대기중인 작업 대기열을 늘리는 것입니다 (이 경우 iowait메트릭이 변경 될 수 있음 )


로드 평균에는 현재 실행중인 작업도 포함된다는 것을 이해합니다. 이는 CPU에 대한 실제 경합없이로드 평균을 확실히 증가시킬 수 있음을 의미합니다. 아니면 내가 당신을 착각하거나 오해하고 있습니까?
K Erlandsson '12

@KristofferE 당신은 완전히 옳습니다. 실제 공식은 loadavg = taks 실행 + 작업 대기 (사용 가능한 코어) + 작업 차단입니다. 즉,로드 평균 24를 가질 수 있으며 작업이 대기 중이거나 차단되지 않아 경합없이 "전체 사용량"또는 하드웨어 용량 만 가질 수 있습니다. 로드 평균 대 실행중인 프로세스 수 대 CPU 사용에 대해 혼란스러워 보였으므로 전체적으로 실행중인 프로세스가 거의없는 상태에서로드 평균이 여전히 어떻게 증가 할 수 있는지에 대한 설명에 중점을 두었습니다. 다시 읽은 후에는 분명하지 않을 수 있습니다.
Xavier Lucas

2

로드 평균에는 디스크 IO에서 차단 된 작업이 포함되므로 매우 느린 디스크에서 10 개의 작업을 모두 읽으려고하면 CPU 사용률이 0이고로드 평균은 10입니다. 따라서 사용량이 많은 서버가 디스크 스레 싱을 시작하는 것이 일반적이며 모든 검색은 많은 차단 된 작업으로 인해로드 평균을 높이는 반면 CPU 사용량은 감소합니다. 모든 작업은 디스크에서 차단되기 때문입니다.


1

Matthew Ife의 답변은 매우 도움이되었고 올바른 방향으로 우리를 이끌었지만 우리 사건의 원인은 정확히 아니 었습니다. 우리의 경우에는 스레드 풀링을 사용하는 멀티 스레드 Java 응용 프로그램이 있는데 실제 작업을 만드는 작업이없는 이유는 무엇입니까?

그러나 스레드가 실제로 수행하는 작업은 수명이 짧으며 IO 대기 또는 동기화 혼잡 대기를 포함합니다. Matthew가 자신의 답변에서 언급했듯이 OS에서로드 평균을 샘플링하므로 수명이 짧은 작업을 놓칠 수 있습니다.

동작을 재현하는 Java 프로그램을 만들었습니다. 다음 Java 클래스는 서버 중 하나에서 28 % (650 % 누적)의 CPU 사용률을 생성합니다. 이 작업을 수행하는 동안로드 평균은 약 1.3입니다. 여기서 핵심은 스레드 내부의 sleep ()이며로드 계산이 정확하지 않습니다.

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class MultiThreadLoad {

    private ThreadPoolExecutor e = new ThreadPoolExecutor(200, 200, 0l, TimeUnit.SECONDS,
            new ArrayBlockingQueue<Runnable>(1000), new ThreadPoolExecutor.CallerRunsPolicy());

    public void load() {
        while (true) {
            e.execute(new Runnable() {

                @Override
                public void run() {
                    sleep100Ms();
                    for (long i = 0; i < 5000000l; i++)
                        ;
                }

                private void sleep100Ms() {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            });
        }
    }

    public static void main(String[] args) {
        new MultiThreadLoad().load();
    }

}

요약하자면, 이론은 애플리케이션의 스레드가 많이 유휴 상태를 유지 한 다음 수명이 짧은 작업을 수행한다는 것인데, 그 이유는 작업이로드 평균 계산으로 올바르게 샘플링되지 않은 이유입니다.


0

로드 평균은 CPU 큐의 평균 프로세스 수입니다. 각 시스템에 따라 다르므로 한 LA가 모든 시스템에서 일반적으로 높고 다른 LA가 낮다고 말할 수는 없습니다. 따라서 12 개의 코어가 있으며 LA가 크게 증가하려면 프로세스 수가 실제로 높아야합니다.

또 다른 질문은 "CPU 사용량"그래프의 의미입니다. SNMP에서 가져온 것처럼 SNMP 구현이 net-snmp이면 12 개 CPU 각각에서 CPU로드를 스택합니다. 따라서 net-snmp총 CPU로드 량은 1200 %입니다.

내 가정이 맞다면 CPU 사용량이 크게 증가하지 않았습니다. 따라서 LA는 크게 증가하지 않았습니다.


CPU 사용량은 all행인 mpstat에서 가져 옵니다. 나는 그것이 모든 CPU에서 평균이라고 확신하지만, 쌓이지 않았습니다. 예를 들어, 문제가 발생하면 top은 한 프로세스의 CPU 사용량을 2000 %로 표시합니다. 그것은 누적 된 사용법입니다.
K Erlandsson '12

0

이 시나리오는 조금 이상하지만 특별히 예상치 못한 것은 아닙니다. Xavier가 다루지 만 많이 개발하지 않는 것은 Linux (기본적으로)와 유닉스의 대부분의 풍미가 건강한 머신에서 선제적인 멀티 태스킹을 구현하더라도 작업이 선점되는 경우는 거의 없다는 것입니다. 각 작업은 CPU를 점유하는 시간 조각으로 표시되며,이 시간을 초과하고 실행 대기중인 다른 작업이있는 경우에만 선점됩니다 (load는 CPU 및 실행 대기 중 평균 프로세스 수를보고합니다) . 대부분의 경우 프로세스가 중단되지 않고 처리됩니다.

(일반적으로 스케줄러가 선점 작업을 시작할 때 CPU 수에 가까워 질 때로드에 대해서만 걱정하면됩니다.)

CPU가 시간의 75 %를 사용하는 경우로드 평균이 더 높지 않아야합니까?

활동 패턴에 관한 모든 것, 일부 작업 (소수의 작은 수의 가능성)에 의해 CPU 사용률이 분명히 증가하여 다른 작업의 처리에 부정적인 영향을 미치지 않았습니다. 처리중인 트랜잭션을 분리 할 수 ​​있다면, 기존 작업 세트에는 영향을 미치지 않으면 서 속도 저하 중에 새로운 그룹이 나타날 것으로 예상됩니다.

최신 정보

CPU 부하가 크게 증가하지 않고 높은 CPU가 발생할 수있는 일반적인 시나리오 중 하나는 작업이 다른 작업 중 하나 (또는 ​​시퀀스)를 트리거하는 경우입니다 (예 : 네트워크 요청을 수신하면 처리기가 요청을 별도의 스레드, 별도의 스레드로 라우팅 함) 그런 다음 다른 프로세스에 대한 비동기 호출을 수행합니다 .... Runqueue의 샘플링으로 인해로드가 실제보다 낮게보고됩니다. 그러나 CPU 사용량에 따라 선형으로 증가하지는 않습니다. 트리거 된 작업 체인은 실행되지 않은 상태에서 실행할 수 없었습니다. 초기 이벤트 및 순차적으로 발생하기 때문에 (대략) 실행 큐가 팽창되지 않습니다.


OP는 원래 집계 CPU %가 "2000 %"였다는 표시를 제공했습니다. 하나의 사용 중 프로세스가 아니라 CPU를 사용하는 많은 작업이 있음을 나타냅니다. 1 분 동안 일관된 2000 % 인 경우 일반적으로 부하가 20-ish 인 것으로 예상합니다.
Matthew Ife

... 의견이 아닌 의견으로 그는 확실하지 않습니다. 'ALL'옵션이 없으면 mpstat는 평균이 아닌 총 % 사용량을보고합니다. 그러나 그것은 대답을 바꾸지 않습니다-그것은 활동의 패턴에 관한 것입니다.
symcbean

차트에서 볼 수있는 CPU 유틸리티가 "CPU 당 평균"이라고 100 % 긍정적입니다. Mpstat는 ALL없이 실행되지만 CPU 별 정보 만 남기고 all행에는 여전히 CPU 당 평균이 표시됩니다. 나는 질문을 명확히 할 것이다.
K Erlandsson

마지막 섹션을 조금 더 자세히 설명해 주시겠습니까? 나는 당신이 무엇을 의미하는지 이해하지 못하지만, 당신이 인용 한 내 질문의 일부는 내가 이해하기 가장 어려운 부분입니다.
K Erlandsson
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.