네트워크

로드 밸런서 1 - 부하 분산, 헬스 체크

우잉~ 2024. 11. 27. 17:22

단일 서버로 애플리케이션을 운영할 경우, 이 서버에 장애가 생기면 서비스를 이용할 수 없게 된다.

이러한 문제를 해결하기 위해서는 여러 대의 서버를 운영하는 것이 바람직하다. → 고가용성(High Avilability, HA)

 

하나의 서비스를 보통 두 대 이상의 서버로 구성할 수 있는데, 각 서버는 서로 다른 IP 주소를 가지고 있다.

사용자가 서비스를 호출할 경우 어떤 서버의 IP로 보낼 것인지 결정해야 한다. 

 

이중 서버 호출 분리

 

그런데 만약에 2대의 서버 중 하나의 서버에 장애가 발생했을 경우는 어떻게 될까?

위 사진에서의 1.1.1.1의 서버에 장애가 발생했다고 가정할 경우, 1.1.1.1을 요청한 사용자는 요청한 서비스가 제대로 작동하지 못할 것이다... 사용자에게 장애가 발생한 서버에 요청을 보내지 않도록 해야한다.

장애 발생하여 요청을 보내도 서비스 불가능

 

사용자에게 원활한 서비스를 제공하기 위해서 해야 할 일을 정리해보자면 아래와 같다.

1. 여러 대의 서버를 프로비저닝한다.

2. 장애가 발생한 서버에 접근할 수 없도록 한다.

 

여러 대의 서버를 프로비저닝하는 것은 문제가 되지 않는다.

하지만 장애가 발생한 서버를 접근하지 못하게 막으려면, 어떤 서버가 장애가 발생했는지 확인하는 작업이 필요한데 이것은 어떻게 할 것인가? 와 같은 의문이 생기게 된다.

 

여태까지 2대의 서버를 예시로 들어 설명하였지만, 서버가 100대가 넘어가게 된다면 장애가 발생한 서버는 어떻게 구분할 것이며, 사용자에게 장애가 발생한 서버로 요청하지 않도록 할 수 있을까?

 

이러한 문제와 의문을 해결해줄 수 있는 장비가 바로 로드 밸런서이다.

L4 또는 L7 스위치라고 부르는 로드 밸런서에는 1. 동일한 서비스를 하는 다수의 서버가 등록되고, 사용자로부터 서비스 요청이 들어오게 되면 로드 밸런서가 받아 2. 이 요청을 여러 대의 서버에 분산하게 된다.

 

 

로드 밸런서는 서비스를 위해 가상 IP(VIP)를 제공하고, 사용자는 이 VIP를 통해 요청을 보낼 수 있다.

이후 로드 밸런서는 요청을 각 서버의 실제 IP로 변경하여 부하를 분산한다.

로드 밸런서는 각 서버가 원활하게 작동하고 있는지 확인하는 헬스 체크 기능이 탑재되어 있다.

만약 서버에 장애가 생겼을 경우, 해당 서버에는 트래픽을 전송하지 않는다.

로드 밸런서를 이용하여 요청을 분산하여 서비스 가용성을 확보한다.

 

* 보통 서버 부하 분산은 SLB(Server Load Balancing), 방화벽 부하 분산은 FWLB(FireWall Load Balancing)이라고 한다.

 

 

 

로드 밸런서의 부하 분산 방법

로드 밸런서 부하 분산 예시 구조

 

VIP에 사용자 서비스 요청이 들어올 때, 어느 서버로 요청을 전달할 것인지 부하 부산 그룹을 설정한다.

위의 예시에서는 부하 분산 그룹이 http 서비스와 https 서비스로 나뉘어져 있다.

부하 부산 그룹을 만들 때는 IP 정보서비스 포트까지 지정해줘야 한다. → 로드 밸런서를 L4 스위치라고 부르는 이유가 바로 이것이다. 

 

VIP는 동일한 VIP를 사용해도 되지만, 서로 다른 VIP로도 구성할 수 있다.

