피드로 돌아가기
From one blocking accept() to epoll: a C TCP server up the I/O ladder, measured
Dev.toDev.to
Infrastructure

Blocking I/O에서 epoll까지, CPU 99%에서 0%로의 최적화 여정

From one blocking accept() to epoll: a C TCP server up the I/O ladder, measured

Valentyn Kit2026년 6월 30일12advanced

Context

단일 스레드 기반 TCP 서버에서 Blocking I/O 사용 시 발생하는 Head-of-Line Blocking 문제 분석. 특정 클라이언트의 지연이 전체 시스템의 응답 중단으로 이어지는 구조적 한계 극복을 목표로 함.

Technical Solution

  • O_NONBLOCK 모드 도입을 통한 non-blocking I/O 구현으로 개별 클라이언트의 대기 시간이 타 연결에 영향을 주지 않는 구조 설계
  • Polling 방식의 CPU 자원 낭비를 해결하기 위해 Readiness Notification 기반의 select 시스템 콜 도입
  • select의 FD_SETSIZE 제약 및 매 루프마다 fd_set을 복사해야 하는 오버헤드 해결을 위해 poll 및 epoll로 점진적 확장
  • epoll의 Event-driven 메커니즘을 통해 커널이 준비된 fd만 반환하게 함으로써 O(n)에서 O(1) 수준의 효율성 달성
  • 스트림 데이터를 메시지 단위로 처리하는 Framing Rule 적용으로 메모리 바운드 설정 및 프로토콜 안정성 확보

Impact

  • Blocking I/O에서 발생한 1.51초의 응답 지연을 non-blocking 전환으로 완전히 제거
  • Non-blocking Polling 시 발생한 98~99%의 CPU 점유율을 select 도입 직후 0% 수준으로 급감

Key Takeaway

단순한 API 교체가 아닌 '상태를 계속 묻는 방식(Polling)'에서 '이벤트 발생 시 깨어나는 방식(Notification)'으로의 패러다임 전환이 시스템 확장성의 핵심임.


- 고성능 네트워크 서버 설계 시 I/O 모델이 CPU 자원 소모량에 미치는 영향 정밀 측정 - 대규모 연결 처리가 필요한 경우 O(n) 복잡도를 가진 select/poll 대신 epoll/kqueue 검토 - TCP 스트림의 경계 부재 문제를 해결하기 위한 명확한 Application-level Framing 프로토콜 정의

원문 읽기