1.시스템&인프라/개발 입문자를 위한 운영체제

15편. 저장장치 I/O 완전 정복 – 입출력 처리 방식과 병목 진단 실습

쿼드큐브 2025. 11. 22. 08:44
반응형
반응형

15편. 저장장치 I/O 완전 정복 – 입출력 처리 방식과 병목 진단 실습

 

📚 목차
1. 저장장치 I/O는 어떻게 작동할까? - 저장장치 I/O의 흐름 이해
2. I/O 처리 방식 비교 - 누가 데이터를 옮기는가?
3. I/O 병목 분석 - 어디서 속도가 막히는가?
4. 실무 사례로 보는 I/O 성능 저하 원인
✔ 마무리 - 성능 튜닝은 I/O 이해에서 시작된다.

 

운영체제를 학습하다 보면 CPU와 메모리 같은 핵심 자원에만 집중하기 쉽습니다. 그러나 실제 시스템 성능에 있어 저장장치 I/O는 예상을 뛰어넘는 영향을 미칩니다. 아무리 빠른 CPU와 충분한 메모리를 갖췄다 하더라도, 느린 디스크 입출력 속도는 전체 시스템 반응성을 심각하게 떨어뜨릴 수 있습니다.


특히 로그 분석, 대규모 빌드, 백업, 영상 처리 등에서 I/O는 병목의 핵심 지점이 되며, 이때의 문제는 곧 작업 지연, 서버 멈춤, 사용자 불편으로 이어집니다.


이번 글에서는 I/O의 기본 작동 방식부터, 운영체제가 어떻게 입출력을 중재하는지, 그리고 병목이 실제로 발생하는 지점과 실무 개선 방법까지 단계적으로 살펴보겠습니다.

 

1. 입출력은 어떻게 작동할까? – 저장장치 I/O의 흐름 이해

컴퓨터에서 어떤 파일을 열거나 저장할 때, 이 작업은 단순히 파일 시스템을 거치는 것으로 끝나지 않습니다. 내부적으로는 CPU, 메모리, 디스크가 협력하여 데이터 입출력(I/O) 작업을 처리합니다.

특히 운영체제는 이 과정을 효율적으로 제어하고 중재하는 핵심 역할을 수행합니다.


예를 들어 사용자가 텍스트 편집기에서 sample.txt 파일을 열면, 이 요청은 다음과 같은 흐름을 거칩니다:

저장장치 I/O 처리 흐름 예시
저장장치 I/O 처리 흐름 예시

▸ 1. 사용자 앱이 OS에 파일 열기 요청.

▸ 2. OS는 디스크 컨트롤러에 파일 위치 조회 지시

▸ 3. 디스크가 데이터를 읽어 메모리로 전달 → 앱으로 연결

 

이처럼 디스크, 메모리, CPU가 협력하여 데이터를 주고받으며, 이 과정을 운영체제가 효율적으로 중재합니다.

 

I/O 처리 방식에 따라 시스템 자원 활용 효율이 크게 달라지며, 대표적인 방식은 다음과 같습니다:
🔸 Programmed I/O
🔸 Interrupt I/O
🔸 DMA (Direct Memory Access)

 

2. I/O 처리 방식 비교 – 누가 데이터를 옮기는가?

입출력(I/O) 처리 방식은 시스템의 성능과 자원 효율성에 큰 영향을 미칩니다. 특히 CPU가 얼마나 개입하느냐에 따라 전체 시스템의 처리 속도와 반응성이 달라집니다. 운영체제는 상황에 따라 다음 세 가지 주요 방식 중 하나를 선택해 장치와 데이터를 주고받습니다.

 

🟦 CPU가 직접 대기하는 방식 – Programmed I/O

Programmed I/O는 가장 기초적인 입출력 방식으로, CPU가 장치의 상태를 직접 감시하면서 I/O 작업을 수행하는 구조입니다.

CPU는 데이터를 요청한 후, 장치가 데이터를 준비할 때까지 계속 확인하면서 대기해야 합니다.

즉, CPU는 이 작업이 완료될 때까지 다른 어떤 작업도 하지 못하고 발이 묶인 상태가 됩니다.

 

🔸비유

회사 사장이 택배가 올 예정이라고 해서 하루 종일 문 앞에 서 있는 상황을 떠올려 보세요. 다른 일을 할 수도, 회의를 할 수도 없습니다.

