[TIL] 이중화와 부하분산의 기본

<서버/인프라를 지탱하는 기술>을 읽고 내용을 정리해봤다.

Cold Standby와 Hot Standby

  • Cold Standby는 물리장비를 이중화하되, 하나의 장비만 Active하게 사용하며, Active 장비에 장애가 발생했을 때 유휴 장비로 물리적 회선연결을 변경하거나 전원을 투입해 서비스를 제공한다.
  • Cold Standby는 간단하다. 다만 장애시 물리회선 연결이나 장비에 대한 전원을 ON 하기 위한 시간이 소요되어 다운타임이 길어질 수 있다.
  • Cold Standby는 라우터에는 적절할 수도 있지만 항상 최신화되어야 하는 웹 어플리케이션 서버에는 적합하지 않을 수 있다.
  • Hot Standby는 두개 이상의 운용장비가 항상 전원이 켜진 상태이며 네트워크에도 연결된 상태로 존재한다. Active 운용장비가 요청을 전담해 처리하지만, 예비 운용장비는 항상 Active 장비와 갱신내용을 공유하며 최신 상태를 유지한다. 따라서 장애시 다운타임이 짧다.

Failover

물리적인 회선 연결이나 장비의 대치 작업이 없이 자동으로 장애를 극복하는 방법을 Failover라고 한다. 예를들면 VIP(가상 IP)를 활용한 장애극복이 있을 수 있다.

클라이언트가 10.10.0.1로 접속한다고 하자.

사실 웹서버는 총 2대이고 10.10.0.101과 10.10.0.102가 있다. 이 둘은 가상 IP 주소인 10.10.0.1을 공유한다.

만약 10.10.0.101 서버가 정상 동작한다면, 10.10.0.1로 보내진 요청은 10.10.0.101 서버로 라우팅되어 처리된다. 만약 위 서버에 장애가 발생하면 10.10.0.1로 보내진 요청은 10.10.0.102 서버로 라우팅되어 처리된다.

여기서 핵심은 클라이언트가 각 서버 장비의 IP를 기억할 필요 없이 VIP만 기억하면 라우터와 서버들이 알아서 장애에 대응한다는 것이다.

유념할 점은, 실제 통신에는 IP가 아닌 MAC 주소가 사용되는데, IP를 바탕으로 MAC 주소를 조회하는 ARP 프로토콜을 이용하며, MAC 주소는 ARP 테이블 등에 캐싱될 수 있다는 점이다. 따라서 캐시를 무효화(갱신) 시키는 Gratuitous ARP 요청을 보내야 한다.

Healthcheck

헬스체크는 장애검출을 하기 위한 방법이다.

  • ICMP 감시(Layer 3)는 ICMP의 echo 요청을 보내 응답여부를 확인한다. 간단하지만 웹서비스의 다운여부는 확인할 수 없다.
  • 포트 감시(Layer 4)는 TCP 접속을 시험한다. 웹서비스(아파치나 Nginx)의 다운 여부는 검출할 수 있지만 서버 과부하로 응답을 하지 못하거나 서버가 에러를 반환하는 것을 감지할 수 없다.
  • 서비스 감시(Layer 7)는 HTTP 요청을 보내 정상 응답이 오는지를 확인하는 방법이다. 대부분의 이상을 감지할 수 있지만 경우에 따라서는 잦은 healthcheck 요청이 서버에 부하를 줄 수 있다.

참고로, 라우터도 헬스체크를 할 수 있다. 이 경우 ICMP 감시를 하는데, 라우터에 대해 감시하는 것이 아니라, 라우터 뒷단의 서버에 대해 ICMP 감시를 한다. 만약 서버가 echo 요청에 정상적으로 응답한다면 라우터가 정상적으로 패킷을 서버로 전달하고 있음을 확인할 수 있기 때문이다.

웹 서버의 이중화

  • DNS 라운드로빈은 DNS 서버가 각 물리서버의 IP 주소를 가지고 있는 상태에서 클라이언트에 따라 다른 IP 주소를 반환하는 형태로 된 이중화 구성 방법이다.
  • DNS 라운드로빈을 사용하기 위해서는 각 물리장비가 별도의 Public IP주소를 가지고 있어야 한다.
  • DNS 질의 결과를 클라이언트쪽 기기나 네트워크 기기들이 캐싱하고 있다. 따라서 일부 장비에 요청이 몰릴 수도 있다.
  • 로드밸런서는 글로벌 주소를 가진 가상 서버처럼 동작하는 장비다. 클라이언트는 로드밸런서의 주소를 웹서버의 주소라고 생각하고 요청을 보낸다. 로드밸런서는 이렇게 들어온 요청을 적절히 서버들로 분산해 인계한다. 이 과정에서 반드시 헬스체크가 성공한 서버만 요청을 나눠준다.
  • 로드밸런서의 종류로는 L4 스위치와 L7 스위치가 있다. L4 스위치가 성능이 더 좋고, IP 주소나 포트번호에 따라 분산대상 서버를 지정할 수 있다. 가장 일반적이다.
  • 로드밸런서의 경우 부하를 분산하는 스케줄링 알고리즘을 선택해야 한다. 가장 단순한 구성은 라운드 로빈이며 모든 서버가 균등하게 요청을 받지만, 각 서버의 성능이나 각 요청의 처리시간이 균등하지 않은 경우가 많은 현실에는 별로 맞지 않는 방법이다.
  • 이외에 weighted round-robin 방식이 있고 각 장비별로 가중치를 줄 수 있다.
  • 가장 일반적인 방법은 least-connection 알고리즘이다. 로드밸런서는 가장 적은 접속수를 가지는 서버에 요청을 인계한다.
  • weighted least-connection 알고리즘도 있다. 고성능 서버에 추가적인 가중치를 줄 수 있다.

