부하 분산

완료됨

트래픽이 증가할 때 새 VM을 온라인으로 가져와서 규모를 확장하는 것이 요구 사항을 충족하도록 크기를 조정하는 효과적인 전략입니다. 탄력성을 달성하려면 VM을 빠르게 프로비저닝할 수 있어야 합니다. 그러나 서버 간에 트래픽을 분산하지 않는 한 추가 서버를 온라인으로 가져오는 것은 “유용”하지 않습니다. 전반적으로는 시스템이 증가하는 부하를 처리하는 데 도움이 됩니다. 따라서 부하 분산은 작업에 할당된 리소스의 수를 동적으로 조정하는 것이 중요합니다.

부하 분산의 필요성은 두 가지 기본 요구 사항에서 비롯됩니다. 첫째, 처리량은 병렬 처리에 의해 향상됩니다. 단일 서버가 시간 단위당 5,000개의 요청을 처리할 수 있는 경우 10개의 완벽한 부하 분산 서버는 시간 단위당 50,000개의 요청을 처리할 수 있습니다. 두 번째, 부하가 분산된 리소스는 더 높은 가용성을 제공합니다. 부하 분산 장치는 유지하기 위해 이미 작동 중인 서버로 요청을 전달하는 대신, 부하가 적은 서버로 요청을 보낼 수 있습니다. 또한 서버가 오프라인 상태로 전환되고 부하 분산 장치에서 이를 인식하는 경우 요청을 다른 서버로 보낼 수 있습니다.

부하 분산이란?

잘 알려진 형태의 부하 분산은 라운드 로빈 DNS로, 많은 대용량 서버에서 여러 웹 서버 간에 요청을 분산하는 데 사용하고 있습니다. 특히 고유한 IP 주소를 가진 여러 프런트 엔드 서버는 DNS 이름을 공유합니다. 각 웹 서버의 요청 수를 분산하기 위해 Google 등의 대기업은 각 DNS 항목에 대한 IP 주소 풀을 유지 관리하고 조정합니다. 클라이언트가 요청을 수행할 때(예: www.google.com) Google의 DNS는 풀에서 사용 가능한 주소 중 하나를 선택하여 클라이언트로 보냅니다. IP 주소를 디스패치하는 가장 간단한 전략은 라운드 로빈 큐를 사용하는 것입니다. 여기서 각 DNS 응답 후에는 주소 목록이 요소가 순열로 배치됩니다.

클라우드가 등장하기 전에 DNS 부하 분산은 장거리 연결의 대기 시간을 줄이는 간단한 방법이었습니다. DNS 서버의 디스패처가 클라이언트와 지리적으로 가까운 서버의 IP 주소를 사용하여 응답하도록 프로그래밍되었습니다. 이 작업을 수행하는 가장 쉬운 방법은 클라이언트의 IP 주소와 수치상 가장 가까운 위치에 있는 풀의 IP 주소를 사용하여 응답하는 것입니다. IP 주소가 전역 계층에 배포되지 않기 때문에 이 메서드는 안정적이지 않았습니다. 현재 기술은 더 정교하며, ISP(인터넷 서비스 공급자)의 실제 맵을 기반으로 하는 위치에 IP 주소를 매핑하는 소프트웨어를 사용합니다. 이 매핑은 비용이 많이 드는 소프트웨어 조회로 구현되므로 이 메서드는 더 나은 결과를 얻을 수 있지만 컴퓨팅에 많은 비용이 듭니다. 그러나 DNS 조회는 클라이언트가 서버에 처음 연결한 경우에만 발생하기 때문에 느린 조회 비용이 상환됩니다. 모든 후속 통신은 디스패치된 IP 주소를 소유하는 서버와 클라이언트 간에 직접 발생합니다. DNS 부하 분산 체계의 예는 그림 9에 나와 있습니다.

그림 9: 클라우드 환경의 부하 분산.

그림 9: 클라우드 환경의 부하 분산입니다.

이 메서드의 단점은 서버 오류가 발생한다는 점이며 다른 IP 주소로의 전환은 DNS 캐시의 TTL(Time-to-live) 구성에 따라 달라집니다. DNS 항목은 오래 사용되는 것으로 알려져 있으며 업데이트가 전파되는 데 1주일 이상이 소요됩니다. 즉, 클라이언트에서 서버 오류를 신속하게 "숨기는" 것이 어렵습니다. 캐시에서 IP 주소의 유효성(TTL)을 줄이면 성능이 저하되고 조회 수가 증가하여 이를 개선합니다.