그저 택배가 올지 안 올지 모르지만 계속 확인하고 있어야 합니다. 이것이 바로 Programmed I/O 방식입니다.

 

🔸예시

어떤 프로그램이 CPU를 통해 하드디스크에 저장된 log.txt 파일을 읽으려고 합니다.

이때 CPU는 디스크 컨트롤러에게 “파일을 읽어 달라”고 요청한 뒤, 디스크가 데이터를 준비하는 동안 매 순간 상태를 체크하며 기다립니다.

이 과정에서 CPU는 아무 다른 작업도 수행할 수 없습니다.

 

🔸단점 요약

▸ CPU 자원의 낭비: I/O 처리 중 CPU가 블로킹됨
▸ 멀티태스킹 불가: 다른 프로세스의 스케줄링이 지연됨
▸ 효율성 저하: 장치가 느릴수록 낭비가 커짐

 

이 방식은 매우 단순하고 구현하기는 쉽지만, 현대적인 시스템에서는 거의 사용되지 않으며, 임베디드 시스템이나 단순 컨트롤러에서 제한적으로 활용됩니다.

 

🟦 장치가 먼저 알리는 방식 – Interrupt I/O

Interrupt I/O는 Programmed I/O의 비효율을 개선한 방식으로, CPU가 작업만 요청하고, 다른 일을 하다가 장치가 완료되면 ‘인터럽트’ 신호로 알리는 구조입니다.

CPU는 응답을 기다리며 아무 것도 하지 않는 대신, 다른 프로그램을 실행하거나 계산을 수행하며 자신의 일을 계속합니다.

 

🔸비유

사장이 직접 기다리는 대신, 경비실에 택배가 오면 초인종을 눌러 알리는 시스템을 생각해 보세요.

사장은 자기 업무에 집중할 수 있고, 벨이 울리면 그제야 문 앞에 나갑니다. 이 구조가 Interrupt I/O입니다.

 

🔸예시

웹 브라우저가 큰 파일을 다운로드할 때, CPU는 다운로드 요청을 보낸 후 사용자 인터페이스(UI) 그리기나 다른 프로세스 실행을 계속합니다.

다운로드가 완료되면 장치가 CPU에 인터럽트를 보내 알려주고, CPU는 그 신호를 감지해 후속 작업(예: 저장, 사용자 알림 등)을 진행합니다.

 

🔸장점 요약

CPU 자원 활용 극대화: 대기 시간 최소화
반응성 향상: 사용자의 요청을 더 빠르게 처리 가능
다중 작업 처리: 멀티태스킹 환경에 적합

 

Interrupt I/O는 현대 운영체제에서 매우 일반적으로 사용되는 방식이며, 네트워크 처리, 키보드 입력, 마우스 클릭 등 다양한 이벤트 기반 작업에서 필수적입니다.

 

🟦 완전 자동화된 전송 – DMA

DMA(Direct Memory Access)는 가장 진보된 형태의 입출력 처리 방식으로, 입출력 장치가 CPU의 직접적인 개입 없이 메모리와 데이터를 주고받는 구조입니다.

CPU는 데이터 전송 요청만 하고, 이후의 실제 데이터 이동은 DMA 컨트롤러라는 하드웨어 장치가 대신 처리합니다.

 

🔸비유

사장이 업무에 집중하고 있을 때, 비서가 택배를 대신 받고, 사장에게는 “잘 받았습니다”라고 보고만 하는 상황을 상상해 보세요.

사장은 전혀 개입하지 않고도 택배 처리가 완료됩니다.

이처럼 CPU는 I/O 처리에서 완전히 자유로워지는 것이 DMA 방식입니다.

 

🔸예시

고해상도 4K 영상을 편집할 때, 수백 MB에 달하는 영상 데이터를 디스크에서 메모리로 읽어오는 작업은 매우 빈번합니다.

이 경우 DMA를 사용하면, CPU가 데이터를 하나하나 복사할 필요 없이, 장치가 메모리로 직접 데이터를 전송합니다.

CPU는 대신 영상 렌더링, 색 보정 등의 작업에 집중할 수 있습니다.

 

🔸장점 요약

▸ CPU 오버헤드 없음: 병렬 작업 성능 극대화

▸ 고속 데이터 전송에 유리: 영상, 이미지 처리, 머신러닝 등

