본 글은 educative.io 의 Grokking Modern System Design Interview 코스의 Load Balancer 챕터 내용을 정리한 글입니다.
What is local load balancing?
로컬 LB 는 데이터센터 내에 존재하고 리버스 프록시같이 동작하며 들어오는 요청들을 가용서버들에게 분산시킨다. 들어오는 요청들은 가상 IP 주소 (VIP, Virtual IP) 를 사용하는 LB 에 원활하게 연결된다.
Algorithms of load balancers
로컬 로드밸런서에 사용되는 잘 알려진 알고리즘들은 아래와 같은 것들이 있다. 이 외에도 randomized 나 weighted least connection 알고리즘 등이 있다.
- Round-robin scheduling
- 각 요청은 반복되는 순차적 방식으로 풀에 있는 서버들에 전달된다
- Weighted round-robin
- 만약 어떤 서버들이 더 높은 요청처리 기능을 가진다면 이 알고리즘이 선호된다. 여기에서는 각 서버들이 weight 를 부여받게 되고, LB 는 각 서버들의 weight 에 따라 요청을 전달한다. weight 가 높을수록 전달받는 요청 수도 많아진다.
- Least connections
- 모든 서버가 같은 용량을 갖더라도 특정 서버들에 불균등한 부하를 줄 수도 있다. 예를들어 어떤 클라이언트는 더 오래 서비스해야하는 요청을 보낼 수도 있고 어떤 클라이언트는 동일한 연결에 이어지는 요청들을 보낼 수도 있다. 이런 경우 least connection 과 같은 알고리즘을 사용해 새로 도착하는 요청들을 가장 적은 커넥션을 갖는 서버에 전달할 수 있다. 이 경우 LB는 현재 연결 수와 매핑의 상태를 유지하고 있다.
- Least response time
- 성능에 민감한 서비스의 경우 least response time 과 같은 알고리즘을 사용할 필요가 있다. 이 경우 가장 작은 응답시간을 갖는 서버가 클라이언트 요청을 서빙하게 된다.
- IP hash
- 어떤 앱은 사용자의 IP 주소에 따라 사용자에게 다른 수준의 서비스를 제공할 수도 있다. 이 경우 사용자 요청을 특정 서버로 할당하기 위해 IP 주소 해시를 사용한다.
- URL hash
- 어떤 앱의 특정 서비스는 특정 서버들만 제공하는 경우가 있을 수도 있다. 이런 경우 URL 을 이용한 요청은 특정 클러스터 또는 서버군에게 할당된다. 이런 경우 URL 해시 알고리즘이 사용된다.
Static vs dynamic algorithms
알고리즘은 머신 상태에 따라 정적 또는 동적일 수 있다.
- Static algorithms
- 서버의 변경되는 상태를 고려하지 않는다. 따라서 이미 알고있는 서버의 설정들에 기반해서 작업이 할당된다. 당연히 알고리즘이 간단하며 단일 라우터 또는 모든 요청이 도착하는 범용 기기에 구현되어 있다.
- Dynamic algorithms
- 서버의 현재 또는 최근의 상태를 고려한다. 이러한 상태는 서버들과의 통신을 통해 유지하며 당연히 통신 오버해드가 발생한다. 상태 유지는 알고리즘 디자인을 더 복잡하게 한다.
다이나믹 알고리즘은 서로 정보 교환을 위한 통신을 해야 하기 때문에 다른 로드밸런싱 서버들이 필요하다. 그러므로 다이나믹 알고리즘은 modular 일 수 있어야 하는데, 단일 엔티티만으로는 의사결정이 불가능하기 때문이다. 이는 다이나믹 알고리즘을 더 복잡하게 만들지만 부하 분산을 더 개선시킬 수 있다. 또한 다이나믹 알고리즘은 서버들의 상태를 모니터링하여 가용 서버로만 요청을 전달한다.
Note: 실제로 서버의 상태를 유지하기 때문에 다이나믹 알고리즘이 더 좋은 결과를 보이므로 복잡성과 추가 비용을 감수할만 하다.
Stateful vs stateless LBs
정적 동적 알고리즘이 서버의 상태를 고려하기 위해 필요하다면, 서로 다른 클라이언트와 서버의 세션 정보를 들고 있기 위해 상태를 사용한다.
만약 세션정보가 더 저수준 레이어 (분산캐시 혹은 DB) 에서 유지되지 않는다면, 세션 정보를 유지하기 위해 로드밸런서가 사용된다. LB 를 통해 세션관리를 수행하는 방법으로 stateful, stateless 두가지가 있다.
Stateful load balancing
stateful 로드밸런싱은 클라이언트와 서버간에 연결된 세션의 상태를 유지하는 작업을 포함한다. stateful LB 는 상태 정보를 알고리즘에 활용하여 로드밸런싱을 수행한다.
stateful LB 는 클라이언트와 서버를 매핑하는 데이터 구조를 가진다. 또한 모든 클라이언트의 세션 정보가 모든 LB 에 저장되기 때문에 복잡도도 커지며 확장성도 제한된다. 이는 LB 가 요청 전달 결정을 하기 위해 서로 상태정보를 공유해야 함을 뜻한다.
Stateless load balancing
무상태 로드밸런싱은 상태를 관리하지 않으므로 더 빠르고 가볍다. stateless LB 는 consistent hahsing 을 사용하여 요청을 어떻게 전달할지 결정한다. 하지만 서버가 추가된다든지 하는 인프라변경이 발생하면 무상태 LB 는 stateful LB 보다 탄력적 (resilient) 이지 않을 수 있는데, consistent hashing 만으로는 올바른 앱서버로 요청을 전달하기에 충분하지 않기 때문이다. 따라서 consistent hasing 을 사용하면서도 로컬 상태를 유지하는게 필요할 수도 있다.
서로 다른 로드밸런서들간에 상태를 유지하는 것은 stateful 로드밸런싱으로 간주할 수 있고, 특정 로드밸런서 내부적으로만 상태가 유지되는 것은 stateless 로드밸런싱이라 할 수 있다.
Types of load balancers
요구사항에 따라 로드밸런싱은 네트워크/전송 그리고 애플리케이션 레이어에서 수행될 수 있다.
- Layer 4 LB
- 레이어 4는 TCP 또는 UDP 같은 전송 프로토콜 기반으로 수행되는 로드밸런싱을 말한다. 이러한 유형의 LB 는 동일한 클라이언트로 온 요청이 동일한 백엔드서버로 전달될 수 있도록 연결 및 세션 정보를 유지한다. TLS 종료는 레이어 7에서 수행되지만, 몇몇 레이어 4 LB 도 이를 지원한다.
- Layer 7 LB
- 레이어 7 LB 는 앱 레이어 프로토콜의 데이터를 기반으로 한다. 이는 HTTP 헤더, URL, 쿠키 그리고 다른 앱별 데이터 (예를들어 사용자 ID) 등을 기반으로 앱을 인식하여 요청을 전달할 수 있도록 한다. TLS 종료를 수행하는 것 외에도 이러한 LB는 사용자의 요청량 제한, HTTP 라우팅 및 헤더 재작성과 같은 작업을 수행해야 하기도 한다.
Note: 레이어 7 LB 는 검사 측면에서 더 똑똑하고, 레이어 4 LB 는 처리 측면에서 더 빠르다.
Load balancer 배포
서로 다른 계층에서의 LB 에 대해 알아봤는데, 실제로는 단일 계층 LB 만으로는 대규모 데이터센터에 충분하지 않다. 실제로 여러 계층의 LB 가 협력하여 정보를 기반으로한 요청 전달 결정을 내린다. 전통적인 데이터센터는 아래와 같은 3계층 LB가 있을 수 있다.
Tier-0 and tier-1 LB
만약 DNS 를 티어 0 LB 로 간주할 수 있다면 등가비용 다중경로 (ECMP, equal cost multipath) 라우터가 1티어 LB일 것이다. ECMP 는 이 레이어에 도착하는 요청을 IP 또는 라운드로빈이나 가중치 라운드로빈과 같은 알고리즘을 기반으로 분산시킨다. 1티어 LB 는 서로 다른 경로로 들어오는 부하를 더 높은 티어의 LB 들로 로드밸런싱한다.
ECMP 라우터는 상위 티어 LB 들의 수평확장성에 매우 중요한 역할을 한다.
Tier-2 LB
두번째 티어의 LB는 레이어4 LB 를 포함한다. 2티어 LB 는 어느 연결에서도 모든 패킷들이 같은 3티어 LB 로 전달되도록 한다. 이를 위해서 consistent hashing 과 같은 기술이 사용될 수 있다. 그러나 인프라에 변경이 있을 경우 이로는 부족할 수 있어서 로컬 또는 글로벌 상태 유지가 필요할 수 있다.
2티어 LB 는 1티어와 3티어 사이의 접착제로 볼 수 있으며 2티어 LB 를 제외하면 장애 발생이나 LB의 동적 스케일링이 있는 경우 잘못된 전달결정이 발생할 수 있다.
Tier-3 LB
레이어7 LB 는 3티어에서 제공된다. 이런 LB는 백엔드서버와 직접 연결되므로 HTTP 수준의 서버 상태 모니터링이 수행된다. 이 티어는 백엔드 서버들로 요청을 균등하게 분산시켜 시스템에 확장성을 준다. 또한 서버들의 상태를 직접 모니터링해서 고가용성을 제공하기도 한다. 그리고 TCP 정체 제어 프로토콜, 최대 전송 유닛 검색 등의 낮은 수준의 디테일을 처리하여 최종 서버의 부담을 줄여준다. 가끔 레이어7LB 는 서비스 호스트와 같은 레벨에 있다.
요약하면, 1티어 LB 는 로드밸런서 사이의 로드를 균등하게 분배하고, 2티어는 장애시 1티어에서 3티어로 전달되는 로드가 원활하게 전환될 수 있도록 한다. 3티어의 경우 실제 백엔드 서버간의 로드를 분산시키는 역할을 하며, 각 티어는 최종 서버의 부하를 줄이기 위한 동작들을 수행한다.
Practical example
클라이언트로부터 요청이 들어와서 다른 앱서버로 전달되는 예제를 살펴보자.
첫번째 그림은 다음과 같은 순서로 진행된다.
- R1 은 첫번째 요청을 나타내며 ECMP 라우터 (티어1 LB) 중 하나를 통해 들어온다.
- ECMP 라우터는 라운드로빈 알고리즘을 이용해 3개의 가용한 2티어 LB 중 하나로 R1 을 전달한다. 2티어 LB 는 소스 IP 주소의 해시값을 들고있으며 (IPc) 다음 티어 LB 로 패킷을 전달한다.
- 3티어 LB 는 패킷을 받아서 TLS 를 제거하고 HTTP(S) 데이터를 읽는다. 요청된 URL 을 확인해서 slides 요청을 처리하는 서버로 요청을 전달한다.
두번째 그림의 R2는 소스 IP 가 같으므로 동일한 3티어 LB 를 경유하지만 요청된 URL 경로가 slide 대신 document 이므로 다른 최종 서버에서 처리된다. 3티어 LB 는 앱서버로 요청을 전달할 때 앱 데이터에 기반해서 전달할 수 있도록 미리 설정할 수 잇다. 예를들어, 전형적인 HAProxy 서버는 3티어 LB 에서 다음과 같은 설정을 사용할 수 있다.
mode HTTP //define which mode the LB will work on, TCP for tier-2 LBs
acl slidesApp path_end -i /presentation //define a category of applications if the path ends in /presentation
use_backend slidesServers if slidesApp // use a set of backend servers if the request arrives for slidesApp
backend slidesServers // listing servers serving slidesApp
server slides1 192.168.12.1:80 //using slides1 server to serve slidesApp.
Question
1: 백엔드서버로 요청이 도착하면 응답은 각 티어의 로드밸런서를 다시 경유하여 돌아가야할까?
→ 아니다. 서버는 응답을 3티어 LB 를 통해 바로 라우터 (1티어 LB) 로 전송할 수 있다. 이러한 응답을 direct routing (DR) 또는 direct server return (DSR) 이라고 한다.
2: 서버는 왜 3티어 LB 대신 1티어 LB 로 바로 응답을 보내지 않는걸까?
→ 3티어가 연결의 상태, 예를들어 SSL 암복호화 등을 유지하기 때문이다. 이는 클라이언트에게 매끄러운 경험을 주기 위해 필요하다.
3: 어떤 티어의 LB 가 버그에 취약할까?
→ 3티어가 더 복잡하므로 버그에 더 취약할것이다.
4: 위 예제에서 3티어 LB 가 2티어 LB 보다 수가 많은데 왜일까?
→ 3티어는 앱에 한정된 분석과 대체로 더 정교한 연산을 수행한다. 따라서 같은 수의 쿼리를 처리하려면 더 많은 머신이 필요하다. 또한 3티어 LB 는 앱서버에 관련된 많은 종류의 상태를 유지하고 있고, 때문에 2티어보다 리소스를 더 많이 필요로 할 수 있다.
Implementation of load balancers
요청수, organization, 앱에 한정된 요구사항 등에 따라 서로 다른 종류의 로드밸런서 구현체들이 있다.
Hardware load balancers
LB 는 1990년대에 하드웨어 장비로 고안되었다. 하드웨어 LB 는 stand-alone 장비였으며 꽤 비쌌다. 그럼에도 성능 이점이 있었으며 많은 유저를 동시에 처리할 수 있었다. 하드웨어 기반 LB 의 설정은 공수가 들어서 어려웠다. 그래서 이를 감당 가능한 큰 기업에게조차도 편리한 솔루션이 아니었다. 장애 발생시 추가 장비가 더 필요했기 때문에 가용성에도 문제가 있었다. 또한 하드웨어 LB 는 높은 유지보수, 운영 비용 및 호환성 이슈에다가 vendor lock 문제도 생길 수 있다.
Software load balancers
소프트웨어 LB 는 유연성과 프로그램 가능함, 그리고 비용 효율성 때문에 갈수록 널리 쓰이고있다. 상용 하드웨어에 구현되었기 때문이다. 소프트웨어 LB 는 요구사항이 증가할수록 잘 확장될 수 있으며, 상용 하드웨어에 섀도우 LB 를 구현하는데 작은 비용이 들기 때문에 가용성도 문제가 되지 않는다. 또한 향후 트래픽 패턴을 대비하기 위한 예측 분석도 할 수 있다.
Cloud load balancers
클라우드 컴퓨팅이 도입되면서 LBaaS (Load Balancers as a Service) 가 도입되었다. 클라우드 소유자들이 로드밸런싱 서비스를 제공하는 것이다. 사용자는 사용량 또는 클라우드 제공자의 SLA (service-level agreement) 에 따라 금액을 지불한다. 로컬 온프레미스 LB 설비를 대신해서 클라우드 기반 LB 를 쓸 필요는 없을 수 있지만 클라우드 기반은 서로 다른 지역의 글로벌 트래픽을 처리할 수 있다. 이런 LB 의 주요 장점은 쓰기 쉽고, 사용량 기반으로 비용이 계산되며, 유연하게 사용될 수 있고, 감사나 모니터링 서비스도 포함한다는 것이다. 아래 예시는 클라우드 기반 LB 로 GSLB 를 제공하는 예이다.
로드밸런싱의 다른 흥미로운 구현은 클라이언트 측면의 로드밸런싱이 있다. 클라이언트 측면의 LB 는 트위터의 경우와 같이 여러 서비스가 있고 각 서비스에 많은 인스턴스들이 있는 경우에 적합하다. 그러나 대부분의 3계층 앱은 설계에 이런 기능을 사용하기 때문에 우리는 전통적 LB 에 중점을 두었다.
Conclusion
LB 는 하드웨어의 형태부터 지금의 클라우드에서 제공되는 서비스가 되기까지 긴 역사를 가졌다. 기업 수준의 서비스에서 LB 는 중요한 역할을 하는 컴포넌트이다. 호스팅서버를 수평 확장 하기 위해서는 좋은 로드밸런싱 레이어가 필요하며, 로드밸런싱, 세션 관리, TLS 오프로딩, 서비스 디스커버리 등의 기능을 제공해야 한다.
'System Design' 카테고리의 다른 글
Databases #2 - Data Replication (0) | 2023.04.16 |
---|---|
Databases #1 - RDB vs NoSQL (1) | 2023.04.16 |
Load Balancer #2 - Global and Local Load Balancing (0) | 2023.03.26 |
Load Balancer #1 - Introduction to Load Balancers (0) | 2023.03.26 |
Domain Name System (1) | 2023.03.19 |