본문 바로가기
서버연구 블로그 서버연구 블로그

CPU Steal Time이 높다는 것은 무엇을 의미할까? 가상 서버 성능 분석

읽는 시간 약 12분

클라우드나 가상 서버를 운영하다 보면 CPU 사용률은 그다지 높지 않은데 서버가 이상하게 느려지는 경우가 있다.

top을 확인해도 애플리케이션이 CPU를 100% 사용하고 있는 것은 아니다. 메모리도 충분하고 디스크 I/O에도 특별한 문제가 없어 보인다. 그런데 요청 처리 시간이 길어지고, 평소보다 애플리케이션의 반응이 늦어진다.

이때 반드시 확인해야 하는 지표 중 하나가 CPU Steal Time이다.

Steal Time은 일반적인 CPU 사용률과 성격이 다르다. 프로세스가 CPU를 많이 사용해서 발생하는 것이 아니라, 가상 머신이 CPU를 사용하고 싶었지만 실제 물리 CPU를 할당받지 못한 시간을 의미한다.

특히 AWS EC2, 가상화 서버, VPS, KVM 기반 환경처럼 하나의 물리 서버를 여러 가상 머신이 공유하는 구조에서는 Steal Time을 이해하지 못하면 CPU 성능 문제의 원인을 애플리케이션에서만 찾게 될 수 있다.

이번 글에서는 CPU Steal Time이 발생하는 원리부터 실제 서버에서 어떻게 확인하고 분석해야 하는지까지 운영 관점에서 살펴보자.

CPU Steal Time이 발생하는 원인

일반적인 물리 서버에서는 운영체제가 CPU 스케줄러를 통해 어떤 프로세스에 CPU 시간을 배분할지 결정한다.

하지만 가상 서버는 구조가 한 단계 더 복잡하다.

가상 머신 내부에는 Linux Kernel과 CPU Scheduler가 존재하지만, 그 아래에는 Hypervisor가 있다.

구조를 단순화하면 다음과 같다.

Application
    ↓
Guest OS
    ↓
Guest CPU Scheduler
    ↓
vCPU
    ↓
Hypervisor
    ↓
Physical CPU

Guest OS 입장에서는 vCPU가 자신의 CPU처럼 보인다.

문제는 이 vCPU가 실제 물리 CPU를 항상 독점적으로 사용하는 것은 아니라는 점이다.

예를 들어 하나의 물리 서버에 여러 가상 머신이 실행되고 있다고 생각해보자.

Physical CPU

 ├─ VM A
 │   └─ 4 vCPU
 │
 ├─ VM B
 │   └─ 4 vCPU
 │
 └─ VM C
     └─ 4 vCPU

VM A의 Linux Kernel이 어떤 프로세스를 실행하려고 해도 Hypervisor가 실제 CPU를 VM B나 VM C에 할당하고 있다면 VM A는 기다려야 한다.

바로 이 시간이 Steal Time으로 기록될 수 있다.

즉 Steal Time은 쉽게 말하면

“내 가상 서버는 CPU를 사용하려고 했지만, Hypervisor가 CPU를 다른 곳에 할당해서 기다린 시간”

이라고 이해할 수 있다.

따라서 Steal Time이 높다면 애플리케이션 자체보다 가상화 호스트의 CPU 경쟁 상황을 의심해야 한다.

Steal Time은 내부적으로 어떻게 보이는가

Linux에서는 CPU 시간을 여러 상태로 구분한다.

top 명령을 실행하면 다음과 비슷한 값을 볼 수 있다.

%Cpu(s): 20.0 us, 5.0 sy, 0.0 ni, 65.0 id,
         0.0 wa, 0.0 hi, 0.0 si, 10.0 st

여기에서 중요한 값은 st다.

us : user
sy : system
ni : nice
id : idle
wa : iowait
hi : hardware interrupt
si : software interrupt
st : steal

예를 들어 st = 10%라면 가상 머신 관점에서 CPU 실행 기회를 상당 시간 확보하지 못하고 있다는 의미로 해석할 수 있다.

여기서 중요한 점이 있다.

Steal Time은 Idle Time과 다르다.

Idle은 CPU를 사용할 작업이 없어서 쉬고 있는 시간이다.

반면 Steal은 실행할 작업이 있었음에도 가상 머신이 실제 CPU를 사용할 수 없었던 시간이다.

따라서 다음 두 상황은 완전히 다르다.