▸ 복잡한 데이터 흐름 최적화 가능

 

DMA는 대용량 처리와 고성능 시스템에서 필수적인 기술이며, 특히 SSD, 그래픽 카드, 사운드 카드, 네트워크 인터페이스 등 다양한 고속 장치에서 폭넓게 사용됩니다.

반응형

 

3. I/O 병목 분석 – 어디서 속도가 막히는가?

입출력(I/O) 성능은 단순히 디스크의 속도만으로 결정되지 않습니다.

운영체제는 내부적으로 수많은 프로세스, 버퍼, 캐시, 디스크 드라이버, 파일 시스템 등 다양한 요소를 중재하면서 I/O를 처리합니다.

그렇기 때문에 고속 SSD를 사용해도 느려질 수 있고, CPU 사용률이 낮아도 시스템이 버벅거릴 수 있습니다.

 

🟦 Ubuntu에서 실습 – iostat와 iotop 사용하기

✔️ 1) iostat – 디스크 병목 숫자로 확인하기

iostat는 디스크의 입출력 성능을 실시간으로 확인할 수 있는 유용한 도구입니다.

특히 -xz 옵션을 사용하면 각 장치별 I/O 요청 수, 처리 속도, 대기 시간, 사용률 등을 1초 단위로 확장 출력할 수 있습니다.

sudo apt install sysstat        # iostat가 포함된 패키지 설치
iostat -xz 1                    # 1초마다 전체 디스크 I/O 상태 출력

iostat: 디스크 전체 사용률 예시
iostat: 디스크 전체 사용률 예시

▸ %util: 디스크 사용률 (100%에 가까울수록 포화 상태), 90% 이상이면 병목 가능성

▸ r_await / w_await: 읽기/쓰기 요청당 평균 대기 시간 (ms), 10~20ms 이상이면 주의

▸ aqu-sz : 요청 큐의 평균 깊이, 요청 큐의 평균 깊이

 

만약 /dev/sda의 %util이 98%이고 w_await가 120ms라면?

→ 이 디스크는 지속적으로 작업 중이며, 쓰기 요청은 평균 0.12초를 기다려야 처리됩니다.

이런 상태가 지속되면, 응답 지연, 시스템 멈춤, 데이터 손실 등 심각한 병목 현상으로 이어질 수 있습니다.

 

✔️ 2) iotop – 문제 프로세스를 추적하자

iotop은 top처럼 실시간으로 어떤 프로세스가 얼마나 많은 디스크 I/O를 사용하고 있는지를 보여주는 도구입니다.

sudo apt install iotop
sudo iotop

iotop 실행화면 예시
iotop 실행화면 예시

프로세스별 DISK READ, WRITE 속도, IO 비율, SWAPIN 등 항목이 실시간으로 출력되어 상위 점유자를 빠르게 파악할 수 있음

▸ TID : 프로세스 ID

▸ DISK READ / DISK WRITE : 읽기/쓰기 속도

▸ SWAPIN : 스왑 입출력 비율

▸ IO : 전체 I/O 사용 비율

 

▸활용 예시

rsync, fluentd, mysqld 등의 백업, 로그, DB 프로세스가 디스크 I/O를 과도하게 점유하는 경우 등, 특정 앱이 예상치 못하게 디스크를 지속적으로 읽고 쓴다면, 해당 프로세스가 병목의 직접적인 원인일 수 있습니다.

 

🟦 Windows에서 I/O 상태 확인하기

Linux가 아닌 Windows 환경에서도 유사한 방식으로 I/O 병목을 진단할 수 있습니다.

 

✔️ 1) 리소스 모니터 (Resource Monitor)

단축키: Ctrl + Shift + Esc → 작업 관리자 실행 > [성능] 탭 → 리소스 모니터 열기 클릭

Windows 리소스 모니터 예시
Windows 리소스 모니터 예시

🔸 확인할 포인트

▸ 디스크 활동량(MB/s)이 높은 프로세스는 병목 후보

▸ 응답 시간이 지나치게 긴 특정 파일 → 느려진 프로그램 또는 서비스

▸ 파일 경로를 통해 원인 앱을 추적 가능

 

🟦 병목의 단서는 어디에 있을까?

입출력 병목은 단순히 디스크가 느려서가 아닙니다. 문제는 예기치 않은 프로세스, 누적되는 큐, 지연되는 요청, 스왑 남용 등 시스템 전체의 상호작용에서 발생합니다.

 

