I/O 작업과 CPU 작업: 개념 및 동작 방식
1. I/O 작업 (Input/Output)
개념
• I/O 작업은 **외부 시스템(디스크, 네트워크, DB 등)**과 데이터를 주고받는 작업입니다.
• CPU가 아닌 하드웨어 장치와 통신하며, 시간이 오래 걸릴 수 있습니다.
• 예: 파일 읽기/쓰기, 네트워크 요청, 데이터베이스 조회 등.
특징
• 상대적으로 속도가 느림 (네트워크 지연, 디스크 접근 시간 등).
• CPU는 이 작업 중에 대기 상태로 남아 있을 수 있음.
동작 방식
1. 프로세스는 I/O 작업 요청을 보냄.
2. 하드웨어 장치(디스크, 네트워크 등)가 작업을 수행.
3. 작업 완료 후, 프로세스는 결과를 받음.
2. CPU 작업
개념
• CPU 작업은 데이터를 계산하거나 로직을 처리하는 작업입니다.
• CPU에서 직접 수행되며, 상대적으로 빠릅니다.
• 예: 데이터 가공, 알고리즘 계산, 암호화/복호화, 데이터 매핑 등.
특징
• 메모리 내에서 동작하며, CPU 자원을 소모.
• 다중 작업을 효율적으로 처리하려면 CPU 사용량 관리가 중요.
동작 방식
1. 데이터를 메모리에 로드.
2. CPU가 계산/처리를 수행.
3. 결과를 반환.
3. I/O와 CPU 작업의 분리 필요성
문제점
• 동기적으로 I/O 작업과 CPU 작업을 처리하면 자원 낭비가 발생.
• 예: CPU가 빠르게 처리할 수 있는 작업을 대기하는 동안 I/O 작업 완료를 기다림.
분리의 이점
1. 효율적인 자원 사용:
• I/O 작업은 CPU를 사용하지 않으므로, I/O 작업 중에는 CPU를 다른 작업에 사용할 수 있음.
2. 병렬 처리:
• 비동기를 통해 여러 I/O 작업을 동시에 실행.
3. 응답 속도 개선:
• CPU는 대기 없이 로직을 처리할 수 있어 시스템 응답 속도가 빨라짐.
4. 실제 스프링 프로젝트에서 I/O 작업과 CPU 작업
I/O 작업의 예
1. 데이터베이스 조회
• userRepository.findById(id)
• DB 서버와 통신해 데이터를 가져오는 작업.
2. 네트워크 요청
• REST API 호출 (RestTemplate or WebClient).
3. 파일 읽기/쓰기
• 서버 로컬 파일 시스템에서 로그 파일을 읽거나 쓰는 작업.
CPU 작업의 예
1. 데이터 가공
• DB에서 조회한 데이터를 포맷 변경.
2. 알고리즘
• 대규모 연산, 통계 처리, 암호화/복호화.
3. 비즈니스 로직
• 조건에 따라 데이터를 처리하고 응답을 생성.
5. 예제: 스프링에서의 I/O와 CPU 작업
I/O 작업: 사용자 데이터 조회
public User getUserById(Long id) {
// 데이터베이스 조회 (I/O 작업)
return userRepository.findById(id)
.orElseThrow(() -> new RuntimeException("User not found"));
}
CPU 작업: 데이터 가공
public String processUserData(User user) {
// CPU 작업 (데이터 포맷 변경)
return user.getName().toUpperCase() + " - " + user.getEmail();
}
I/O + CPU 작업
public String getUserInfo(Long id) {
// I/O 작업
User user = getUserById(id);
// CPU 작업
return processUserData(user);
}
6. 비동기적으로 분리하기
효율적인 비동기 처리
public CompletableFuture<User> getUserByIdAsync(Long id) {
return CompletableFuture.supplyAsync(() ->
userRepository.findById(id)
.orElseThrow(() -> new RuntimeException("User not found"))
);
}
public CompletableFuture<String> processUserDataAsync(User user) {
return CompletableFuture.supplyAsync(() ->
user.getName().toUpperCase() + " - " + user.getEmail()
);
}
public CompletableFuture<String> getUserInfoAsync(Long id) {
return getUserByIdAsync(id)
.thenCompose(user -> processUserDataAsync(user));
}
7. 결론
• I/O 작업: 느리고 CPU를 사용하지 않음. 비동기로 처리하면 효율적.
• CPU 작업: 빠르지만 자원을 소모. 비즈니스 로직에 최적화.
• 실제 스프링에서의 적용:
• 비동기 처리(CompletableFuture, @Async)를 통해 I/O와 CPU 작업 분리.
• 동기적으로 처리해도 문제 없을 만큼 단순한 로직은 비동기 처리 불필요.
'spring' 카테고리의 다른 글
[Spring] CompletableFuture 동작 예시 (2) | 2025.01.16 |
---|---|
[Spring] CompletableFuture 등장 배경 (1) | 2025.01.16 |
[Spring] Spring에서의 동기 비동기 (0) | 2025.01.06 |
[Spring] Jackson (0) | 2024.12.17 |
[Spring] JWT기반 로그인 예시 (0) | 2024.12.11 |