카테고리 없음
I/O 바운드
늘이
2025. 1. 3. 13:59
I/O 바운드(I/O Bound)는 애플리케이션 성능이 입출력(Input/Output, I/O) 작업의 속도에 의해 제한되는 상태를 말합니다. I/O 작업은 보통 외부 리소스(디스크, 네트워크, 데이터베이스 등)와의 통신을 포함하며, CPU가 아닌 다른 리소스를 대기하는 데 시간이 걸립니다.
1. I/O 작업의 예
I/O 작업은 다음과 같은 작업들을 포함합니다:
- 네트워크 요청: 다른 서버와의 통신 (HTTP 요청, WebSocket 등)
- 파일 읽기/쓰기: 디스크에서 파일을 읽거나 쓰는 작업
- 데이터베이스 접근: SQL 쿼리를 실행하거나 데이터를 가져오는 작업
- 외부 API 호출: 외부 서비스와 통신 (REST API, GraphQL 등)
2. I/O 바운드와 CPU 바운드 비교
특징 | I/O 바운드 | CPU 바운드 |
제한 요인 | I/O 작업(네트워크, 디스크, 데이터베이스) 대기 시간 | CPU 연산 속도 |
예시 작업 | 데이터베이스 조회, 파일 읽기/쓰기, API 호출 | 이미지 처리, 암호화/복호화, 대규모 데이터 계산 |
해결 방법 | 비동기 처리, 멀티스레딩 | 고성능 CPU 사용, 병렬 처리 |
스레드 활용 | 스레드는 주로 I/O를 대기하면서 비활성 상태로 유지됨 | 스레드가 지속적으로 연산을 수행하며 활성 상태로 유지됨 |
3. I/O 바운드에서의 비동기의 이점
I/O 작업은 대기 시간이 많기 때문에, 비동기적으로 처리하면 대기 중인 스레드를 다른 작업에 재활용할 수 있습니다. 이렇게 하면 동시에 더 많은 요청을 처리할 수 있습니다.
동기 방식 (스레드 블로킹)
// HTTP 요청을 동기적으로 처리
String response = restTemplate.getForObject("https://example.com/api", String.class);
System.out.println(response); // 응답을 받기 전까지 스레드가 대기
- 하나의 요청이 완료될 때까지 스레드가 아무 작업도 하지 않고 대기합니다.
비동기 방식
// HTTP 요청을 비동기적으로 처리
webClient.get()
.uri("https://example.com/api")
.retrieve()
.bodyToMono(String.class)
.subscribe(response -> System.out.println(response));
- 요청이 완료될 때까지 스레드가 다른 작업을 처리할 수 있습니다.
4. I/O 바운드 시스템에서 비동기의 활용
- 고성능 웹 서버: 수많은 클라이언트 요청을 처리해야 하는 경우(예: 대규모 웹 서비스).
- 비동기 데이터베이스 접근: DB 쿼리를 기다리는 동안 다른 요청 처리.
- 멀티미디어 스트리밍: 네트워크 대기 시간이 많은 작업에서 효율적.
5. I/O 바운드에서의 비동기의 제한점
- 복잡성 증가: 비동기 코드의 흐름은 동기 코드보다 복잡할 수 있습니다.
- 오버헤드: 비동기 작업 생성과 컨텍스트 전환에도 비용이 발생합니다.
- 적합한 환경 필요: 비동기 코드가 효과를 발휘하려면 애플리케이션 구조가 적합해야 합니다(예: Netty 기반 WebFlux, 비차단형 데이터베이스).
6. 결론
I/O 바운드는 CPU가 작업을 수행하지 않고 대기 상태로 머무는 경우가 많아, 비동기 처리로 효율성을 높이는 것이 중요합니다.
트래픽이 높은 서비스나 외부 I/O 작업이 많은 애플리케이션에서는 비동기 프로그래밍을 적극적으로 활용하는 것이 좋습니다.