Linux

Linux: Disk I/O 분석 스크립트

dewstream 2026. 4. 8. 08:00
728x90

※ Linux: Disk I/O analysis script .

 

안녕하세요. 듀스트림입니다.

 

시스템을 운영하다 보면 Disk I/O를 체크해야 될 때가 있습니다.

 

물론 모니터링에서 찍어주지만, 조금 더 실시간성으로 정밀하게 분석해야 될 때 사용하시면 됩니다.


분석 Shell-scripts

아래 스크립트는 /proc/diskstats를 두 번 읽고, 각 디바이스에 대해 r/s, w/s, rkB/s, wkB/s, r_await, w_await, util%, avgqu를 계산하는 스크립트입니다.

#!/usr/bin/env bash

set -u

INTERVAL="${1:-1}"
DEVICE_REGEX="${2:-^(sd[a-z]+|vd[a-z]+|xvd[a-z]+|nvme[0-9]+n[0-9]+|dm-[0-9]+)$}"

TMP1="$(mktemp)"
TMP2="$(mktemp)"

trap 'rm -f "$TMP1" "$TMP2"' EXIT

read_stats() {
  awk -v regex="$DEVICE_REGEX" '
    $3 ~ regex {
      printf "%s %s %s %s %s %s %s %s %s\n",
             $3, $4, $6, $7, $8, $10, $11, $13, $14
    }
  ' /proc/diskstats | sort
}

read_stats > "$TMP1"
sleep "$INTERVAL"
read_stats > "$TMP2"

awk -v interval="$INTERVAL" '
BEGIN {
  printf "\n%-10s %8s %8s %10s %10s %10s %10s %8s %8s %-10s %s\n",
         "DEVICE", "r/s", "w/s", "rkB/s", "wkB/s",
         "r_await", "w_await", "util%", "avgqu", "STATE", "COMMENT"
  printf "%s\n", "-----------------------------------------------------------------------------------------------------------------------------"
}

FNR==NR {
  r_ios[$1]=$2
  r_sec[$1]=$3
  r_ms[$1]=$4
  w_ios[$1]=$5
  w_sec[$1]=$6
  w_ms[$1]=$7
  io_ms[$1]=$8
  wio_ms[$1]=$9
  next
}

{
  dev=$1

  dr_ios=$2-r_ios[dev]
  dr_sec=$3-r_sec[dev]
  dr_ms=$4-r_ms[dev]
  dw_ios=$5-w_ios[dev]
  dw_sec=$6-w_sec[dev]
  dw_ms=$7-w_ms[dev]
  dio_ms=$8-io_ms[dev]
  dwio_ms=$9-wio_ms[dev]

  rps = dr_ios / interval
  wps = dw_ios / interval
  rkBps = (dr_sec * 512 / 1024) / interval
  wkBps = (dw_sec * 512 / 1024) / interval
  rawait = (dr_ios > 0) ? dr_ms / dr_ios : 0
  wawait = (dw_ios > 0) ? dw_ms / dw_ios : 0
  util = (dio_ms / (interval * 1000)) * 100
  avgqu = dwio_ms / (interval * 1000)

  state="OK"
  comment="Normal"

  if (util > 90 && (rawait > 20 || wawait > 20)) {
    state="CRITICAL"
    comment="Disk saturated + high latency"
  }
  else if (util > 80 && avgqu > 1) {
    state="WARN"
    comment="Queue buildup (I/O backlog)"
  }
  else if (rawait > 10 || wawait > 10) {
    state="WARN"
    comment="High latency"
  }
  else if (util < 30 && (rawait > 5 || wawait > 5)) {
    state="WARN"
    comment="Sporadic delay"
  }
  else if (rps == 0 && wps == 0) {
    state="IDLE"
    comment="No disk activity"
  }

  printf "%-10s %8.1f %8.1f %10.1f %10.1f %10.2f %10.2f %8.1f %8.2f %-10s %s\n",
         dev, rps, wps, rkBps, wkBps, rawait, wawait, util, avgqu, state, comment
}
' "$TMP1" "$TMP2"

echo
echo "[자동 판단 기준]"
echo "- OK       : 정상"
echo "- WARN     : 지연 발생 또는 큐 적체"
echo "- CRITICAL : 디스크 포화 + latency 증가 (병목 확정)"
echo "- IDLE     : I/O 없음"
echo
echo "[해석 가이드]"
echo "- util > 80% + avgqu 증가 → I/O 밀림"
echo "- await > 10ms → 스토리지 지연 시작"
echo "- await > 20ms → 병목 가능성 높음"
echo "- util 낮은데 await 높음 → checkpoint / burst I/O 의심"
echo
사용법은 ./disk_io_check.sh <n> 인터벌 초를 줘서 사용하시면 됩니다. (값 미부여시 기본 인터벌은 1s)

스크립트 출력 컬럼 해석표