idle 70%, steal 0%
→ CPU 여유가 있는 상태

idle 40%, steal 30%
→ VM 내부에서는 여유처럼 보일 수 있지만
   상당한 CPU 시간을 Hypervisor에서 확보하지 못한 상태

이 차이를 모르고 단순히 CPU 사용률만 확인하면 가상 서버의 CPU 병목을 놓칠 수 있다.

실제 서버에서는 어떤 증상이 나타나는가

Steal Time이 높아지면 가장 먼저 나타나는 현상은 전반적인 처리 지연이다.

웹 서버라면 요청 처리 시간이 증가할 수 있다.

예를 들어 평소 100ms 정도에 처리되던 요청이 특별한 코드 변경이나 트래픽 증가가 없는데도 300ms, 500ms 이상으로 늘어날 수 있다.

애플리케이션 서버에서도 비슷한 현상이 발생한다.

프로세스는 실행 가능한 상태지만 CPU 실행 기회를 충분히 얻지 못하기 때문에 작업 완료 시간이 길어진다.

데이터베이스에서도 문제가 나타날 수 있다.

쿼리 자체는 동일하지만 CPU 실행이 지연되면서 쿼리 처리 시간이 증가할 수 있고, 이것이 누적되면 connection 증가나 요청 대기로 이어질 수 있다.

특히 문제가 되는 것은 원인이 애플리케이션 내부에 있는 것처럼 보일 수 있다는 점이다.

예를 들어 다음과 같은 현상이 동시에 나타날 수 있다.

응답 시간 증가
Load Average 상승
Run Queue 증가
Context Switch 증가
애플리케이션 처리량 감소
CPU 사용률은 예상보다 낮음

운영자가 CPU 사용률만 보면 “CPU에는 문제가 없다”고 판단하기 쉽다.

하지만 실제로는 VM이 CPU를 충분히 배정받지 못하고 있을 수 있다.

Steal Time은 어떻게 분석해야 할까

가장 간단한 방법은 top이다.

top

CPU 영역에서 다음 값을 확인한다.

st

순간적인 값보다 일정 시간 지속되는지가 중요하다.

보다 지속적으로 확인하려면 vmstat도 사용할 수 있다.

vmstat 1

출력 마지막 부분에는 다음과 같은 CPU 정보가 나타난다.

us sy id wa st

여기에서도 st가 Steal Time이다.

1초 간격으로 확인하면 Steal Time이 순간적으로 발생하는지 지속적으로 발생하는지 파악하기 쉽다.

CPU별 상태를 자세히 보고 싶다면 mpstat도 유용하다.

mpstat -P ALL 1

여기에서는 %steal 항목을 확인한다.

예를 들어 특정 시간대에 다음과 같이 나타난다고 가정해보자.

CPU   %usr  %sys  %idle  %steal

all   25.0   5.0   50.0    20.0

단순 계산으로는 CPU가 30% 정도만 사용되는 것처럼 보일 수 있다.

하지만 Steal Time이 20%라면 이야기가 달라진다.

VM이 원하는 만큼 CPU 실행 시간을 확보하지 못하고 있을 가능성을 함께 조사해야 한다.

장기간 추세를 확인하는 것도 중요하다.

sar -u 1 10

또는 모니터링 시스템을 사용한다면 CPU Steal 지표를 별도로 수집하는 것이 좋다.

Prometheus Node Exporter 환경에서는 CPU mode별 메트릭을 이용해 steal 시간을 추적할 수 있다.

중요한 것은 특정 순간의 숫자 하나로 결론을 내리지 않는 것이다.

CPU Usage
Steal Time
Load Average
Run Queue
Context Switch
Request Latency
Throughput

이 지표들을 같은 시간축에서 비교해야 한다.

예를 들어 요청 지연이 발생한 시간과 Steal Time 상승 시간이 정확히 겹친다면 가상화 계층의 CPU 경쟁 가능성이 훨씬 높아진다.

Steal Time이 높다면 어떻게 해결해야 할까

Steal Time 문제는 일반적인 CPU 튜닝과 접근 방식이 다르다.

애플리케이션이 CPU를 과도하게 사용한다면 코드 최적화, 프로세스 조정, CPU 증설 등을 고려할 수 있다.

하지만 Steal Time은 VM 외부의 자원 경쟁에서 발생할 수 있기 때문에 Guest OS 내부 설정만 변경해서 해결되지 않는 경우가 많다.