서비스 포트와 실제 서버의 포트도 굳이 같을 필요는 없다. (예: VIP의 서비스 포트: 80/실제 서버의 서비스 포트: 8080)

이렇게 포트가 다를 경우에도 VIP로 서비스 요청이 들어오면, 로드 밸런서가 해당 서비스의 요청을 실제 서버의 서비스 포트로 변경해주기 때문에 걱정하지 않아도 된다.

 

 

 

로드 밸런서가 리얼 서버로 부하를 분산할 때, 사전에 설정한 분산 알고리즘을 통해 부하 분산이 이루어지게 된다.

 

[주요 부하 분산 알고리즘 종류]

부하 분산 알고리즘  
라운드 로빈
(Round Robin)
현재 구성된 장비에 부하를 순차적으로 분산
총 누적 세션 수는 동일하지만, 활성화된 세션 수는 달라질 수 있음
최초 접속 방식
(Least Connection)
현재 구성된 장비 중 가장 활성화된 세션 수가 적은 장비로 부하 분산
가중치 기반 라운드 로빈
(Weighted Round Robin)
라우드 로빈 방식과 동일하지만, 각 장비에 가중치를 두어 가중치가 높은 장비에 부하를 더 많이 분산
처리 용량이 다른 서버에 부하를 분산하기 위한 알고리즘
가중치 기반 최초 접속 방식
(Weighted Least Connection)
최초 접속 방식과 동일하지만, 각 장비에 가중치를 두어 가중치가 높은 장비에 부하를 더 많이 분산
처리 용량이 다른 서버에 부하를 분산하기 위한 알고리즘
해시(Hash) 해시 알고리즘을 이용한 부하 분산

 

부하 분산 알고리즘 1 - 라운드 로빈

특별한 규칙 없이 현재 구성된 장비에 순차적으로 돌아가면서 트래픽을 분산하는 알고리즘

3대의 서버가 있을 경우

첫 번째 요청 - 1번 서버

두 번째 요청 - 2번 서버

세 번째 요청 - 3번 서버

네 번째 요청 - 1번 서버

와 같은 방식으로 진행된다. 모든 장비의 총 누적 세션 수는 같아진다.

 

부하 분산 알고리즘 2 - 최초 접속 방식

서버가 가진 세션 부하를 확인하고, 가장 세션 수가 적은 장비로 서비스 요청을 보내는 알고리즘

서비스별로 세션 수를 관리하면서 분산하게 되므로 각 장비에서 처리되는 세션 수가 비슷하게 분산되면서 부하를 분산하게 된다.

 

부하 분산 알고리즘 3 - 해시

서버 부하를 고려하지 않고, 클라이언트가 같은 서버에 지속적으로 접속하도록 만들기 위해 사용하는 부하 분산 방ㅇ식

해시 알고리즘을 이용해 얻은 결과값으로 어떤 장비로 부하를 분산할 건지 결정한다. → 알고리즘에 의해 계산된 값에 의해서 부하를 분산하기 때문에 같은 알고리즘을 계쏙 사용하면 항상 동일한 결과를 가지고 서비스를 분산할 수 있다.

 

 

로드 밸런서의 헬스 체크

로드 밸런서는 각 서버가 죽었는지 살았는지 확인하는 작업을 거치는데, 이를 헬스 체크(Health check)라고 한다.

만약에 장애가 발생한 서버가 발생했다면, 서비스 그룹에서 제외시켜 트래픽을 보내지 않도록 한다. → 사용자는 정상적으로 서비스를 이용할 수 있음

헬스 체크를 주기적으로 하여 죽었던 서버가 정상화되면 그때 다시 서비스 그룹에 넣어 트래픽을 분산하는 방식으로 진행된다.

 

헬스 체크 방식은 매우 다양하다.

 

헬스 체크 방법 1 - ICMP

VIP에 연결된 리얼 서버에 대해 ICMP ping을 이용하여 헬스 체크를 수행한다.

ICMP 핑은 단순하게 서버가 살았는지 죽었는지만 확인하는 방법으로 잘 사용하진 않는 편이다.

 