최신 부하 분산은 종종 전용 인스턴스(또는 인스턴스 쌍)를 사용하여 백 엔드 서버에 들어오는 요청을 디스패치하는 것을 의미합니다. 지정된 포트에서 들어오는 각 요청에 대해 부하 분산 장치는 배포 전략에 따라 백 엔드 서버 중 하나로 트래픽을 리디렉션합니다. 그러면 부하 분산 장치가 애플리케이션 프로토콜 헤더(예: HTTP 헤더)와 같은 정보를 포함하여 요청 메타데이터를 유지 관리합니다. 이 경우 모든 요청이 부하 분산 장치를 통과하므로 오래된 정보는 문제가 되지 않습니다.

모든 유형의 네트워크 부하 분산 장치는 백 엔드 서버에 대한 컨텍스트와 함께 요청을 전달하고 클라이언트에 응답을 다시 제공하는 경우 두 가지 기본 전략1 중 하나를 사용할 수 있습니다.

  • 프록시 - 이 방식은 부하 분산 장치가 백 엔드에서 응답을 수신하고 클라이언트에 다시 릴레이합니다. 부하 분산 장치는 표준 웹 프록시로 작동하며 네트워크 트랜잭션의 절반과 관련되어 있습니다. 즉, 요청을 클라이언트에 전달하고 응답을 다시 보냅니다.

  • TCP 전달 - 이 방식에서 클라이언트와의 TCP 연결은 백 엔드 서버에 전달되며 서버는 부하 분산 장치를 통하지 않고 클라이언트에 직접 응답을 보냅니다.

해당 전략의 후자는 그림 10에 나와 있습니다.

그림 10: 디스페처에서 백 엔드 서버로의 TCP 전달 메커니즘.

그림 10: 디스페처에서 백 엔드 서버로의 TCP 전달 메커니즘입니다.

부하 분산의 이점

부하 분산의 이점 중 하나는 시스템에서 오류를 숨길 수 있다는 것입니다. 클라이언트가 여러 리소스를 나타내는 단일 엔드포인트에 표시되는 한, 개별 리소스의 오류는 다른 리소스를 사용해 요청을 처리하여 클라이언트에서 숨겨집니다. 다만 그러면 부하 분산 장치 자체가 단일 실패 지점이 됩니다. 모든 백 엔드 서버가 계속해서 작동하더라도 어떤 이유로든 실패하면 클라이언트 요청이 처리되지 않습니다. 따라서 부하 분산 장치는 고가용성을 얻기 위해 종종 쌍으로 구현됩니다.

더 중요한 점은 부하 분산이 클라우드의 여러 컴퓨팅 리소스에 워크로드를 분산하여 응답성을 향상하는 것입니다. 클라우드에 단일 컴퓨팅 인스턴스가 있는 경우 몇 가지 제한 사항이 있습니다. 이전 모듈에서는 워크로드를 늘리기 위해 더 많은 리소스가 필요한 성능의 물리적 제한 사항에 대해 알아보았습니다. 부하 분산을 사용하면 더 많은 워크로드가 여러 리소스에 분산되므로 각 리소스가 독립적으로 동시에 요청을 충족하여 애플리케이션의 처리량을 향상시킬 수 있습니다. 또한 부하 분산은 워크로드를 처리할 서버가 더 많으므로 부하 분산은 평균 응답 시간을 향상합니다.

상태 검사는 성공적인 부하 분산 전략을 구현하기 위한 핵심입니다. 부하 분산 장치는 리소스를 사용할 수 없게 되면 해당 리소스로 트래픽이 전달되지 않도록 알림을 받아야 합니다. 부하 분산 장치가 ICMP(Internet Control Message Protocol) 요청을 사용하여 서버를 "ping"하는 Ping 에코 모니터링은 특정 리소스의 상태를 확인하는 데 가장 많이 사용되는 방법 중 하나입니다. 트래픽을 전달 시 리소스 상태를 고려하는 것 외에도 일부 부하 분산 전략은 처리량, 대기 시간 및 CPU 사용률과 같은 다른 메트릭을 고려합니다.