먼저 가상 머신의 CPU 할당 구조를 확인해야 한다.

자체 가상화 환경이라면 물리 호스트에서 vCPU가 지나치게 많이 할당되어 있지 않은지 확인한다.

예를 들어 물리 CPU 자원에 비해 지나치게 많은 vCPU를 배정하는 CPU Overcommit이 발생하면 여러 VM이 동시에 CPU를 요구할 때 경쟁이 심해질 수 있다.

Physical CPU capacity
        ↓
과도한 vCPU 할당
        ↓
여러 VM 동시 CPU 요청
        ↓
Hypervisor CPU 경쟁
        ↓
Steal Time 증가

클라우드 환경에서는 인스턴스 유형과 CPU 제공 방식도 확인해야 한다.

공유형 또는 버스트 특성이 있는 인스턴스는 전용 CPU 자원을 제공하는 환경과 성능 특성이 다를 수 있다.

따라서 단순히 “vCPU가 몇 개냐”만 보는 것이 아니라 해당 인스턴스가 어떤 방식으로 CPU 자원을 제공하는지 확인해야 한다.

지속적으로 높은 Steal Time과 성능 저하가 함께 관찰된다면 인스턴스 유형 변경이나 CPU 자원 확대, 호스트 배치 변경 등을 검토할 수 있다.

자체 가상화 서버라면 특정 호스트에 VM이 지나치게 몰려 있는지도 확인해야 한다.

경우에 따라 VM을 다른 물리 호스트로 이동하는 것만으로도 CPU 경쟁이 줄어들 수 있다.

다만 Steal Time이 조금 보인다는 이유만으로 바로 인프라를 변경해서는 안 된다.

Steal Time 자체보다 중요한 것은 서비스 성능과의 상관관계다.

예를 들어 일시적으로 2~3%가 나타났지만 요청 지연이나 처리량 변화가 없다면 즉각적인 장애로 볼 필요는 없다.

반대로 Steal Time이 지속적으로 상승하면서 응답 시간이 증가하고 Run Queue까지 길어진다면 실제 CPU 실행 기회 부족을 의심할 근거가 강해진다.

정리

가상 서버에서 CPU 성능을 분석할 때 단순한 CPU 사용률만 보는 것은 충분하지 않다.

가상 머신의 CPU는 물리 CPU 그 자체가 아니라 Hypervisor를 통해 제공되는 vCPU이기 때문이다.

Guest OS가 CPU를 사용하려고 해도 Hypervisor가 실제 CPU를 다른 VM에 할당하고 있다면 실행이 지연될 수 있으며, 이 시간이 Linux에서 Steal Time으로 관찰될 수 있다.

핵심은 다음과 같다.

CPU 사용률이 낮다
        ≠
CPU 자원을 충분히 받고 있다

가상 서버에서는 반드시 다음 흐름으로 확인하는 것이 좋다.

응답 시간 증가
      ↓
CPU Usage 확인
      ↓
Load Average / Run Queue 확인
      ↓
Steal Time 확인
      ↓
서비스 지표와 시간대 비교
      ↓
VM 내부 문제인지
Hypervisor 자원 경쟁인지 구분

특히 클라우드와 가상화 환경에서는 Steal Time을 모르고 있으면 서버가 느려진 원인을 애플리케이션, 데이터베이스, Linux 설정에서만 찾게 될 수 있다.

51번에서 살펴본 CPU Scheduler가 Linux 내부에서 CPU 시간을 어떻게 배분하는가에 대한 문제였다면, 52번 Context Switch는 CPU가 실행 대상을 변경할 때 발생하는 비용에 대한 문제였다.

그리고 이번 Steal Time은 한 단계 더 아래로 내려가 가상 머신 자체가 물리 CPU 실행 시간을 얼마나 확보하고 있는가를 보는 지표다.

결국 서버 CPU 성능 분석에서는 CPU 사용률 하나가 아니라 Scheduler → Run Queue → Context Switch → Steal Time → 실제 서비스 응답 시간을 하나의 흐름으로 연결해서 보는 것이 중요하다.

instone
함께 보면 좋은 글

댓글 0

첫 댓글을 남겨보세요.

error: Content is protected !!

광고 차단 알림

광고 클릭 제한을 초과하여 광고가 차단되었습니다.

단시간에 반복적인 광고 클릭은 시스템에 의해 감지되며, IP가 수집되어 사이트 관리자가 확인 가능합니다.