L4 스위치의 구성

  • NAT(Network Address Translation) 구성은 스위치가 클라이언트와 서버 사이에서 요청의 발신지와 수신지의 주소를 “번역”해주는 구성이다. 클라이언트는 서버의 주소가 아닌 로드밸런서의 주소로 요청을 한다. 로드밸런서는 이 요청의 수신자 주소를 자기 자신에서 서버의 주소로 바꿔 서버로 인계한다. 서버는 인계받은 요청을 처리하고, 요청에 적힌 클라이언트의 주소로 응답 메시지를 발신한다. 로드밸런서는 이 응답을 가로채 마치 자신이 응답하는 것처럼 응답자의 주소를 자신의 주소로 바꾼다.
  • DSR(Direct Server Return) 구성은 요청의 주소를 변경하지 않고 로드밸런서가 서버로 바로 요청을 인계한다. 서버는 요청을 처리해 응답메시지를 만들고 로드밸런서를 경유하지 않고 바로 클라이언트에 응답을 발송한다. 이를 위해 서버가 글로벌 주소를 처리할 수 있어야 한다. 로드밸런서의 부하를 줄일 수 있는 방법이고, 동일 서브넷 하의 서버를 부하분산할 수 있다.

라우터 및 로드밸런서의 다중화

  • 쉽게는 Cold Standby 방식으로 로드밸런서를 하나 더 준비하는 방법이 있다. 이는 사람이 수동으로 연결을 변경해줘야 하므로 효과적인 방법은 아니다.
  • VRRP(Virtual Router Redundancy Protocol)을 이용하면 로드밸런서를 이중화할 수 있다. VRRP 프로토콜 아래에서는 마스터 노드와 백업노드가 존재하는데, 마스터 노드는 스스로가 살아있음을 멀티캐스팅 주소로 지속적으로 발신한다. “advertisement”라고도 한다. 백업노드들은 VRRP 패킷을 수신하는 동안은 대기상태로 있다가 VRRP 패킷이 끊기면 능동적으로 마스터노드로 스스로를 변경한다.
  • VRRP에는 우선순위와 선점형 모드가 존재한다. 즉, 기본적으로 각 노드는 서로 다른 우선순위를 가지고 있는데, 마스터 노드에 장애가 발생하면 다른 백업노드들이 스스로 VRRP 패킷을 발신하기 시작한다. 다만, 이 방법으로 다른 노드들의 VRRP 패킷을 수신했는데 자신보다 우선순위가 높으면 더 이상의 VRRP 패킷 발신을 멈춘다. 따라서 항상 더 높은 우선순위의 노드가 마스터 노드가 된다.
  • 기본모드인 선점형 모드에서는 마스터노드에 장애가 발생해 백업노드가 마스터 노드가 되더라도, 장애가 발생했던 노드가 복구되면 더 높은 우선순위로 인해 바로 마스터노드의 지위를 차지하게 된다. 만약 마스터 노드의 상태가 빈번하게 악화되고 재기동을 반복하는 상황이라면 선점형 모드를 무효화 하는 방법을 고민해 볼 수도 있다.
  • VRRP는 가상 MAC 주소가 정의되어 있다. 이는 이더넷 특성에 기인하는데, 앞서 살펴봤듯 실제 통신에서는 IP로 MAC 주소를 조회해 통신이 이뤄진다. 이 MAC 주소는 각 장비들에 캐싱될 수 있는데, 이를 모두 무효화시키는 것은 이더넷의 특성상 100% 가능하진 않다. ARP 통신이 정상적으로 도달하리란 보장은 없기 때문이다. 따라서 MAC 주소를 변경하도록 ARP 요청을 보내는 대신, VRRP 내부의 MAC 주소를 다른 노드에 인계함으로서 이 문제를 해결한다. 즉, 캐싱되어 있는 MAC 주소를 바꿀 필요가 없이 마스터 노드를 변경할 수 있고, 정상적으로 이전과 같은 MAC 주소로 통신을 이어갈 수 있다.