부하 분산 장치는 고가용성을 보장해야 하는 경우가 많습니다. 이 작업을 수행하는 가장 간단한 방법은 각각 고유한 IP 주소를 사용하여 여러 부하 분산 인스턴스를 만들고 단일 DNS 주소에 연결하는 것입니다. 어떤 이유로든 부하 분산 장치가 실패할 때마다 새로운 장치로 바뀌고 모든 트래픽이 장애 조치(failover) 인스턴스에 최소한의 성능 영향으로 전달됩니다. 동시에 새 부하 분산 장치 인스턴스를 구성하여 실패한 항목을 바꾸고 DNS 레코드를 즉시 업데이트해야 합니다.

백 엔드 서버 간에 요청을 분산하는 것 외에도 부하 분산 장치는 서버의 부하를 줄이고 전체 처리량을 향상하기 위해 메커니즘을 사용합니다. 관련 메커니즘 중 일부는 다음과 같습니다.

  • SSL 오프로드 - HTTPS 연결은 트래픽이 암호화되므로 성능 비용이 추가로 발생합니다. SSL(Secure Sockets Layer)을 통해 모든 요청을 처리하지 않고도 SSL을 통해 부하 분산 장치에 대한 클라이언트 연결을 설정할 수 있지만, 각 서버에 대한 리디렉션 요청은 암호화되지 않은 HTTP를 통해 수행됩니다. 이 기법은 서버 부하를 상당히 줄입니다. 또한 공개 네트워크를 통해 리디렉션 요청이 수행되지 않는 한 보안이 유지됩니다.

  • TCP 버퍼링 - 부하 분산 장치에 대한 저속 연결로 클라이언트를 오프로드하여 해당 클라이언트에 대한 응답을 제공하는 서버를 완화하는 전략입니다.

  • 캐싱 - 특정 시나리오에서 부하 분산 장치는 가장 인기 있는 요청(또는 정적 콘텐츠와 같이 서버로 이동하지 않고도 처리할 수 있는 요청)에 대한 캐시를 유지하여 서버의 부하를 줄일 수 있습니다.

  • 트래픽 셰이핑 - 부하 분산 장치는 이 기법을 사용하여 패킷 흐름을 지연하거나 우선 순위를 다시 지정하여 서버 구성에 맞게 트래픽을 최적화할 수 있습니다. 이는 일부 요청에 대한 QoS에 영향을 주지만 들어오는 부하를 처리할 수 있도록 합니다.

부하 분산 장치가 대처할 수 있는 부하가 아닌 경우에만 부하 분산을 기억해야 합니다. 그렇지 않으면 부하 분산 장치가 병목 상태가 됩니다. 다행히 부하 분산 장치는 받는 요청에 대한 처리를 거의 수행하지 않으며, 대신 백 엔드 서버에 활용하여 요청을 응답으로 전환하는 실제 작업을 수행합니다.

균등 디스패치

클라우드에서 사용되는 부하 분산 전략은 여러 가지가 있습니다. 가장 일반적인 방법 중 하나는 간단한 라운드 로빈 알고리즘을 사용하여 모든 노드 간에 트래픽을 균등하게 분산하는 ‘균등 디스패치’입니다. 시스템에서 개별 리소스의 사용률을 고려하지 않으며 요청 실행 시간에도 해당하지 않습니다. 시스템의 모든 노드를 사용 중인 상태로 유지하려고 하며 구현하는 것이 가장 간단한 방법 중 하나입니다.

AWS는 ELB(탄력적 부하 분산 장치) 제품에서 이 방법을 사용합니다. ELB는 연결된 EC2 인스턴스 간에 트래픽을 분산하는 부하 분산 장치를 프로비저닝합니다. 부하 분산 장치는 기본적으로 트래픽을 구체적으로 라우팅하는 서비스가 있는 EC2 인스턴스입니다. 부하 분산 장치 뒤에 있는 리소스가 확장되면 부하 분산 장치의 DNS 레코드에서 새 리소스의 IP 주소가 업데이트됩니다. 모니터링 및 프로비저닝 시간이 모두 필요하기 때문에 프로세스를 완료하는 데 몇 분 정도 걸릴 수 있습니다. 이 크기 조정 기간(부하 분산 장치가 더 높은 부하를 처리할 준비가 될 때까지의 대기 시간)은 부하 분산 장치가 "준비 중"인 상태를 의미합니다.

