Contents
1. 용어
2. 스레드 수와 성능
3. I/O bound 시스템의 적절한 스레드 수 설정
4. EatDa에서의 트러블슈팅 경험
1. 용어
버스트(burst):
- 어떤 작업이 짧은 시간 동안 집중적으로 수행되는 구간
CPU 버스트:
- 프로세스가 CPU에서 연속적으로 실행되는 시간
- CPU 버스트는 대부분 8ms 이하의 짧은 시간을 가지고 있다.
IO 버스트:
- 프로세스가 I/O 작업을 요청하고 대기하는 시간
CPU bound:
- CPU 연산이 병목인 작업
- CPU 사용률이 높고 I/O 대기 시간은 적다.
- 동영상 인코딩, 머신러닝 연산
IO bound:
- I/O 대기가 병목인 작업
- CPU는 자주 대기 상태가 되고, I/O 대기 시간이 길다.
- 웹 서버(API 서버), DB 조회, 네트워크 요청
2. 스레드 수와 성능
2.1 CPU bound

CPU를 최대한 활용하는 것이 중요하다.
- 스레드 수를 늘려도 성능 향상은 제한적이다.
- CPU bound 환경에서는 스레드가 CPU 자원을 두고 경쟁하게 되므로, 스레드 수가 많아질수록 컨텍스트 스위칭이 증가하여 오버헤드가 발생한다.
적절한 스레드 수:
- CPU 코어 수
- 약간의 여유를 두어 CPU 코어 수 + 1 정도로 설정하기도 한다. (Goetz)
2.2 I/O bound

I/O 대기 동안 CPU를 놀리지 않는 것이 중요하다.
- 스레드 수를 늘리면 성능 향상이 가능하다.
적절한 스레드 수:
- 스레드 수 ≈ CPU 코어 수 × (1 + I/O 대기 시간 / CPU 사용 시간)
3. I/O bound 시스템의 적절한 스레드 수 설정

IO bound 시스템에서는 정해진 가이드라인이 없으므로, 여러 상황을 고려해 적절한 스레드 개수를 찾아야 한다.
- 스레드 수가 많을수록 좋은 것은 아니다.
- 과도한 스레드는 컨텍스트 스위칭 비용과 메모리 사용량을 증가시킨다.
고려 요소:
- CPU 코어 수
- I/O 대기 시간
- 동시 요청 수
- 요청 처리 시간
- 외부 시스템 성능(DB, API)
튜닝 과정:
-
모니터링
- CPU 사용률
- 요청 처리 시간(latency)
- 처리량(throughput)
- 대기 시간(queue length)
-
병목 판단
- CPU 사용률이 높고 latency 증가 → CPU bound
- CPU 사용률이 낮고 latency 높음 → IO bound
-
스레드 수 조정
- 스레드 수를 점진적으로 증가
- throughput 증가 여부 확인
- latency 변화 확인
-
임계 지점 탐색
- throughput 증가가 멈추는 지점 확인
- latency가 급격히 증가하는 지점 확인
- CPU 사용률이 포화되는 시점 확인
-
최적값 결정
- throughput은 충분히 확보하면서
- latency가 안정적인 지점 선택
스레드 수를 늘릴수록 처리량은 증가하지만,
특정 시점 이후에는 latency 증가와 context switching 비용으로 인해 전체 성능이 오히려 저하될 수 있다.
4. EatDa에서의 트러블슈팅 경험


리뷰 생성 API 성능 테스트 과정에서 CPU 사용률이 100%를 찍으며 서버가 다운되는 문제가 발생했다.
초기 분석 결과:
- CPU 코어가 모두 100% 사용되는 상태
- 요청 처리 중 이미지 처리 작업이 CPU를 집중적으로 사용
CPU 사용률이 100%에 도달했으며, 이미지 처리 과정에서 CPU-intensive 작업이 병목으로 작용하고 있었다.
4.1 스레드 수 증가 시도
처음에는 스레드 수를 늘리면 성능이 개선될 것이라 예상했다. 하지만 효과는 없었고 오히려 응답 시간이 증가했다.
CPU bound 환경에서 스레드 수 증가:
- CPU 자원 경쟁 발생
- 컨텍스트 스위칭 빈도 증가
- 오버헤드 증가
4.2 비동기 처리 도입

이미지 업로드 작업을 비동기로 분리한 결과:
- CPU 사용률 100% → 10 ~ 20% 수준으로 감소
- 요청 처리 안정성 확보
- dropped 요청 제거
분석:
- HTTP 요청 스레드가 블로킹되지 않도록 개선
- 작업이 분산되면서 CPU 사용 패턴이 안정화
비동기 처리로 HTTP 요청 스레드의 블로킹이 제거되면서, 요청 처리 구조가 개선되고 CPU 사용 패턴이 안정화 되었다.
4.3 이미지 최적화 로직 제거(webp, 리사이징)

결과:
- CPU 사용률↓
- 응답시간 증가(3.76s → 13.53s)
이미지 최적화 작업(디코딩, 리사이징, 인코딩)이 모두 CPU bound 작업이므로 CPU 사용률은 줄었으나,
- 이미지 크기 증가
- 이미지 최적화 로직 제거로 데이터 크기가 증가하면서 네트워크 전송 시간과 디스크 I/O가 증가
CPU와 I/O는 trade-off 관계이며, 한쪽의 부담을 줄이면 다른 쪽이 병목으로 드러날 수 있다.
4.4 결론
CPU 부담을 줄인다고 성능이 항상 좋아지는 것은 아니다.
병목은 제거되는 것이 아니라, 시스템 내 다른 자원으로 전이된다.