Views: 0
목차
개요
서버가 느려질 때 원인이 항상 CPU나 메모리만은 아니다. 대다수의 지연은 디스크 I/O 병목에서 비롯되며, 이를 조기에 찾아내려면 관측 도구를 체계적으로 써야 한다. iostat은 디스크별 지표로 병목 지점을 명확히 보여주고, vmstat은 시스템 전체의 런큐와 페이지 활동을 통해 “I/O 때문에 대기 중인지”를 가늠하게 한다. dstat은 다중 리소스를 한 화면에서 비교해 상관관계를 빠르게 파악하게 해준다. 이 글은 세 도구의 핵심 지표와 해석법, 단계별 진단 루틴, 워크로드 유형별 대응 전략, 자주 겪는 함정과 트러블슈팅까지 실전 관점으로 정리한다.
기본 준비와 설치
대부분 배포판에 기본 포함되지만 없다면 다음처럼 설치한다.
# Debian/Ubuntu
sudo apt-get update && sudo apt-get install -y sysstat dstat
# RHEL/Alma/Rocky
sudo yum install -y sysstat dstat
설치 후 커널 버전에 맞춰 블록 디바이스 명칭과 NUMA/스케줄러 설정을 확인해 해석 오류를 줄인다.
iostat: 디스크별 병목을 수치로 본다
iostat은 블록 디바이스 단위의 처리량과 대기 시간을 보여준다. 간단한 실행 형태는 다음과 같다.
# 1초 간격으로 10회
iostat -x 1 10
# 장치만 보기(파티션 제외)
iostat -xd 1
핵심 지표 해석
- r/s, w/s: 초당 읽기·쓰기 IOPS. 급증 구간을 부하 이벤트와 대조한다.
- rkB/s, wkB/s: 처리량(MB/s 환산 가능). 시퀀셜 워크로드인지 판단에 도움.
- await(ms): I/O 완료까지 평균 대기시간. 내부 큐잉+장치 지연을 모두 포함한다. 수 ms에서 안정, 수십 ms 이상이면 체감 지연 가능성 크다.
- svctm(ms): 장치 서비스 시간. 최신 sysstat에선 의미가 제한적일 수 있어 await, r_await, w_await 중심으로 본다.
- r_await, w_await(ms): 읽기/쓰기 대기시간 분리 지표. 쓰기만 느리면 저널·캐시 플러시, 읽기만 느리면 캐시 미스나 랜덤 읽기 의심.
- avgqu-sz: 장치 큐 길이 평균. 1 이상이 지속되면 대기열이 쌓이는 중.
- %util: 장치 바쁨 비율. 100% 근접이 지속되면 해당 디스크 혹은 어레이가 포화 상태.
실무 팁
- RAID·LVM의 상·하위 장치가 함께 보이면 동일 시점의 %util·await 상관을 본다. 하위 물리 디스크에서 포화가 먼저 보인다.
- NVMe는 높은 IOPS에도 await 수 ms 수준이 정상일 수 있다. 장치 특성을 기준으로 “평소 프로파일”을 만들어 비교한다.
vmstat: 시스템 레벨에서 I/O 병목의 징후를 읽는다
vmstat 1
핵심 지표
- r: 런큐 길이. CPU 코어 수 대비 높고 us+sy가 낮으며 wa가 높다면 I/O 대기로 막힌 CPU를 의심.
- b: 블록(불가중) 대기 프로세스 수. 값이 지속되면 디스크 혹은 NFS 대기일 가능성.
- si/so: 스왑 인·아웃. 스왑이 활발하면 디스크 I/O 폭증과 함께 전반적 지연이 발생.
- bi/bo: 블록 장치로의 읽기·쓰기. iostat의 rkB/s, wkB/s와 함께 흐름을 본다.
- us/sy/wa/st: 사용자·시스템·I/O 대기·스틸타임. wa가 20% 이상 장시간 유지되면 디스크 혹은 네트워크 스토리지가 병목일 가능성.
실무 팁
- r가 높지만 us, sy가 낮고 wa가 높다면 “CPU가 놀지만 I/O 기다리는 중”. 반대로 us·sy가 높고 r도 높다면 CPU 병목 또는 락 경합을 먼저 본다.
dstat: 상관관계를 한 화면에
# 디스크/네트/페이지/CPU를 한 번에
dstat -cdnym --top-io --top-latency
유용한 옵션
- -d: 디스크 총 I/O
- -D sda,nvme0n1: 특정 디스크만
- -n: 네트워크
- -y: 시스템 인터럽트, 스위치
- –top-io, –top-latency: I/O 많이 쓰는/지연 큰 프로세스 상위
dstat은 “이 시점에 누가 원인인가”를 빠르게 좁히는 데 강력하다. 특히 –top-io로 I/O 소비 상위 프로세스를 즉시 파악한다.
단계별 진단 루틴(현장 절차)
- 증상 캡처
- 사용자의 느림 보고 시간대를 바탕으로
vmstat 1,iostat -x 1,dstat를 동시에 켠다. 가능하면 60~120초 이상 수집한다.
- 병목 지점 식별
- vmstat의 wa↑, b↑ 여부 확인
- iostat에서 %util≈100, await↑, avgqu-sz↑인 장치 찾기
- dstat –top-io로 가해 프로세스 상위 확인
- 워크로드 유형 판별
- iostat의 rkB/s·wkB/s와 r/s·w/s 비율에서 랜덤(IOPS형) vs 시퀀셜(Throughput형) 구분
- RAID/NVMe 여부와 파일시스템 캐시 효과를 고려
- 원인 분류
- 쓰기만 느림: 저널/캐시 플러시, 배치 대량 쓰기, fsync 폭주
- 읽기만 느림: 캐시 미스, 파편화, 작은 랜덤 읽기
- 특정 디스크만 포화: 결함 디스크, 비대칭 레이아웃, 리빌드 중
- 추가 심화
pidstat -d 1또는iotop -oPa로 프로세스별 읽기/쓰기 확인smartctl -a /dev/sdX로 미디어 에러/재할당 섹터/온도 확인- 파일시스템 관점:
grep -i dirty /proc/meminfo,cat /proc/sys/vm/dirty_*로 쓰기백 지연 확인
- 조치와 검증
- 설정 변경·튜닝 또는 워크로드 스케줄 조정 후 같은 측정으로 개선 여부를 수치로 확인
워크로드 유형별 대응 전략
랜덤 읽기 중심(OLTP, 키밸류)
- NVMe 또는 RAID10 채택 검토, 파일시스템 옵션 noatime 적용
- 캐시 적중률 확보: 애플리케이션 레벨 캐시, 적절한 메모리 할당
- 스케줄러: NVMe는 기본, SATA SSD/HDD는 mq-deadline 권장
랜덤 쓰기 및 fsync 많음(로그·메시지 큐·저널링 DB)
- 저널/로그 전용 디스크 분리
- writeback 파라미터 조정
# 쓰기 집합 제어(환경과 테스트 필수)
sysctl -w vm.dirty_background_ratio=5
sysctl -w vm.dirty_ratio=20
- 애플리케이션 배치/버퍼링 옵션 활용
대용량 순차(백업, ETL, 미디어 처리)
- 스트라이프 맞춤 포맷(XFS su/sw, EXT4 stride/stripe-width)
- 마운트 옵션 noatime, 큰 I/O 사이즈 사용
- RAID5/6 쓰기 패널티 회피 필요 시 RAID10 고려
실전 지표 해석 예시
- 사례 1: iostat에서 nvme0n1 %util 99~100, await 25ms, r/s 20k, rkB/s 80,000. vmstat wa 30%. → NVMe 단일 디바이스가 랜덤 읽기 과부하. 샤딩 또는 캐시 확충, 복제 노드 분산.
- 사례 2: md0(raid5) w_await 80ms↑, avgqu-sz 10↑, wkB/s 높음. → 쓰기 패널티 구간. 로그/저널/임시 쓰기를 별도 디스크로 분리하거나 RAID10 전환 검토.
- 사례 3: %util 낮은데 await만 높음. → 상위 계층(NFS, iSCSI, 네트워크, 컨트롤러 큐) 지연 가능성. 네트워크·스토리지 경로를 추적.
자주 겪는 함정과 예방
- %util 100%만 보고 결론: NVMe는 짧은 대기라면 100%여도 체감이 없을 수 있다. await·r/w_await로 보정.
- 파티션 단위 지표만 해석: 상·하위 장치 동시 관찰로 실제 병목 위치를 찾는다.
- 스왑 활성화를 무시: vmstat si/so가 있다면 먼저 메모리 압박을 해소해야 한다. 스왑이 I/O를 폭증시켜 악순환이 된다.
- RAID 리빌드/스크럽 간과: /proc/mdstat를 항상 확인하고 유지보수 창에 맞춰 작업을 스케줄한다.
튜닝 체크리스트
- I/O 스케줄러
cat /sys/block/sdX/queue/scheduler
echo mq-deadline | sudo tee /sys/block/sdX/queue/scheduler
- 읽기 어헤드
blockdev --getra /dev/sdX
blockdev --setra 4096 /dev/sdX
- 파일시스템 마운트 옵션(noatime, nodiratime)
- 쓰기백 파라미터(vm.dirty_*): 사전 부하 테스트 필수
- RAID 청크/정렬, LVM 스트라이프 설정 재점검
장애 징후 조기 탐지와 모니터링
- 운영 대시보드에 await, %util, avgqu-sz, r/s·w/s를 수집
- vmstat wa, b와 CPU 사용률 비교 그래프화
- SMART 상태·온도·재할당 섹터 수 알림
- 주기적 I/O 스모크 테스트로 평상시 기준선 확보
진단 자동화 스니펫
#!/usr/bin/env bash
set -euo pipefail
DUR=${1:-60}
echo "# vmstat"; vmstat 1 $DUR > /tmp/vmstat.out &
echo "# iostat"; iostat -x 1 $DUR > /tmp/iostat.out &
echo "# dstat"; dstat -cdnym --output /tmp/dstat.csv 1 $DUR > /dev/null &
wait
echo "saved: /tmp/vmstat.out /tmp/iostat.out /tmp/dstat.csv"
수집된 파일을 저장해 이벤트 전후 비교에 활용한다.
트러블슈팅 요약
- wa↑, await↑, %util≈100: 디스크 포화. 워크로드 분산이나 하드웨어 계층 확장.
- await↑, %util 낮음: 상위 네트워크/스토리지 지연, 파일시스템 락, 컨트롤러 큐 확인.
- si/so↑: 메모리 압박 해소가 우선. 캐시 사이즈 조정과 스왑 튜닝.
- 특정 시점만 급등: 배치 스케줄, 백업, 크론 잡과 대조. 시간 분산 또는 QoS 적용.
마무리
디스크 I/O 문제는 “어디가 막혔는지”를 빠르게 좁히는 것이 관건이다. vmstat로 시스템 수준의 I/O 대기 징후를 확인하고, iostat로 장치별 병목을 특정하며, dstat으로 가해 프로세스와 상관관계를 한 번에 본다. 이 세 도구를 일관된 루틴으로 운용하면 원인 식별 시간이 단축되고, 워크로드에 맞는 대응 전략을 수치로 검증할 수 있다. 평소 기준선을 확보하고, 리빌드·백업·배치 시점을 조정하며, 캐시·레이아웃·스케줄러를 정교하게 맞추면 디스크 병목은 예측 가능한 범위로 들어온다.