도구는 많지만 핵심은 다음과 같습니다:

🔸 iostat: 장치 레벨의 병목을 찾는 데 유용

🔸 iotop: 프로세스 수준에서의 원인 추적에 강력

🔸 리소스 모니터: 시각화된 정보로 빠르게 확인 가능

 

4. 실무 사례로 보는 I/O 성능 저하 원인

실제 개발 환경에서 저장장치 I/O 병목 현상은 예상치 못한 성능 저하로 이어지는 경우가 많습니다. 특히 다음과 같은 상황에서는 CPU나 메모리보다 디스크 입출력 속도가 전체 작업 성능을 좌우하게 됩니다.

대용량 로그 분석이나 빌드 작업에서의 I/O 병목 예시
대용량 로그 분석이나 빌드 작업에서의 I/O 병목 예시

 

🟦 사례 1: 대용량 로그 분석이 느린 이유

운영 중인 서버에서 시스템 로그나 애플리케이션 로그를 분석할 때, grep, awk, tail 같은 명령어를 사용해 수십 GB에 달하는 로그 파일을 검색하는 일이 흔히 발생합니다.

 

🔸증상: 명령어를 실행하면 결과가 나올 때까지 수 분 이상 걸리며, 서버 응답이 잠시 느려집니다.


🔸원인: 로그 파일이 디스크에 저장되어 있고, 크기가 매우 크기 때문에 운영체제가 연속적으로 파일을 읽어야 합니다. 특히 HDD에서는 이 연속 읽기 속도가 매우 제한적입니다.

 

🔸개선 방법:

SSD 또는 NVMe 기반 저장장치로 로그를 저장하면 읽기 속도를 대폭 향상시킬 수 있습니다.

분석 작업 전에 로그 파일을 RAM 디스크로 복사해 처리하면, 메모리 기반 속도를 활용할 수 있어 응답 시간이 획기적으로 단축됩니다.

 

🟦 사례 2: 빌드 작업 시간이 과도하게 길어질 때

대형 프로젝트(C++, Java, Android 등)를 빌드하거나 테스트할 때, 성능이 낮은 시스템에서는 빌드 완료까지 몇 분에서 수십 분까지 소요되는 경우가 있습니다.

 

🔸증상: 빌드 중 CPU 사용률은 낮은데, 작업 시간이 매우 길어집니다.

 

🔸원인: 컴파일 및 링크 과정에서 수천 개의 소스 파일을 읽고 임시 파일을 생성해야 하며, 이 모든 과정이 디스크 I/O를 강하게 요구합니다. 디스크가 병목 구간이 되면, 전체 빌드 속도가 떨어질 수밖에 없습니다.

 

🔸개선 방법:

▸ SSD 또는 NVMe 저장장치를 사용하면 소스 파일 접근 속도가 빨라져 빌드 시간이 단축됩니다.

▸ 빌드 캐시 도구(ccache)를 사용하면 변경되지 않은 파일에 대한 반복 컴파일을 줄일 수 있습니다.

▸ make -j8과 같은 병렬 빌드 옵션을 통해 CPU 코어를 효율적으로 활용하면, I/O 병목 구간을 완화하고 전반적인 속도를 향상시킬 수 있습니다.

 

✔ 마무리 - 성능 튜닝은 I/O 이해에서 시작된다

시스템이 느린 진짜 원인은 CPU나 메모리보다 저장장치 I/O 병목인 경우가 많습니다. 특히 로그 분석, 빌드, 백업 등은 디스크 입출력이 성능의 핵심입니다.


Programmed I/O, Interrupt, DMA의 차이를 이해하고, iostat, iotop 같은 도구로 병목을 진단할 수 있다면, 불필요한 장비 증설 없이도 실질적인 성능 개선이 가능합니다.


📌 실무 핵심 요약:
🔸 SSD 교체만으로 속도 개선
🔸 빌드·분석 작업 시간 단축
🔸 문제 프로세스 빠르게 추적
🔸 고성능 시스템 설계 기반 마련


I/O는 보이지 않지만, 가장 강력한 성능 개선 포인트입니다.

 


※ 게시된 글 및 이미지 중 일부는 AI 도구의 도움을 받아 생성되거나 다듬어졌습니다.

반응형

 

 

반응형