대형 마트 계산대를 떠올려 보자. 손님이 한 줄로만 서면 계산대가 아무리 많아도 소용이 없다. 안내 직원이 “3번 계산대 비었습니다”라며 손님을 빈 줄로 흩어 주어야 전체가 빠르게 돌아간다. 웹 서비스에서 이 안내 직원 역할을 하는 장치가 바로 로드 밸런서(load balancer)다. 밀려드는 사용자 요청을 뒤편의 여러 서버에 고르게 나눠, 한 대에 부하가 몰려 쓰러지지 않게 막는다. 트래픽이 조금만 커져도 서버 한 대로는 감당이 안 되는 오늘날, 로드 밸런서는 사실상 모든 규모 있는 서비스의 기본 장비다. 이 글은 로드 밸런서가 정확히 무엇이고, 어떤 원리와 알고리즘으로 트래픽을 나누는지를 개발자 관점에서 정리한다.
로드 밸런서란 무엇인가 — 트래픽을 나누는 분배기
로드 밸런서는 이름 그대로 부하(load)를 고르게 맞춘다(balance). 사용자와 서버 무리 사이에 서서, 들어오는 요청을 여러 서버에 분산시키는 장치나 소프트웨어를 말한다. 이렇게 부하를 나누는 행위 자체를 로드 밸런싱(load balancing)이라고 부른다.
핵심 발상은 단순하다. 한 대의 서버가 처리할 수 있는 요청에는 한계가 있으니, 여러 대를 두고 일감을 쪼개 주자는 것이다. 사용자는 로드 밸런서의 대표 주소 하나만 바라보고, 그 뒤에 실제 서버가 몇 대인지는 알 필요가 없다. AWS의 정의에 따르면, 로드 밸런싱은 애플리케이션을 지원하는 여러 자원에 네트워크 트래픽을 고르게 분배하는 방법으로, 확장성과 안정성을 동시에 확보하는 핵심 수단이다.
여기서 한 가지 짚고 갈 것이 있다. 이 장치는 앞선 글에서 다룬 리버스 프록시와 개념이 겹친다. 실제로 리버스 프록시가 수행하는 여러 역할 가운데 ‘부하 분산’만 전문화한 것이 로드 밸런서라고 봐도 무방하다. 둘은 배타적인 장비가 아니라, 하나의 소프트웨어(예: Nginx)가 두 역할을 겸하는 경우가 흔하다.
왜 필요한가 — 확장성과 고가용성
로드 밸런서를 도입하는 이유는 크게 두 가지로 압축된다. 확장성(scalability) 과 고가용성(high availability) 이다.
- 확장성: 트래픽이 늘면 서버를 옆으로 늘려(수평 확장, scale-out) 대응한다. 새로 추가한 서버에도 요청이 자동으로 나뉘므로, 이론상 서버를 추가하는 만큼 처리량이 커진다. 서버 한 대의 사양을 키우는 수직 확장과 달리, 물리적 한계에 덜 부딪힌다.
- 고가용성: 서버 한 대가 죽어도 서비스가 멈추지 않는다. 이 장치는 각 서버의 상태를 주기적으로 점검하다가, 응답이 없는 서버에는 요청을 보내지 않고 살아 있는 서버로만 트래픽을 돌린다. 사용자는 장애가 났는지조차 모르고 지나간다.
이 두 가지는 안정적인 서비스 운영의 근간이다. 갑작스러운 트래픽 폭증(이벤트·마케팅·입소문)에도 서버를 늘려 버티고, 일부 서버에 문제가 생겨도 전체가 무너지지 않는다. 여러 인스턴스를 수평 확장하는 쿠버네티스 같은 오케스트레이션 환경이 로드 밸런서와 뗄 수 없는 관계인 것도 이 때문이다. 쿠버네티스의 Service(type=LoadBalancer)나 Ingress가 바로 이 분산 역할을 맡는다.
L4 vs L7 — 어느 계층에서 나누나
이를 이해할 때 반드시 마주치는 구분이 L4냐 L7이냐다. 이는 OSI 네트워크 모델에서 어느 계층의 정보를 보고 트래픽을 나누는지를 가리킨다.
| 구분 | L4 로드 밸런서 | L7 로드 밸런서 |
|---|---|---|
| 판단 기준 | IP·포트 (전송 계층) | URL·헤더·쿠키 (애플리케이션 계층) |
| 속도 | 빠름 (내용을 안 봄) | 상대적으로 느림 (내용을 해석) |
| 정교함 | 단순 분배 | 경로·조건별 라우팅 가능 |
| 예시 판단 | “이 연결을 3번 서버로” | “/api 요청은 API 서버군으로” |
- L4(전송 계층): 패킷의 IP 주소와 포트만 보고 서버를 정한다. 내용물을 뜯어보지 않으니 빠르고 부담이 적다. 단순히 연결을 고르게 흩뿌리는 데 적합하다.
- L7(애플리케이션 계층): HTTP 요청의 URL·헤더·쿠키까지 들여다보고 판단한다. “이미지 요청은 이미지 서버로,
/api경로는 API 서버로” 같은 콘텐츠 기반 라우팅이 가능하다. 그만큼 연산 비용이 더 들지만 훨씬 정교하다.
오늘날 웹 서비스에서 흔히 말하는 로드 밸런서는 대개 L7이다. 마이크로서비스 구조에서 경로별로 서로 다른 서비스에 요청을 보내야 하는 REST API 게이트웨이 같은 상황에서는 L7의 세밀한 라우팅이 필수적이다. Cloudflare의 설명도 이 두 계층의 차이를 로드 밸런싱 이해의 핵심으로 짚는다.
트래픽을 나누는 알고리즘
로드 밸런서가 “어느 서버로 보낼지”를 정하는 규칙을 분산 알고리즘이라고 한다. 상황에 따라 여러 방식을 골라 쓴다.
- 라운드 로빈(Round Robin): 서버에 순서대로 돌아가며 배정한다. 1→2→3→1→2→3… 가장 단순하고 직관적이다. 서버 사양이 비슷할 때 잘 맞는다.
- 가중 라운드 로빈(Weighted Round Robin): 서버마다 가중치를 두어, 사양이 좋은 서버에 더 많은 요청을 준다. 성능이 제각각인 서버가 섞여 있을 때 유용하다.
- 최소 연결(Least Connections): 현재 연결 수가 가장 적은 서버로 보낸다. 요청마다 처리 시간이 들쭉날쭉할 때, 실제 부하를 더 잘 반영한다.
- IP 해시(IP Hash): 클라이언트 IP를 해싱해 늘 같은 서버로 보낸다. 특정 사용자를 같은 서버에 붙여 두어야 할 때 쓴다.
어떤 알고리즘이 “정답”이라고 단정하긴 어렵다. 서버 사양이 균일한지, 요청 처리 시간이 일정한지, 세션을 유지해야 하는지에 따라 최적의 선택이 달라진다. NGINX 문서는 기본값으로 라운드 로빈을 두되 워크로드 특성에 맞춰 바꾸라고 권한다.
헬스 체크와 세션 유지
로드 밸런서를 실무에서 쓸 때 알고리즘만큼 중요한 두 개념이 있다.
헬스 체크(health check) 는 로드 밸런서가 각 서버의 생사를 확인하는 절차다. 주기적으로 정해진 경로(예: /health)에 요청을 보내 정상 응답이 오는지 본다. 응답이 없거나 오류가 반복되면 그 서버를 분배 대상에서 빼고, 다시 살아나면 복귀시킨다. 앞서 말한 고가용성이 실제로 작동하게 하는 장치가 바로 이 헬스 체크다.
세션 유지(sticky session) 는 특정 사용자의 요청을 계속 같은 서버로 보내는 기능이다. 로그인 정보나 장바구니 같은 상태를 개별 서버 메모리에 들고 있는 경우, 매 요청이 다른 서버로 튀면 상태가 유실된다. 이를 막으려 같은 사용자를 한 서버에 고정하는 것이다. 다만 세션 유지는 부하가 한쪽으로 쏠리게 만드는 부작용이 있어, 요즘은 세션 정보를 공유 저장소(예: Redis)에 두고 서버를 상태 없이(stateless) 만드는 편을 더 권장한다.
어디서 구현하나 — 하드웨어부터 클라우드까지
로드 밸런서는 형태가 다양하다.
- 소프트웨어 로드 밸런서: Nginx, HAProxy처럼 일반 서버에 설치해 쓰는 방식. 유연하고 비용이 낮아 가장 널리 쓰인다.
- 하드웨어 로드 밸런서: 전용 장비로 처리하는 방식. 초고성능이 필요한 대규모 환경에서 쓰이지만 비싸다.
- 클라우드 관리형 로드 밸런서: AWS ELB, Google Cloud Load Balancing처럼 클라우드 사업자가 제공하는 서비스. 직접 구축·운영할 필요 없이 설정만으로 확장까지 자동화된다(Google Cloud 문서).
오늘날 대부분의 서비스는 클라우드 관리형을 택한다. 직접 장비를 세우고 이중화하는 부담을 클라우드에 넘기고, 트래픽에 따라 자동으로 늘고 주는 편의를 얻기 때문이다.
도입 시 저울질할 것
로드 밸런서는 확장성과 안정성을 크게 높여 주지만, 공짜는 아니다.
- 그 자체가 단일 장애점이 될 수 있다: 모든 트래픽이 이 장치를 거치므로, 이것이 죽으면 뒤편 서버가 멀쩡해도 서비스가 멈춘다. 그래서 로드 밸런서 자체도 이중화해 두는 것이 정석이다.
- 상태 관리가 까다로워진다: 요청이 매번 다른 서버로 갈 수 있으니, 서버가 로컬에 상태를 들고 있으면 문제가 생긴다. 앞서 본 세션 유지나 공유 저장소 설계가 필요해진다.
- 비용과 복잡도: 서버를 여러 대 두고 분산 구조를 운영하는 만큼, 단일 서버보다 비용과 관리 부담이 커진다.
그렇다면 언제 필요할까? 트래픽이 서버 한 대의 처리 한계를 넘어서거나, 무중단 서비스가 중요하거나, 향후 확장을 염두에 둔 서비스라면 로드 밸런서는 사실상 필수다. 반대로 방문자가 적고 짧은 다운타임을 감당할 수 있는 서비스라면, 굳이 초기부터 분산 구조를 갖출 이유는 없다. 여러분이 운영하는 서비스가 지금 어느 쪽에 가까운지 가늠해 보면 도입 시점을 판단하기 쉬워진다.
정리 — 로드 밸런서를 이해하는 핵심 관점
로드 밸런서는 “트래픽을 여러 서버에 고르게 나누는 분배기”라는 한 문장으로 요약된다. 핵심을 다시 짚으면 이렇다.
- 정의: 사용자 요청을 뒤편 여러 서버에 분산해, 한 대에 부하가 몰리지 않게 한다.
- 목적: 서버를 옆으로 늘리는 확장성과, 일부가 죽어도 버티는 고가용성을 확보한다.
- 계층: IP·포트만 보는 L4와, URL·헤더까지 보는 L7로 나뉜다. 정교한 라우팅은 L7의 몫이다.
- 알고리즘: 라운드 로빈·가중치·최소 연결·IP 해시 중 워크로드 특성에 맞게 고른다.
- 운영: 헬스 체크로 죽은 서버를 걸러내고, 필요하면 세션 유지로 상태를 지킨다.
로드 밸런서는 리버스 프록시·CDN과 뿌리를 공유하면서도, ‘부하 분산’이라는 한 가지 임무에 특화된 개념이다. 이 셋의 관계를 함께 잡아 두면 웹 인프라 앞단의 그림이 완성된다. 여러분이 접속하는 규모 있는 서비스라면, 그 뒤에는 십중팔구 로드 밸런서가 조용히 요청을 나눠 담고 있을 것이다. 다음 글에서는 서버 사이의 비동기 통신을 책임지는 메시지 큐를 다룬다.