또한 AWS 부하 분산 장치는 상태 검사를 유지하기 위해 워크로드 배포에 대해 연결된 리소스를 모니터링합니다. Ping 에코 메커니즘을 사용하여 모든 리소스가 정상적인 상태인지 확인합니다. ELB 사용자는 지연 및 재시도 횟수를 지정하여 상태 검사의 매개 변수를 구성할 수 있습니다.

해시 기반 배포

이 방법은 각 요청을 정의하는 메타데이터를 해시하고 해시를 사용하여 서버를 선택함으로써 세션 기간 동안 동일한 클라이언트의 요청이 매번 동일한 서버로 전달되도록 합니다. 해시가 제대로 수행되면 요청이 서버 간에 상대적으로 균등하게 분산됩니다. 이 방법의 한 가지 장점은 세션을 인식하는 애플리케이션에 적합하다는 것입니다. 이 애플리케이션은 데이터베이스 또는 Redis Cache와 같은 공유 데이터 저장소에 데이터를 기록하는 대신 메모리에 세션 데이터를 저장할 수 있습니다. 단점은 모든 요청을 해시해야 하기 때문에 약간의 대기 시간이 발생한다는 것입니다.

Azure Load Balancer는 해시 기반 메커니즘을 사용하여 부하를 분산합니다. 이 메커니즘은 원본 IP, 원본 포트, 대상 IP, 대상 포트 및 프로토콜 유형을 기반으로 하는 모든 요청에 대한 해시를 만들어 일반적인 상황에서 동일한 세션의 모든 패킷이 동일한 백 엔드 서버에 도달하도록 합니다. 해시 함수가 선택되므로 서버에 대한 연결 분포가 임의적입니다.

기타 부하 분산 전략

특정 서버가 요청(또는 일련의 요청) 처리를 중단하는 경우에도 라운드 로빈 또는 해시 기반 디스패치 알고리즘을 사용하는 부하 분산 장치는 요청을 서버로 전달합니다. 용량을 고려한 여러 리소스의 부하 분산을 위해 더욱 정교한 전략이 더 있습니다. 용량 측정에 가장 일반적으로 사용되는 두 가지 메트릭은 다음과 같습니다.

  • 요청 실행 시간 - 이 메트릭에 기반한 전략은 우선 순위 예약 알고리즘을 사용하므로 요청 실행 시간이 개별 요청의 대상을 선택하는 데 사용됩니다. 이 방법을 사용할 때의 가장 큰 과제는 실행 시간을 정확하게 측정하는 것입니다. 부하 분산 장치는 각 서버에 요청을 전달하는 시간과 반환되는 시간 사이의 차이를 저장하는 메모리 내 테이블을 사용(및 계속해서 업데이트)하여 실행 시간을 추측할 수 있습니다.

  • 리소스 사용률 - 이 메트릭을 기반으로 하는 전략은 CPU 사용률을 사용하여 노드 간 사용률을 조정합니다. 부하 분산 장치는 해당 사용률에 따라 정렬된 리소스 목록을 유지 관리하고, 각 요청을 가장 적은 부하가 발생하는 리소스로 보냅니다.

부하 분산은 확장 가능한 클라우드 서비스를 구현하는 데 매우 중요합니다. 백 엔드 리소스 간에 트래픽을 분산하는 효과적인 수단이 없는 경우에는 필요 시 리소스를 생성하고, 리소스가 부족하지 않은 경우 프로비저닝을 해제하여 탄력성을 확보할 수 있습니다.

참고 자료

  1. Aron, Mohit and Sanders, Darren and Druschel, Peter and Zwaenepoel, Willy (2000). “Scalable content-aware request distribution in cluster-based network servers.” 2000년 연례 USENIX 기술 컨퍼런스 자료

지식 점검

1.

라운드 로빈 스케줄러가 포함된 부하 분산 장치를 두 웹 서버에 대한 프런트 엔드로 사용하는 시나리오를 고려해 보세요. 한 웹 서버는 2개의 코어와 8GB RAM이 포함된 중간 크기의 인스턴스이고, 다른 하나는 4개의 코어와 16GB RAM이 포함된 대규모 인스턴스입니다. 가능한 시나리오는 무엇일까요?