고디스크 I/O 지연 시간 문제 해결: 단계별 Linux 가이드
iostat, iotop, pidstat, vmstat, 로그 및 실용적인 워크로드 점검을 통해 Linux 디스크 I/O 지연 시간을 진단합니다.
고디스크 I/O 지연 시간 문제 해결: 단계별 Linux 가이드
높은 디스크 I/O 지연 시간은 매우 특정한 느낌을 줍니다. SSH는 여전히 연결되고, CPU는 최대로 사용되지 않지만, 파일을 건드리는 모든 명령이 잠시 멈춥니다. 웹 앱은 세션을 쓰는 동안 일시 중지됩니다. 일반적으로 빠르게 반환되는 데이터베이스 쿼리가 스토리지에서 대기하기 시작합니다. 기계는 살아있는 것처럼 보이지만, 진흙 속을 걷는 것처럼 느껴집니다.
요령은 추측을 피하는 것입니다. "디스크가 느리다"는 것은 포화된 블록 장치, 스왑 스래싱, 고장 나는 드라이브, 시끄러운 백업 작업, 과부하된 네트워크 볼륨, 또는 인덱스가 없어서 무작위 읽기를 수행하는 데이터베이스를 의미할 수 있습니다. 동일한 증상이 매우 다른 원인에서 발생할 수 있습니다.
디스크 I/O 메트릭 이해하기
문제 해결에 뛰어들기 전에 I/O 문제를 나타내는 주요 메트릭을 이해하는 것이 중요합니다. 높은 지연 시간이 주요 증상이지만, 문제의 심각성과 원인을 확인하기 위해 지원 데이터 포인트가 필요합니다.
I/O 경합의 주요 지표
- 높은 지연 시간 (
await): I/O 요청이 완료되는 평균 시간(밀리초)입니다. 여기에는 큐에서 대기하는 시간과 서비스되는 시간이 포함됩니다. "높음"으로 간주되는 것은 스토리지와 워크로드에 따라 다릅니다. 가능하면 시스템의 정상 기준선과 비교하십시오. - 높은 사용률 (%util): 이 메트릭이 100%에 가까워지면 장치가 포화 상태이며 추가 요청을 효율적으로 처리할 수 없습니다.
- 높은 큐잉 (avgqu-sz): 평균 큐 크기가 크면 많은 프로세스가 디스크가 사용 가능해지기를 기다리고 있음을 의미합니다.
1단계: iostat를 사용한 초기 시스템 상태 점검
iostat 유틸리티(sysstat 패키지의 일부)는 장치 사용률 및 성능 통계를 모니터링하기 위한 초석입니다. CPU 및 장치 I/O에 대한 과거 및 현재 데이터를 제공합니다.
I/O 성능의 실행 중인 집계를 얻으려면 간격(예: 2초마다)을 지정하여 iostat를 실행하십시오:
sudo iostat -dxm 2
iostat -dxm 출력 분석
장치 통계 열(x 플래그)에 특히 초점을 맞추십시오:
| 열 | 설명 | 높은 값의 의미 |
|---|---|---|
| r/s, w/s | 초당 읽기/쓰기 (IOPS) | 높은 값은 높은 처리량 요구를 나타냅니다. |
| rkB/s, wkB/s | 초당 읽기/쓰기된 킬로바이트 | 처리량 볼륨을 측정합니다. |
| await | I/O 요청의 평균 대기 시간(ms) (서비스 시간 + 큐 시간) | 높은 지연 시간의 주요 지표. |
| %util | 장치가 요청을 서비스하는 데 바쁜 시간의 백분율 | 100%에 가까우면 포화 상태를 나타냅니다. |
예제 시나리오: /dev/sda가 await 시간 150ms 및 %util 98%를 표시하면 해당 디스크에서 심각한 I/O 병목 현상을 확인한 것입니다.
팁: 확장 통계를 위해
-x플래그를 사용하고, 메가바이트 단위로 보고하려면-m을 사용하십시오. 킬로바이트(-k)보다 종종 더 명확합니다.
2단계: iotop으로 원인 프로세스 식별
iostat가 특정 장치(예: /dev/sda)에서 높은 지연 시간을 확인하면, 다음 중요한 단계는 어떤 프로세스가 해당 부하를 생성하는지 결정하는 것입니다. top 명령의 기능을 미러링하지만 I/O 활동에 초점을 맞춘 iotop 유틸리티가 여기서 필수적입니다.
iotop이 설치되지 않은 경우 먼저 설치하십시오:
# Debian/Ubuntu
sudo apt update && sudo apt install iotop
# RHEL/CentOS/Fedora
sudo yum install iotop # 또는 dnf install iotop
루트 권한으로 iotop을 실행하고, I/O를 적극적으로 수행하는 프로세스만 표시하십시오:
sudo iotop -oP
-o: I/O를 적극적으로 수행하는 프로세스만 표시합니다.-P: 개별 스레드가 아닌 프로세스를 표시합니다.
출력을 검사하고 IO_READ 및 IO_WRITE 열에 주의하십시오. 상단에 나열된 프로세스가 가장 많은 디스크 대역폭을 소비하고 있습니다. 일반적인 원인으로는 데이터베이스 서버(MySQL, PostgreSQL), 백업 유틸리티, 로그 순환 스크립트 또는 스왑 공간에 적극적으로 쓰는 시스템이 있습니다.
iotop 출력 해석
iotop은 각 프로세스의 총 디스크 사용량을 표시합니다. 단일 애플리케이션이 디스크 사용률을 지배하는 경우(예: 지연 시간이 급증하는 동안 백업 스크립트가 50MB/s로 실행되는 경우), 즉각적인 원인을 찾은 것입니다.
3단계: pidstat로 심층 분석
iotop은 프로세스당 총 I/O를 표시하는 반면, pidstat는 특정 PID에 의해 시작된 I/O 작업에 대한 자세한 과거 컨텍스트를 제공할 수 있으며, 이는 장기 실행 또는 간헐적 문제에 유용합니다.
5초마다 5회 반복하여 모든 프로세스의 I/O 통계(블록 읽기 및 쓰기)를 모니터링하려면:
sudo pidstat -d 5 5
-d 출력의 주요 메트릭은 다음과 같습니다:
- kB_rd/s: 작업에 의해 디스크에서 초당 읽은 데이터 양.
- kB_wr/s: 작업에 의해 디스크에 초당 기록된 데이터 양.
- kB_ccwr/s: 스왑 공간에 기록된 데이터 양(c=취소/커밋된 쓰기).
사용자가 일시 중지를 보고할 때마다 동일한 프로세스에 대한 읽기 및 쓰기가 증가하면 유용한 단서가 있습니다. pidstat는 iotop이 짧은 급증을 표시한 다음 읽기 전에 지워질 때 특히 유용합니다.
4단계: 메모리 스래싱(스왑 사용량) 진단
높은 스왑 활동은 종종 높은 디스크 I/O 지연 시간으로 나타납니다. 시스템이 느린 물리적 디스크를 가상 RAM으로 사용해야 하기 때문입니다. free 명령을 사용하여 메모리 압력을 확인하십시오:
free -h
used 메모리가 total 메모리에 가깝고 swap used 값이 빠르게 증가하는 경우, 시스템에 메모리가 부족하며 I/O 지연 시간은 스와핑의 2차 증상입니다.
스래싱 해결 방법:
top또는htop을 사용하여 메모리를 많이 사용하는 프로세스를 식별합니다.- 가능하면 시스템 RAM을 늘립니다.
- 애플리케이션이 더 적은 메모리를 사용하도록 조정합니다.
또한 문제가 발생하는 동안 vmstat를 확인하십시오:
vmstat 1
si 및 so 열은 스왑인 및 스왑아웃 활동을 표시합니다. 가끔 0이 아닌 값이 자동으로 위기는 아닙니다. 시스템이 느린 동안 지속적인 활동은 더 강력한 신호입니다. wa CPU 열도 유용합니다. 높은 I/O 대기는 작업이 CPU에서 실행되는 대신 스토리지에서 차단되는 데 시간을 보내고 있음을 의미합니다.
5단계: 장치를 파일 시스템에 매핑
iostat는 블록 장치를 보고합니다: sda, nvme0n1, dm-0, md0 등. 애플리케이션 로그는 일반적으로 경로를 언급합니다: /var/lib/mysql, /var/log, /home, /data. 잘못된 디스크를 비난하기 전에 경로를 장치에 매핑하십시오.
df -hT /var/lib/mysql
findmnt /var/lib/mysql
lsblk -f
이것은 LVM, 소프트웨어 RAID, 클라우드 볼륨 또는 별도의 마운트 지점이 있는 호스트에서 중요합니다. dm-0에서 높은 지연 시간이 나타날 수 있지만 실제 백킹 장치는 EBS 볼륨, mdraid 어레이 또는 암호화된 매퍼 장치일 수 있습니다. 사용 중인 파일 시스템이 네트워크 스토리지에 있는 경우 로컬 디스크 도구는 이야기의 일부만 알려줍니다. NFS, iSCSI, 클라우드 볼륨 메트릭 또는 스토리지 어플라이언스도 확인해야 합니다.
6단계: 커널 및 하드웨어 단서 찾기
지연 시간은 높지만 처리량이 높지 않은 경우 스토리지 오류를 확인하십시오. 고장 나는 디스크 또는 재설정 경향이 있는 컨트롤러는 적당한 I/O에서도 시스템을 기어가게 만들 수 있습니다.
dmesg -T | egrep -i 'error|reset|timeout|nvme|scsi|blk_update|i/o error'
journalctl -k --since "30 minutes ago"
물리적 디스크의 경우 SMART 데이터가 유용할 수 있습니다:
sudo smartctl -a /dev/sda
NVMe 장치의 경우:
sudo nvme smart-log /dev/nvme0
하나의 SMART 필드를 단독으로 과도하게 읽지 마십시오. 다른 공급업체는 다른 카운터를 노출합니다. 그러나 재할당된 섹터, 미디어 오류, 반복된 명령 시간 초과 또는 커널 I/O 오류는 즉각적인 주의가 필요합니다. 디스크가 프로덕션 데이터베이스를 백업하는 경우 튜닝 연습으로 취급하지 말고 중복성, 장애 조치 또는 교체를 진행하십시오.
7단계: 대역폭 문제와 지연 시간 문제 구분
두 인시던트 모두 "느린 디스크"를 표시할 수 있지만 다른 수정이 필요합니다.
순차 백업은 높은 wkB/s 및 높은 %util을 밀어낼 수 있습니다. 이것은 대역폭 문제입니다. 백업을 제한하고, 피크 시간을 피하고, 증분 백업을 사용하거나, 다른 볼륨에 쓰는 것이 도움이 될 수 있습니다.
인덱스가 누락된 데이터베이스는 적당한 처리량이지만 고통스러운 await, 많은 작은 읽기 및 사용자에게 보이는 쿼리 지연을 보일 수 있습니다. 이것은 종종 무작위 I/O 및 쿼리 형태 문제입니다. 더 많은 대역폭을 투입하는 것보다 올바른 인덱스를 추가하거나 작업 세트를 줄이는 것이 더 도움이 될 수 있습니다.
이 빠른 읽기를 사용하십시오:
- 높은
rkB/s또는wkB/s, 높은%util, 명백한 대규모 작업: 대량 읽기/쓰기를 찾으십시오. - 높은
r/s또는w/s, 높은await, 낮은 처리량: 많은 작은 무작위 작업을 찾으십시오. - 높은 스왑 활동, 높은
wa, 낮은 여유 메모리: 메모리 압력을 근본 원인으로 취급하십시오. - 커널 오류가 있는 높은 지연 시간: 스토리지 상태를 근본 원인으로 취급하십시오.
8단계: 애플리케이션 수준 컨텍스트 확인
시스템 도구는 누가 스토리지를 건드리는지 알려줍니다. 항상 그 이유를 알려주지는 않습니다.
데이터베이스의 경우 느린 쿼리 로그와 버퍼/캐시 메트릭을 확인하십시오. iotop 상단의 MySQL 프로세스는 백업 중에는 정상일 수 있고, 피크 트래픽 중에는 나쁠 수 있으며, 버퍼 풀이 차가운 상태에서 재시작 후에는 예상될 수 있습니다. PostgreSQL은 자동 진공, 체크포인트 쓰기 또는 디스크로 유출되는 쿼리를 수행할 수 있습니다. MongoDB는 압축, 인덱스 구축 또는 더 이상 RAM에 맞지 않는 작업 세트 읽기를 수행할 수 있습니다.
웹 서버 및 앱 작업자의 경우 로그 폭풍을 찾으십시오. 활성화된 디버그 로그는 꾸준한 동기 쓰기를 생성할 수 있습니다. 실패하는 종속성은 반복적인 오류 로그를 생성하여 디스크 압력을 유발하고 원래 인시던트를 악화시킬 수 있습니다.
컨테이너의 경우 시끄러운 프로세스가 containerd, dockerd 또는 오버레이 파일 시스템 아래에 나타날 수 있음을 기억하십시오. 컨테이너 수준 도구도 사용하십시오:
docker stats
docker ps --format 'table {{.ID}}\t{{.Names}}\t{{.Status}}'
Kubernetes 노드에서 호스트 수준 I/O를 포드 배치와 비교하십시오. emptyDir, hostPath 또는 로컬 영구 볼륨에 많이 쓰는 단일 포드는 동일한 노드의 관련 없는 포드가 비정상적으로 보이게 만들 수 있습니다.
일반적인 원인 및 해결 전략
원인이 식별되면 적절한 수정을 적용하십시오:
1. 백업 또는 유지 관리 작업
증상: 예약된 작업(예: cron 작업)과 일치하는 높은 I/O 사용률.
해결 방법: 대규모 I/O 작업을 재조정하고, 유틸리티가 지원하는 경우 제한하고, 임시 출력을 다른 볼륨으로 이동하십시오. 예를 들어, rsync --bwlimit, ionice 및 데이터베이스 네이티브 백업 제한은 폭발 반경을 줄일 수 있습니다.
2. 비효율적인 데이터베이스 쿼리
증상: 데이터베이스 프로세스(예: mysqld)가 iotop에서 최상위 소비자입니다.
해결 방법: 전체 테이블 스캔을 강제하여 대규모 무작위 읽기를 초래하는 잘못 인덱싱된 쿼리를 최적화하십시오.
3. 과도한 로깅
증상: 애플리케이션 또는 시스템 로깅 프로세스가 많은 양의 데이터를 쓰고 있습니다. 해결 방법: 애플리케이션 로깅 수준을 검토하십시오. 로컬 디스크 쓰기를 줄이기 위해 로그를 버퍼링하거나 원격 로깅 솔루션(Syslog 또는 ELK 스택 등)을 사용하는 것을 고려하십시오.
4. 디스크 오류 또는 잘못된 구성
증상: 높은 처리량과 상관 관계가 없는 극도로 높은 await 시간 또는 이상한 읽기/쓰기 패턴. 이는 하드웨어 오류 또는 잘못된 RAID 구성을 나타낼 수 있습니다.
해결 방법: SMART 데이터(smartctl)를 확인하여 디스크 상태를 확인하십시오. RAID를 사용하는 경우 어레이 상태를 확인하십시오.
5. 파일 시스템 또는 마운트 옵션
증상: 메타데이터가 많은 워크로드(많은 작은 파일 생성, 디렉토리 삭제, 로그 순환 또는 아카이브 압축 풀기) 주변에서 지연 시간이 나타납니다.
해결 방법: 파일 시스템 유형, 마운트 옵션, inode 사용량 및 저널 동작을 확인하십시오. 가득 찬 파일 시스템, 소진된 inode 또는 거의 가득 찬 씬 프로비저닝된 볼륨은 애플리케이션 측에서 I/O 지연 시간 문제처럼 보일 수 있습니다.
df -h
df -ih
findmnt -o TARGET,SOURCE,FSTYPE,OPTIONS
inode 사용량이 100%인 경우 하나의 거대한 파일을 삭제해도 도움이 되지 않습니다. 많은 작은 파일을 제거하거나 해당 워크로드를 위해 설계된 파일 시스템 레이아웃으로 이동해야 합니다.
사전 예방적 모니터링을 위한 모범 사례
I/O 병목 현상을 방지하는 것이 사후에 수정하는 것보다 낫습니다. 지속적인 모니터링을 구현하십시오:
- 알림 설정: 디스크 지연 시간, 큐 깊이, I/O 대기, 파일 시스템 포화도 및 오류 카운터의 지속적인 변화에 대해 알리도록 모니터링 도구를 구성하십시오. 보편적인 숫자를 복사하는 대신 스토리지 클래스 및 워크로드와 일치하는 임계값을 사용하십시오.
- 성능 기준 설정: 특정 워크로드에 대해 "정상" I/O 지연 시간이 어떻게 보이는지 알아야 합니다. 이렇게 하면 이상 징후를 더 쉽게 발견할 수 있습니다.
- 워크로드 유형 이해: 무작위 I/O 패턴(데이터베이스에서 일반적)은 순차 I/O(미디어 스트리밍 또는 대용량 파일 읽기에서 일반적)보다 훨씬 높은 지연 시간을 유발합니다.
최고의 디스크 지연 시간 조사는 질문을 계속 좁힙니다: 어떤 장치, 어떤 파일 시스템, 어떤 프로세스, 어떤 워크로드, 어떤 최근 변경 사항? 해당 체인이 있으면 수정이 일반적으로 더 명확해집니다. 커널 설정을 무작위로 조정하는 것을 중단하고 백업 일정 변경, 메모리 추가, 스토리지 복구, 쿼리 수정 또는 시끄러운 워크로드를 공유 디스크에서 멀리 이동하는 것을 시작합니다.