컬럼 의미 계산 기준 해석
DEVICE 디스크 장치명 /proc/diskstats의 $3 sda, nvme0n1 같은 장치 이름.
r/s 초당 읽기 요청 수 Δreads completed / interval 최근 구간 동안 초당 몇 건의 read 요청이 처리됐는지 의미.
높을수록 read IOPS가 많은 상태.
w/s 초당 쓰기 요청 수 Δwrites completed / interval 최근 구간 동안 초당 몇 건의 write 요청이 처리됐는지 의미.
높을수록 write IOPS가 많은 상태.
rkB/s 초당 읽기 처리량 Δread sectors × 512 / 1024 / interval 초당 몇 KB를 읽었는지 보여줌.
wkB/s 초당 쓰기 처리량 Δwrite sectors × 512 / 1024 / interval 초당 몇 KB를 썼는지 보여줌.
checkpoint, 배치 작업, flush 구간에서 높아질 수 있음.
r_await 읽기 1건당 평균 지연 시간(ms) Δread time / Δread requests read 요청이 완료되기까지 평균 얼마나 걸렸는지 의미.
큐에서 대기한 시간과 실제 처리 시간이 포함.
w_await 쓰기 1건당 평균 지연 시간(ms) Δwrite time / Δwrite requests write 요청이 완료되기까지 평균 얼마나 걸렸는지 의미.
특히 PostgreSQL에서는 WAL flush, checkpoint, VACUUM 영향으로 중요.
util% 측정 구간 동안 디스크가 바빴던 비율 Δtime spent doing I/Os / elapsed time × 100 디스크가 얼마나 바빴는지 보여줌.
높을수록 바쁜 상태지만 이것만으로 병목을 단정하면 안 되고 await, avgqu와 같이 봐야 함.
avgqu 평균 큐 길이 유사 지표 Δweighted I/O time / elapsed time I/O 요청이 얼마나 쌓였는지 추정하는 값.
높아질수록 처리 대기열이 길어지는 경향을 의미.
STATE 자동 판단 상태 스크립트 조건문 OK, WARN, CRITICAL, IDLE 중 하나로 표시.
수치를 사람이 직접 해석하지 않아도 대략적인 상태를 바로 볼 수 있게 만든 값.
COMMENT 상태에 대한 설명 스크립트 조건문 왜 해당 상태로 판단했는지 짧게 보여줌.
(예: Normal, High latency, Disk saturated + high latency)

STATE 컬럼 해석표

STATE 의미 판단 기준 해석
OK 정상 기본값 디스크가 바쁘더라도 지연이 크지 않고 큐 적체가 심하지 않은 상태.
WARN 주의 util > 80 && avgqu > 1 또는 await 증가 등 병목 전조이거나 지연이 발생하는 상태. (원인 확인 필요)
CRITICAL 심각 util > 90 && (r_await > 20 또는 w_await > 20) 디스크가 거의 포화된 상태에서 지연도 커진 경우. (실제 병목일 가능성이 높음)
IDLE 유휴 r/s == 0 && w/s == 0 측정 구간 동안 디스크 I/O가 없었던 상태.

COMMENT 컬럼 해석표

COMMENT 의미 해석
Normal 정상 특별한 지연이나 큐 적체 없이 처리 중.
Disk saturated + high latency 디스크 포화 + 높은 지연 바쁘기도 하고 느리기도 한 상태. (실질적 병목 가능성 높음)
Queue buildup (I/O backlog) 큐 적체 요청이 처리보다 빨리 들어오면서 대기열이 쌓이는 상태.
High latency 높은 지연 처리량이 많지 않아도 요청 한 건당 시간이 길어진 상태.
Sporadic delay 간헐적 지연 평균 사용률은 높지 않지만 순간적으로 지연이 튄 상태. (flush, burst I/O 등을 의심)
No disk activity I/O 없음 측정 구간 동안 read/write가 없었던 상태.

패턴 해석

패턴 의미 체크 사항
util% 높음, await 낮음 바쁘지만 잘 처리 중 정상적인 busy 상태
util% 높음, await 높음, avgqu 높음 병목 가능성 높음 디스크 포화, 스토리지 한계, checkpoint 밀림
util% 낮음, await 높음 순간 지연 flush, fsync, burst I/O, 스토리지 응답 이상
w/s, wkB/s 높음 쓰기 위주 부하 checkpoint, WAL flush, 배치
r/s, rkB/s 높음 읽기 위주 부하 seq scan, 대량 조회, VACUUM scan
r/s, w/s 둘 다 높음 read/write 혼합 부하 VACUUM, 배치, ETL, 복합 워크로드

오늘은 여기까지~

 

 

728x90

'Linux' 카테고리의 다른 글

Linux: 터미널 세션 기록  (1) 2025.11.14
Linux: rpm 다운로드 방법  (1) 2025.08.04
Linux: 커널 메모리 관리 파라미터  (1) 2025.07.28
Linux: 기본 디렉터리 구조  (2) 2025.07.22
Linux: OpenSSH 사용법  (0) 2025.02.24