오전 10시, 결제 API 응답 시간이 평소보다 10배 느리다는 알림이 왔습니다. 사용자들이 결제 버튼을 눌렀다 오류가 난다고 CS 문의가 쏟아집니다. 서버에 접속했는데 어디서부터 봐야 할지 모릅니다. CPU 문제인지, 메모리가 부족한지, 디스크가 꽉 찼는지 — 잘못된 곳을 먼저 보면 10분이 지나도 원인을 못 찾습니다. 올바른 순서로 올바른 도구를 쓰면 3분 안에 병목을 특정할 수 있습니다.
시스템 리소스 모니터링과 성능 분석
서버가 갑자기 느려졌을 때, "CPU 문제인가? 메모리인가? 디스크인가?"를 5분 안에 판단할 수 있어야 합니다. 이 모듈에서는 실무에서 가장 자주 쓰는 성능 진단 도구들을 체계적으로 다룹니다.
성능 문제는 반드시 데이터로 진단합니다. 느리다는 느낌이 아니라, 숫자로 어디가 병목인지 특정해야 해결이 가능합니다.
- 1top/htop — CPU·메모리·프로세스 실시간 모니터링
- 2load average 해석 — 숫자가 의미하는 것
- 3vmstat — CPU 스케줄러와 메모리 상태 종합 뷰
- 4iostat -x — 디스크 I/O 병목 진단
- 5sar — 히스토리 기반 성능 추이 분석
- 6병목 유형별 진단 플로우
load average — 이 숫자가 높으면 무조건 문제인가?
load average 올바르게 읽기
uptime 또는 top 상단에 보이는 세 숫자: 1분 / 5분 / 15분 평균 실행 대기 프로세스 수
$ uptime
14:23:01 up 42 days, load average: 2.14, 1.87, 1.52
CPU 코어 수 기준으로 판단합니다:
nproc # 논리 CPU 코어 수 확인
grep -c ^processor /proc/cpuinfo
| 코어 수 | load average 기준 | 상태 |
|---|---|---|
| 4코어 | < 4.0 | 정상 |
| 4코어 | 4.0 ~ 8.0 | 주의 |
| 4코어 | > 8.0 | 위험 |
중요: load average가 높다고 반드시 CPU 병목이 아닙니다. I/O 대기 중인 프로세스도 포함됩니다.
# CPU 병목 vs I/O 병목 구분
top
# 상단 확인: %us(user) + %sy(system) 높음 → CPU 병목
# %wa(iowait) 높음 → I/O 병목
vmstat으로 시스템 전체 상태 1초 단위로 보기
vmstat 1 10 # 1초 간격, 10회 출력
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 0 0 512000 82000 1024000 0 0 0 24 312 891 8 2 88 2 0
5 0 0 511000 82000 1024000 0 0 0 512 445 1203 45 8 45 2 0
핵심 컬럼:
- r: 실행 대기 중인 프로세스 수 (코어 수보다 지속적으로 높으면 CPU 포화)
- b: I/O 대기 중인 프로세스 수 (높으면 디스크/네트워크 I/O 병목)
- si/so: swap in/out (0이어야 정상. so > 0이면 메모리 부족 신호)
- wa: CPU I/O 대기 시간 비율 (10% 이상이면 디스크 점검 필요)
iostat으로 디스크 병목 정확히 찾기
iostat -x 1 5 # 확장 통계, 1초 간격, 5회
Device r/s w/s rMB/s wMB/s await svctm %util
sda 12.0 45.0 0.48 2.25 8.50 1.20 12.00
nvme0n1 5.0 120.0 0.20 15.00 0.40 0.30 98.50 ← 포화 상태
진단 기준:
| 지표 | 정상 | 주의 |
|---|---|---|
%util | < 70% | > 90% → 디스크 포화 |
await HDD | < 20ms | > 50ms → 이상 |
await SSD | < 1ms | > 10ms → 이상 |
svctm | await에 근접 | await >> svctm → 큐 대기 과다 |
실습: 병목 유형별 진단 시나리오
시나리오 1: CPU 병목
# 부하 발생 (실습 환경)
stress --cpu 4 --timeout 30 &
# 진단
top # %us 높음, load average 상승
vmstat 1 5 # r 컬럼 높음
시나리오 2: I/O 병목
# 디스크 부하
dd if=/dev/zero of=/tmp/test bs=1M count=2000 &
# 진단
iostat -x 1 5 # %util 높음, await 높음
top # %wa(iowait) 높음
시나리오 3: 메모리 부족
free -h
vmstat 1 5 # si/so 컬럼 확인 (swap in/out)
# 프로세스별 메모리 사용량 (RES 기준)
ps aux --sort=-%mem | head -10
I/O 병목을 CPU 문제로 오진하는 케이스
$ uptime
load average: 25.00, 22.00, 18.00
$ top
%Cpu(s): 8.3 us, 1.2 sy, 0.0 ni, 12.5 id, 77.8 wa ← wa가 77.8%!
원인: load average는 CPU 대기뿐 아니라 I/O 대기 프로세스도 포함합니다. %wa(iowait)가 높으면 디스크/NFS/SAN 문제입니다.
# 확인
iostat -x 1 5 # 디스크 %util, await 확인
df -h # 디스크 풀 확인
dmesg | tail -20 # 디스크 에러 로그
흔한 원인: NFS 마운트 포인트 응답 없음, 디스크 불량 섹터, RAID 리빌드 중
실무에서 이 도구들이 쓰이는 순간
온콜 장애 대응 시나리오:
오전 3시: "API 응답 시간 급증" 알림
1. uptime → load average 확인
2. top → CPU/메모리/iowait 1차 확인
3. 이상 지표 발견:
- %wa 높음 → iostat -x 1 → 디스크 확인
- si/so 있음 → free -h → OOM 근접 확인
- r 높음 → 프로세스 급증 여부 확인
4. 원인 특정 → 해결 or 에스컬레이션
보통 신입이 가장 많이 틀리는 부분: load average만 보고 CPU 병목이라고 판단하는 것. iowait 확인까지 해야 합니다.