load average란?
프로세스의 여러 상태 중 R 또는 D 상태에 있는 프로세스들의 개수를 1분, 5분, 15분 단위로 평균값을 나타낸 값이다.
부하 값이 일정량 높은 수준에서,
1분 동안의 값이 15분 값에 비해서 작다면 이는 장애가 발생한 지 좀 된 것이며,
1분값 < 15분값 = 장애가 발생 좀 됨
15분 값에 비해 1분, 5분 값이 높다면 점점 더 부하가 심해지고 있는 것
1분값 > 15분값 = 부하가 심해지고 있음.
중요
Load Average가 높다는 것은 많은 프로세스가 현재 실행 중이거나,
네트워크 또는 디스크 작업을 처리하기 위한 대기 상태에 있다는 것
cpu 코어가 4개짜리와 1개짜리를 사용하는 환경에서 load average가 8이라고 하면 둘 다 동일한 load average를 갖고 있는 걸까?
load average는 코어의 값에 따라 상대적이다.
load average 8은 코어 4개가 각각 동시에 동작하므로 2에 가까우며,
코어 1개에서의 load average 8은 한 번에 하나만 실행하게 되므로 8을 나타낸다고 볼 수 있음.
status
R
: Running 상태로써 프로세스가 실제로 CPU 자원을 소모하고 있는 실행 중인 상태. R이 많다는 것은 CPU 리소스 측면에서 부하가 있다는 것으로 판단할 수 있음.D
: Uninterruptible Sleep 상태로써 인터럽트에 의해서 상태가 변경되지 않는 대기 상태.
현재 대기의 대상이 끝날 때 까지 방해받지 않고 대기한다. 보통 디스크 또는 네트워크 등 I/O 작업 처리를 대기 중인 프로세스의 상태를 말함
프로세스가 디스크 읽기 또는 쓰기 작업을 하거나 네트워크 작업을 하게 될 경우, 디스크 디바이스나 네트워크 디바이스에게 요청을 보내게된다.
이렇게 되면 프로세스 입장에서 요청에 대한 응답이 올 때까지 아무것도 할 수 없기 때문에 Wait Queue로 들어가며,
자신을 uninterruptible 상태로 마킹한다.
해당 상태가 많다는 것은 특정 요청이 끝나기를 기다리는 프로세스가 많다는 것
이 프로세스들은 요청이 끝나면 다시 R로 돌아가게 되어 시스템의 부하를 계산하는데 포함된다.
만일 특정 프로세스가 'D'인 상태에서 오래 머무른다면?
- 스토리지의 I/O가 종료되지 않은 상태로 되어 있다.
- 커널 내에 문제가 발생했다.
S
: Sleeping 상태로써 동작이 중지된 상태. 일시 정지 된 상태로 인터럽트 신호를 받을 때 까지 멈춰있게 된다.
D 옵션과 다르게 언제든 시그널을 받게 되면 바로 R 상태로 진입하여 처리가 가능하다.
시스템 콜 등을 호출하여 타이머를 작동 시키거나, 콘솔의 입력을 기다리는 프로세스들의 상태이다.
시그널을 받았을 때 처리할 수 있도록 Interruptible 상태로 마킹 후 대기상태로 변환된다.
sleep
-> 터미널의 입력대기가 이런 상태로 진입하게 된다.Z
: 좀비 상태의 프로세스이다. 부모 프로세스가 죽은 자식 프로세스를 의미
Fork()를 통해 새로운 자식 프로세스를 실행시키고 부모 프로세스가 비정상적인 동작으로 죽었을 경우
자식 프로세스는 자신이 종료될 곳을 알려줄 방법이 없어 좀비 프로세스가 된다. 이미 사용 중지된 프로세스 이므로, CPU를 사용하지 않으며 메모리를 사용하지 않아도 된다. 하지만 PID를 소유하고 있으므로 PID 고갈이 일어날 수 있다.
명령어를 통해 확인하는 방법
1) uptime
2) cat /proc/loadavg
3) top htop 등등 모니터링 명령어
Load Average가 높아졌을 때 어떻게 해야 할까?
D와 R의 상태를 지닌 프로세스의 개수가 핵심이라고 했다. 이 말을 잘 생각해 보면,
Load Average가 높을 때 *R 상태의 프로세스의 개수가 많아져서 인지 D상태의 프로세스가 많아서인지 구분해야 한다는 말이다.
R의 상태는 실행 중인 프로세스로 CPU 리소스를 사용 중인 상태이다. ---> CPU 리소스 부하를 의미
D의 상태는 네트워트 또는 디스크의 응답을 대기하는 상태. ---> I/O 부하를 의미
부하 구분하기 vmstat
while 문을 사용하여 무제한 연산하는 프로그램이나, fopen을 통해 계속 파일을 열고 닫는 프로그램이나
Load Average는 동일하게 상승한다. 하지만 둘은 엄연히 다른 종류의 부하이다.
바로 vmstat
라는 툴을 사용해서 알 수 있다.
vmstat(Virual Memory statics)은 현재 메모리 및 CPU의 사용률을 알 수 있는 툴이다.
여기서 앞에 r과 b를 살펴보면
r은 실행되기를 기다리거나 실행 중인 프로세스의 개수를 나타내며
b는 uninterruptible sleep 상태의 프로세스로 I/O를 위해 대기열에 있는 프로세스의 개수를 나타낸다.
그러므로 r은 R 상태의 프로세스 개수이며 b는 D상태의 프로세스 개수를 나타낸다
load average가 높아졌을 때는 vmstat을 통해 CPU리소스 부하(R) 때문인지
I/O 부하(D) 때문인지 원인 파악이 가능하다.
각 CPU코어마다 running중인 프로세스의 개수는?
각 코어 기준이 아니라면 단순히 top 명령어를 통해 'S' 필드의 값이 R인 프로세스를 찾아도 된다.
그런데 각 코어 별 runnung 프로세스의 정보를 알고 싶다면 어떻게 해야 할까?
# cat /proc/sched_debug
로 파일을 확인하면 된다.
실행 스케줄러 현재 조율 값, cfs 통계, 사용 가능한 모든 CPU에서 실행 큐 정보를 출력한다. 따라서 각 코어별 R 상태의 개수와 해당 프로세스를 확인할 수 있다.
각각의 부하는 시스템에 동일한 영향을 미칠까?
CPU 리소스 사용률이 높은 CPU 부하는 I/O 부하와 달리 CPU 점유율에 있어서 경쟁상태가 된다.
특정 프로세스가 장시간 I/O를 점유하고 있으면 같은 자원을 사용하려는 다른 프로세스 I/O처리를 위한 대기시간에 크게 영향을 미치기 때문에 겉으로 보기에는 Load Average가 높지 않지만 실제 시스템에서 I/O 및 Buffer를 거치는 작업 등에서 지연을 경험할 수도 있다.
반대로 Load Average가 높지만 다른 프로세스와 동일한 자원을 사용하지 않는 I/O처리 대기나 프로세스 간에 Context switching이 원할할 경우 성능저하가 느껴지지 않을 수도 있다.
즉, CPU 리소스를 서로 점유하기 위하여 경쟁하게 되며 이는 해당 프로세스의 성능 저하로 이어지게 된다.반면에 I/O 부하의 경우 상대적으로 CPU 경쟁이 낮다 보니 CPU 부하와 다른 결과가 나오게 된다.
그렇다면 CPU부하(R)보다 I/O부하(D)가 더 나은걸까? >> 그건 아니다
해결방안은?
R 프로세스가 많다는 것은 CPU 리소스 부하를 발생시기는 프로세스가 많다는 것으로 해석할 수 있다.
대표적으로 다음과 같은 두가지로 나눌 수 있다.
1) CPU, 메모리 사용량 이외에는 정상적인 경우
2) 특정 프로그램의 CPU 점유율이 매우 높은 경우
전자의 상태에의 경우, 프로그램의 로직이나 알고리즘을 개선 또는 하드웨어 개선을 통해서 대응해야 한다.
후자의 경우 오류를 제거하여 프로그램이 정상 동작하도록 수정해야 한다.
D 프로세스가 많다는 것은, I/O 요청으로 인한 대기중인 프로세스가 많다는 것이다.
다음 두 가지로 해석 가능하다.
1) 프로그램으로부터 입출력이 많아서 부하가 높은경우
2) Swapping이 발생해서 디스크 엑세스가 발생하고 있는 상황인 경우
1번의 경우 프로그램의 파일 입출력 부분을 개선해서 대응한다.
2번의 경우 특정 프로세스가 극단적으로 메모리를 소비하고 있지 않은지를 ps로 확인하며, 프로그램의 오류로 메모리를 지나치게 사용하고 있는 경우에는 프로그램을 개선한다.
또는, 물리적인 램을 증설하는 방법이 있다.