이 문서를 통해 아래 질문들에 답할 수 있게 됩니다.
Disk IO와 Buffered IO에서 붙잡아야 할 핵심 판단 기준은 무엇인가?buffer는 비용을 없애지 않고 시점을 바꾼다라는 기준은 어떤 JVM/OS 신호로 확인되는가?- Java/Spring 코드에서
Disk IO와 Buffered IO판단 기준은 어떤 장애 신호로 드러나는가?
개요
이 문서의 주제는 Disk IO와 Buffered IO이다. Disk I/O, page cache, buffering, flush, sync가 Java 서버에 주는 영향을 다룬다.
먼저 붙잡을 기준은 다음 문장이다. buffer는 비용을 없애지 않고 시점을 바꾼다. 이 문서는 이 기준을 Java/Spring 실행 흐름, JVM/OS 관찰 지표, 장애 판단 순서로 연결한다.
핵심 모델
- 판단 기준: write 호출과 disk 반영은 같은 시점이 아니다.
- Buffered I/O는 page cache와 buffer를 거쳐 실제 storage latency를 숨기거나 늦게 드러낼 수 있다.
fsync나 flush가 들어가면 지연이 요청 thread에 직접 보일 수 있다.- I/O wait는 CPU가 놀고 있다는 뜻이 아니라 storage 응답을 기다리는 작업이 있다는 신호다.
- Disk 병목은 file write, log, dump, upload, DB volume 등 여러 경로가 합쳐져 나타난다.
문서별 핵심 구분
- buffer는 write 비용을 없애지 않고 시점을 바꾼다.
- flush와 fsync 시점에 latency가 튈 수 있다.
- page cache와 dirty page는 Java 코드 밖에서 성능을 좌우한다.
원리
Disk I/O는 애플리케이션의 read와 write 호출만으로 끝나지 않는다. OS page cache, dirty page, flush, fsync, storage queue, 실제 device latency를 거친다.
Buffered I/O는 작은 system call을 줄이고 처리량을 높이지만 비용을 없애지는 않는다. buffer가 가득 차거나 flush/fsync가 발생하는 시점에 지연이 몰릴 수 있다.
Page cache는 읽기 성능을 크게 높일 수 있지만 memory pressure가 생기면 회수 대상이 된다. 같은 코드도 cache warm/cold 상태에 따라 latency가 달라진다.
Disk IO와 Buffered IO 관점에서 중요한 점은 write 완료의 의미를 구분하는 것이다. Java 메서드가 반환됐다는 사실과 데이터가 물리 storage에 안전하게 반영됐다는 사실은 같은 말이 아니다.
Java/Spring 연결
- 대용량 upload/download와 report export는 request thread와 disk bandwidth를 동시에 점유한다.
- Logback file appender와 rotation/compression은 업무 요청과 같은 disk를 쓸 수 있다.
- Heap dump와 GC log 수집은 장애 중 disk I/O를 크게 늘릴 수 있다.
readAllBytes()는 disk I/O뿐 아니라 heap 사용량도 함께 키운다.iostat,pidstat -d, file size 증가를 API latency와 같은 시간축에 맞춘다.
코드와 설정 예시
try (BufferedOutputStream out = new BufferedOutputStream(Files.newOutputStream(path))) {
out.write(payload);
out.flush();
}예시는 buffer가 작은 write를 모아 system call 비용을 줄이지만, flush() 시점에는 대기 시간이 드러날 수 있음을 보여 준다. durability가 필요하면 fsync 계열 비용까지 별도로 판단해야 한다.
관찰 명령
iostat -xz 1 5
vmstat 1 5
cat /proc/meminfo | grep -E 'Dirty|Writeback|Cached'Disk IO와 Buffered IO 관찰 명령은 결론이 아니라 가설 확인 도구다. 운영 중에는 반복 간격, 대상 PID, 수집 시각을 함께 남기고 출력이 큰 명령은 범위를 제한한다.
지표 해석
| 신호 | 먼저 의심할 것 | 다음 확인 |
|---|---|---|
| open files가 limit에 근접 | FD leak 또는 connection 폭주 | lsof, /proc/<pid>/fd |
| iowait 증가와 latency 상승 | disk 병목, flush 지연 | iostat, vmstat |
| 로그량 급증 후 API 지연 | 동기 로그 또는 log collector 지연 | log rate, appender queue |
| tmp 사용량 증가 | upload/export/temp cleanup 실패 | tmp directory, lsof deleted |
Disk IO와 Buffered IO에서는 핵심 신호와 보조 지표를 같은 시간축에서 맞춘다. 먼저 변한 신호와 뒤따라 포화된 신호를 분리해야 원인과 결과를 구분할 수 있다.
장애 상황에서 보는 순서
iostat으로 await, util, queue 관련 값을 본다.pidstat -d로 어떤 process가 읽고 쓰는지 확인한다.- 로그, dump, upload, export 중 어느 파일 경로가 증가했는지 본다.
- page cache 여유와 memory pressure를 함께 확인한다.
- 작업을 중단, rate limit, 별도 volume 분리 중 무엇으로 완화할지 결정한다.
이 순서는 disk I/O 병목을 Java 코드와 storage 지표로 연결하기 위한 루틴이다.
실전 팁
iostat -xz의 await, util, queue 관련 지표를 latency와 함께 본다.Dirty,Writeback, page cache를 확인해 flush 압박을 본다.- 큰 파일 읽기는
readAllBytes()보다 streaming을 먼저 검토한다. - durability가 필요한 쓰기와 단순 buffer flush를 구분한다.
- 같은 disk에 로그, dump, upload, DB volume이 몰려 있는지 확인한다.
주니어 팁
Disk IO와 Buffered IO주제는 용어 암기보다 정상 상태와 장애 상태에서 어떤 증거가 달라지는지 연결해 익힌다.- 처음에는
Disk IO와 Buffered IO를 재현 가능한 기본 명령과 Actuator 지표로 확인하는 습관부터 만든다. Disk IO와 Buffered IO숫자는 크기 자체보다 평소 기준선에서 얼마나 벗어났는지로 판단한다.
시니어 팁
Disk IO와 Buffered IO주제의 영향이 pool, queue, retry, timeout으로 번지는 경로를 설계 리뷰에 포함한다.Disk IO와 Buffered IOrunbook에는 실행 명령, 정상 범위, 해석 기준, 금지할 대응을 같이 둔다.Disk IO와 Buffered IO판단이 container, LB, 다중 인스턴스 환경에서도 같은 의미인지 확인한다.
Guru급 팁
Disk IO와 Buffered IO주제는 단일 snapshot보다 변화 방향이 중요하다. 같은 명령을 간격을 두고 실행해 상태가 증가, 유지, 회복 중 어디인지 본다.- 고급 도구는
Disk IO와 Buffered IO가설을 좁힐 때만 사용하고 기본 지표와 모순되는지 먼저 확인한다. Disk IO와 Buffered IO조치 후에는 CPU, memory, socket, disk, pool 중 다음 포화 지점이 어디로 이동했는지 확인한다.
위험 신호!
- CPU가 낮다는 이유로 I/O 병목을 배제한다.
write()가 반환됐으니 disk 반영도 끝났다고 생각한다.- page cache 영향 때문에 재현 환경과 운영 latency가 다른데 무시한다.
- heap dump나 로그 폭주가 같은 disk를 압박하는 상황을 놓친다.
readAllBytes()로 큰 파일을 한 번에 올려 memory와 I/O를 동시에 압박한다.
확인 질문
확인 질문
Disk IO와 Buffered IO주제를 장애 중 확인할 때 Application 로그만으로 부족한 이유는 무엇인가?
- 로그는 코드 경로를 보여 주지만
Disk IO와 Buffered IO의 JVM/OS 자원 상태, 대기 위치, 포화 방향은 별도 지표로 확인해야 하기 때문이다.Disk IO와 Buffered IO관련 설정이나 pool 크기를 바꾸기 전에 확인할 것은 무엇인가?
- 먼저 변한 신호, 하위 자원 capacity, 변경이 완화인지 증폭인지 판단할 기준을
Disk IO와 Buffered IO지표로 확인해야 한다.Disk IO와 Buffered IO재발을 막기 위해 장애 기록에 무엇을 남겨야 하는가?
- 발생 시간, 영향 범위, 사용한 명령,
Disk IO와 Buffered IO핵심 지표, 원인 판단, 완화 조치, 근본 수정, 남은 리스크를 남긴다.