헬스 체크 방법 2 - TCP 서비스 포트

로드 밸런서에 설정된 서버의 서비스 포트를 확인하는 방법으로, 가장 기본적인 헬스 체크 방법이다. 

만약 로드 밸런서에서 서버의 서비스 포트를 3000으로 등록했을 경우 로드 밸런서에서는 해당 포트로 SYN을 보내고, 서버로부터 SYN, ACK 응답을 받으면 다시 ACK로 응답하여 FIN을 보내 헬스 체크를 종료한다.

→ 정상적인 3-Way Handshake 과정을 거치게 된다.

TCP 서비스 포트를 통한 헬스 체크 과정

 

헬스 체크 방법 3 - TCP 서비스 포트: Half Open

빠르게 헬스 체크를 진행하여 중간에 세션을 끊어버리는 헬스 체크 방식

헬스 체크로 인한 부하를 줄이기 위해 사용된다.

ACK를 전달 받는 대신, RST를 보내 세션을 끊어버리게 된다.

Half Open 헬스 체크 방식

 

 

헬스 체크 방법 4 - HTTP 상태 코드

3-way handshake 과정을 거치고 나서 HTTP를 요청하고, 정상 상태코드(200 OK)를 응답하는지 여부를 체크하는 방식

HTTP 응답 헬스 체크 방식

 

 

 

헬스 체크 방법 5 - 콘텐츠 확인(문자열 확인)

서버에 콘텐츠를 요청하고 응답받은 내용을 확인하여 지정된 콘텐츠가 정상적으로 응답했는지에 대한 여부를 확인하는 헬스 체크 방식

보통 특정 웹 페이지를 호출하여 사전에 지정한 문자열이 해당 페이지 내에 포함되어 있는지 체크하는 기능이다. → 백엔드의 상태도 체크할 수 있게 됨

※ 문자열만 체크하므로 헬스 체크를 하려고 했던 문자열이 포함되어 있다면 비정상적인 경우에도 헬스 체크를 정상으로 판단할 수 있으므로 문자열 자체를 특정 문자열로 지정하여 상태를 확인해야 함

 

헬스 체크 방법은 위 5가지 말고도 더 다양한 방법이 있으므로 서비스에 적합한 방식을 선택하면 된다.

그 외 F5 LTM을 통한 헬스 체크, Citrix NetScaler를 통한 헬스 체크 등이 존재함

 

 

헬스 체크 주기와 타이머

로드 밸런서는 주기적으로 헬스 체크를 하여 서버가 정상적으로 작동중인지 확인한다고 했다.

헬스 체크 주기를 설정할 때는 헬스 체크 시도 횟수, 응답 시간, 타임 아웃 등의 타이머를 고려해야 한다.

 

[주요 타이머 값]

주기(Interval) 로드 밸런서에서 서버로 헬스 체크 패킷을 보내는 주기
응답 시간(Response) 로드 밸런서에서 서버로 헬스 체크 패킷을 보내고 응답을 기다리는 시간
해당 시간까지 응답이 오지 않으면 실패로 간주한다.
시도 횟수(Retries) 로드 밸런서에서 헬스 체크 실패 시 최대 시도 횟수
최대 시도 횟수 이전에 성공 시 시도 횟수는 초기화된다.
타임아웃(Timeout) 로드 밸런서에서 헬스 체크 실패 시 최대 대기 시간
패킷을 서버로 전송한 후 이 시간 내에 성공하지 못하면 해당 서버는 다운된다.
서비스 다운 시의 주기(Dead Interval) 서비스의 기본적인 헬스 체크 주기가 아닌, 서비스 다운 시의 헬스 체크 주기
서비스가 죽은 상태에서 헬스 체크 주기를 별도로 더 늘릴 때 사용

 

헬스 체크 관련 타이머 값은 장애가 발생했을 때, 장애시간에 영향을 미칠 수 있는 값이기 때문에

각 타이머가 헬스 체크를 할 때의 동작 방식을 정확하게 이해해야 한다.