멀티스레드와 Context Switching 구조까지 공부하다 보면 자연스럽게 이런 의문이 생긴다. “그럼 서버는 수만 명이 동시에 접속하면 어떻게 버티는 걸까?” 나도 예전에는 웹서버가 단순히 CPU 성능이 좋아서 많은 사용자를 처리하는 줄 알았다. 그런데 실제 서버 구조를 조금씩 찾아보다 보니까, 현대 서버는 단순히 스레드를 많이 만드는 방식으로 움직이지 않는다는 걸 알게 됐다. 특히 동시에 연결(Connection)이 엄청 많아지는 순간부터는 오히려 스레드가 많을수록 성능이 급격히 나빠질 수도 있었다.
그리고 이 문제를 해결하기 위해 등장한 핵심 기술 중 하나가 바로 Epoll이다. 처음에는 이름만 봐도 너무 리눅스 커널 내부 용어 같아서 어렵게 느껴졌는데, 구조를 이해하고 나니까 “왜 현대 웹서버가 이벤트 기반(Event-Driven) 구조를 사용하는지” 조금 감이 오기 시작했다.

예전 방식은 연결마다 계속 확인해야 했다
서버는 기본적으로 수많은 네트워크 연결을 동시에 관리해야 한다. 예를 들어 웹사이트에 사람들이 접속하면 서버는 각 연결(Socket)을 계속 감시하면서 데이터가 들어왔는지 확인해야 한다.
예전 방식에서는 select()나 poll() 같은 시스템 호출을 많이 사용했다. 쉽게 말하면 운영체제가 “이 연결들 중에서 누가 데이터 들어왔는지 확인해줘”라는 요청을 반복적으로 처리하는 구조였다.
문제는 연결 수가 많아질수록 이 방식이 굉장히 비효율적이 된다는 점이었다. 예를 들어 수만 개 연결이 있으면 운영체제는 매번 엄청 많은 소켓 상태를 전부 검사해야 한다.
나도 처음에는 “컴퓨터가 빠른데 그냥 다 확인하면 되는 거 아닌가?” 싶었는데, 실제로는 대부분 연결이 아무 일도 안 하고 있는 경우가 훨씬 많다고 한다. 즉, 서버는 거의 대부분 시간을 “아무 데이터 안 들어옴”을 계속 확인하는 데 쓰게 되는 것이다.
특히 연결마다 스레드를 하나씩 생성하는 방식은 더 큰 문제를 만든다. 스레드 수가 너무 많아지면 Context Switching 비용까지 급격히 증가하기 때문이다.
예전에 대규모 채팅 서버 구조 관련 글을 보다가 “현대 서버는 연결 수만큼 스레드를 만들지 않는다”는 내용을 본 적이 있었는데, 그때 처음으로 “동시에 많은 연결을 처리하는 건 단순 CPU 성능 문제가 아니구나”라는 걸 느끼게 됐다.
Epoll은 ‘이벤트가 발생한 연결만’ 알려주는 구조다
Epoll의 핵심은 굉장히 단순하다. “모든 연결을 계속 검사하지 말고, 실제로 이벤트가 발생한 연결만 알려주자”는 것이다.
즉, 운영체제가 내부적으로 소켓 상태를 관리하다가:
- 데이터 도착
- 연결 종료
- 쓰기 가능 상태
같은 이벤트가 발생했을 때만 서버 프로그램에게 알려주는 방식이다.
처음 이 개념을 이해했을 때 꽤 인상 깊었다. 예전 방식은 계속 출석 체크하는 느낌이었다면, Epoll은 “문제 생기면 부를게” 구조에 가까웠기 때문이다.
덕분에 서버는 수만 개 연결이 있더라도 실제 이벤트가 발생한 일부 연결만 처리하면 된다. 즉, 불필요한 반복 검사와 Context Switching을 크게 줄일 수 있는 것이다.
나도 예전에는 Nginx나 Node.js 같은 서버들이 왜 “이벤트 기반 구조”를 강조하는지 잘 몰랐는데, Epoll 구조를 이해하고 나니까 왜 스레드를 무한정 늘리는 대신 이벤트 루프(Event Loop)를 사용하는지 조금 감이 오기 시작했다.
특히 현대 웹서비스에서는 대부분 연결이 “대기 상태”인 경우가 많기 때문에, Epoll 방식이 훨씬 효율적이라고 한다.
그래서 현대 서버는 ‘많은 스레드’보다 ‘효율적인 이벤트 처리’를 중요하게 본다
처음 서버 구조를 공부할 때는 “동시에 많은 사용자 처리 = 스레드 엄청 많이 생성”이라고 생각하기 쉽다. 나도 예전에는 그게 당연한 방식인 줄 알았다.
그런데 실제로는 스레드가 많아질수록:
- 메모리 사용량 증가
- Context Switching 비용 증가
- 캐시 효율 저하
같은 문제들이 계속 발생한다.
그래서 현대 서버는 단순히 스레드를 늘리는 대신, 가능한 적은 스레드로 엄청 많은 연결을 효율적으로 관리하려고 한다. 그리고 그 중심에 Epoll 같은 이벤트 기반 구조가 있는 것이다.
나도 처음에는 “대규모 서버 = 엄청 비싼 CPU” 정도로만 생각했는데, 실제로는 운영체제 내부 이벤트 처리 구조와 네트워크 관리 방식 자체가 굉장히 중요한 역할을 하고 있다는 걸 알게 됐다.
특히 요즘처럼 실시간 채팅, 스트리밍, 게임 서버처럼 수많은 연결을 계속 유지해야 하는 환경에서는 Epoll 같은 구조가 사실상 필수 수준이라고 한다.
이걸 공부하면서 가장 인상 깊었던 건 현대 서버는 단순히 “빠르게 계산하는 컴퓨터”가 아니라는 점이었다. 결국 핵심은 얼마나 많은 연결과 이벤트를 불필요한 낭비 없이 효율적으로 관리할 수 있느냐였던 것이다.
한 줄로 정리하면 Epoll은 수많은 네트워크 연결 중 실제 이벤트가 발생한 연결만 효율적으로 알려주는 리눅스 이벤트 처리 구조이며, 대규모 서버에서 Context Switching과 불필요한 검사 비용을 줄이는 핵심 기술이다.