소프트웨어로드 밸런서를 수평 확장하는 일반적인 방법은 무엇입니까?


22

많은 앱 서버 앞에서 SLB / 리버스 프록시가있는 웹 앱 아키텍처가 종종 있습니다.

단일 SLB가 효과적으로 처리하기 위해 SLB에 대한 연결 수가 너무 많은 리소스를 필요로하면 어떻게됩니까 ? 구체적이지만 최상의 예를 들어, 200 만 개의 영구 HTTP 연결을 고려하십시오. 분명히 단일 SLB가이를 처리 할 수 ​​없습니다.

SLB 확장 위해 권장되는 구성은 무엇입니까 ?

LB 그룹 ​​/ 클러스터를 만드는 것이 일반적입니까? 그렇다면 클라이언트로드가 LB 그룹간에 어떻게 분산됩니까?


z8000, 사용중인 소프트웨어로드 밸런서를 말할 수 있습니까? 또한 가능한 경우로드 균형 조정에 사용하는 알고리즘 / 프로토콜
Martin

나는 선호도가 없다. 질문을 더 명확하게 업데이트했습니다.
z8000

로드 밸런서가 본질적으로 2 백만 개의 영구 HTTP 연결을 처리 할 수없는 이유는 분명하지 않습니다.
womble

답변:


10

본질적으로 연결을 유지하는 어딘가에 체인에 단일로드 밸런서가 있으므로로드 밸런서는 다른로드 밸런서로 쉽게 확장 할 수 없습니다. 즉, LVS 또는 HAProxy와 같은 밸런서는 Gbps 범위에서 용량이 부적절합니다. 단일로드 밸런서 (소프트웨어, 하드웨어 등)의 기능을 넘어 서면 라운드 로빈 DNS와 같은 다른 기술로 이동해야합니다.


권리! 단일 LB를 갖는 것이 "문제"입니다. 처리량이 일반적으로 문제가되지 않을 것이라는 데 동의합니다. 그러나 RAM과 같은 다른 리소스가 걱정됩니다. 제 경우에는 제한적입니다. RAM이 소진되기 전에 단일 SLB에서 호스팅 할 수있는 연결이 너무 많습니다.
z8000

HAProxy는 GB의 RAM 당 약 20k-60k 활성 세션을 처리 할 수 ​​있습니다. 보유 세션 데이터가 더 작기 때문에 LVS가 훨씬 더 많은 것을 할 수 있다고 생각합니다. RAM이 부족한 경우 RAM을 업그레이드하거나 라운드 로빈 DNS 시스템이 앞에있는 다른로드 밸런서를 구축하십시오.
Hyppy

1
"로드 밸런서는 다른로드 밸런서에 의해 쉽게 확장 될 수 없습니다"-실제로 단일 ASIC 기반 L4로드 밸런서는 종종 우수한 결과를 제공하는 L7 HTTP 기반로드 밸런서 앞에 배치 될 수 있습니다. 동일한 기본 원칙이 소프트웨어 전용 구현에 적용됩니다 (예 : nignx 앞의 Linux LVS).
Jesper M

19

이미 승인 된 답변이 있지만 추가 할 것이 있습니다. 로드 밸런서 계층을 확장하는 가장 일반적인 '고전적인'방법은 다음과 같습니다 (특별한 순서는 아님).

  • 도메인의 여러 IP 주소를 공개하기위한 DNS Round Robin . 각 IP 주소에 대해 항상 사용 가능한 서버 쌍 (하나의 IP 주소가 항상 작동하도록 협력하는 2 대의 서버)을 구현하십시오. 각 IP는 어플라이언스 또는로드 밸런싱 소프트웨어가있는 서버를 사용하는 하나의로드 밸런서 클러스터에 해당합니다. 필요에 따라 더 많은로드 밸런서 쌍을 추가하여 수평으로 확장하십시오.

  • 라우팅 또는 방화벽 은 여러로드 밸런서로로드를 분산시키기 위해 조정 됩니다. 소스 IP 주소해시 하거나로드 밸런서에 대한 동일한 비용의 경로를 여러 개 갖는 유사한 방식으로 전면 라우터 또는 전면 방화벽이 들어오는 연결을 여러 IP 주소 (각각 하나의로드 밸런서 쌍을 나타냄)로 분산시킵니다.

  • IP 레벨 부하 분산 HTTP 레벨로드 밸런서 층 앞에 . IP 계층로드 밸런싱은 ASIC / 실리콘으로 구현 될 수 있으며 일부 사물에 대해 사악하게 빠질 수 있습니다. 따라서 단일 IP로드 밸런서 쌍은 종종 여러 HTTP / HTTPS 레벨로드 밸런서와 '유지'할 수 있으며 아키텍처를 훌륭하고 단순하게 유지하면서 멀티 기가비트 성능 수준을 제공 할 수 있습니다.

위의 여러 가지 방법에 완전히 깊이 들어가려면 긴 답변이 필요합니다. 그러나 일반적으로 로드 밸런서 계층을 확장하는 것은 어렵지 않고 애플리케이션 서버 계층, 특히 데이터베이스 계층을 확장하는 것이 훨씬 어렵습니다.

어플라이언스 폼 팩터 (F5, Cisco, A10) 또는 일반 서버 (Windows / Linux + 소프트웨어)를 선택하는 것이 중요하지 않습니다. 로드 밸런서 계층을 확장 할 때 고려해야 할 주요 사항은 다음과 같습니다.

  • State-full과 Stateless. 당신은 절대적으로 끈적 끈적한 세션이 필요합니까, 아니면없이 살 수 있습니까? 상태를 유지하지 않으면 모든 것이 더 간단 해집니다.
  • 로드 밸런싱을위한 '하드웨어'(ASIC)와 '소프트웨어' (일반용 서버). 각각 장단점이 있습니다. 위에 링크 된 HAProxy 개요 문서를 참조하십시오.
  • L3 / 4 (IP / TCP / IP)로드 밸런싱 및 L7 (HTTP) 로드 밸런싱. 또한 장단점에 따라 HAProxy 문서는 좋은 개요를 제공합니다.
  • 웹 노드 또는로드 밸런서에서 SSL 종료

일반적으로, 당신이 당신의 웹 사이트 전에이에 대해 걱정할 필요가 없습니다 가져 매우 큰 - 외환의 nginx와 하나의 현대적인 서버가 수십 초 당 일반 HTTP 요청 수천 처리합니다. 따라서 조기 최적화를 수행하지 말고이를 처리하지 마십시오.


실제로 DNS RR을 사용하여 각 IP 주소를 고 가용성으로 사용할 필요 는 없습니다 . 브라우저는 일반적으로 연결할 수 없을 때 사용 가능한 경우 다른 IP로 폴백합니다. 그러나 공용 웹 서비스가있는 경우 많은 웹 서비스 라이브러리가 다른 IP 로의 장애 조치를 자동으로 처리하지 않으므로 각 IP 주소마다 HA가 필요합니다.
rmalayter

9

HTTP로드 밸런싱 계층을 확장하는 핵심은 먼저 하위 레벨 (IP 또는 TCP)로드 밸런싱의 다른 계층을 추가하는 것입니다. 이 계층은 오픈 소스 소프트웨어로 완전히 구축 할 수 있지만 최신 라우터를 사용하면 더 나은 결과를 얻을 수 있습니다.

플로우 (TCP 세션)는 소스 / 대상 IP 및 TCP 포트와 같은 헤더를 사용하여 해시 되어 어떤 프론트 엔드로 이동해야하는지 결정해야합니다. 또한 프론트 엔드가 죽을 때 사용이 중지되도록하는 메커니즘이 필요합니다.

다양한 전략이 있습니다. 저는 수백만 명의 사용자에게 서비스를 제공하는 사이트에서 프로덕션에 사용한 몇 가지를 간략하게 설명하겠습니다. 모든 것을 자세히 설명하기에는 너무 길지만이 답변이 시작하기에 충분한 정보 / 포인터를 제공하기를 바랍니다. 이러한 솔루션을 구현하려면 네트워킹에 대해 잘 알고있는 사람이 필요합니다.

필자가 여기서 설명하는 것은 다른 답변에 설명 된 것보다 구현하기가 훨씬 어렵지만, 99.9 % 이상의 확장 성 문제 및 가용성 요구 사항이있는 트래픽이 많은 웹 사이트를 보유한 경우 실제로는 최신 기술입니다. . 이미 온보드 네트워크 엔지니어를 보유하고 있다면로드 밸런서 어플라이언스보다 설치 및 실행 비용이 적고 (CAPEX 및 Opex 모두), 추가 비용없이 추가로 확장 할 수 있습니다. 현재 모델을 능가하는 고가의 기기).

첫 번째 전략 : 방화벽

아마도 ISP 업 링크가 연결된 몇 개의 라우터가있을 것입니다. ISP는 2 개의 링크를 제공합니다 (VRRP를 사용하여 활성 / 수동). 라우터에서도 VRRP를 사용하며 공용 네트워크로가는 트래픽을 방화벽으로 라우팅합니다. 방화벽은 ( FW 1그리고 FW 2아래)도 또한 액티브 / 패시브하고 (당신의 HTTP로드 밸런서, 트래픽을 필터링하고 건강한 프런트 엔드 서버에 각각의 흐름을 보낼 것입니다 FE 1FE 2아래).

      + -------------- + + -------------- +
      | ISP 라우터 A | | ISP 라우터 B |
      + -------------- + + -------------- +
             | |
           == # ====================== # == (공용 네트워크)
             | |
      + --------------- + + --------------- +
      | 라우터 A | | 라우터 B |
      + --------------- + + --------------- +
             | |
           == # ===== # ========== # ===== # == (RFC 1918 개인 네트워크)
             | | | |
       + ------ + + ------ + + ------ + + ------ +
       | FW 1 | | 2 월 1 일 | | 2 월 2 일 | | FW 2 |
       + ------ + + ------ + + ------ + + ------ +

목표는 다음과 같은 흐름을 유지하는 것입니다.

  1. ISP는 IP로가는 트래픽을 활성 라우터로 라우팅합니다.
  2. 라우터는 트래픽을 RFC 1918 주소 를 사용하는 VIP로 라우팅합니다 . 이 VIP는 VRRP와 같이 활성 방화벽이 소유합니다. 방화벽 요구 사항에 OpenBSD를 사용하는 경우 VRRP / HSRP의 특허없는 대안 인 CARP 를 사용할 수 있습니다 .
  3. 방화벽이 필터를 적용합니다 (예 : "이 특정 IP 주소로가는 80 / tcp 및 443 / tcp 만 허용").
  4. 방화벽은 라우터 역할을하며 패킷을 정상적인 프론트 엔드로 전달합니다.
  5. 프론트 엔드가 TCP 연결을 종료합니다.

이제 마술은 4 단계와 5 단계에서 이루어 지므로 더 자세한 내용을 살펴 보겠습니다.

방화벽은 프런트 엔드 목록 ( FE 1FE 2)을 알고 있으며 흐름의 특정 측면에 따라 (예 : 다른 헤더 중에서 소스 IP 및 포트를 해시) 이들 중 하나를 선택합니다. 그러나 또한 트래픽을 정상적인 프론트 엔드로 전달해야합니다. 그렇지 않으면 트래픽이 블랙홀됩니다. 예를 들어 OpenBSD를 사용한다면을 사용할 수 있습니다 relayd. 뭐relayd간단합니다 : 모든 프론트 엔드의 상태를 점검합니다 (예 : 프로브 HTTP 요청을 전송하여), 프론트 엔드가 정상일 때 방화벽이 주어진 플로우의 패킷의 다음 홉을 선택하는 데 사용하는 테이블에 추가합니다. . 프런트 엔드가 상태 확인에 실패하면 테이블에서 제거되고 더 이상 패킷이 전송되지 않습니다. 패킷을 프런트 엔드로 전달할 때 모든 방화벽은 패킷의 대상 MAC 주소를 선택한 프런트 엔드의 주소로 교체합니다.

5 단계에서 사용자의 패킷은로드 밸런서 (Varnish, nginx 등)에 의해 수신됩니다. 이 시점에서 패킷은 여전히 ​​공개 IP 주소로 보내 지므로 루프백 인터페이스에서 VIP의 별칭을 지정해야합니다. 이 호출됩니다 DSR 당신의 프론트 엔드는 TCP 연결 만이 단순 트래픽을 보는 사이에 방화벽 (들어오는 패킷)를 종료하기 때문에, (직접 서버 반환). 라우터는 나가는 패킷을 ISP의 라우터로 직접 라우팅합니다. 요청이 응답보다 작은 경향이 있기 때문에 HTTP 트래픽에 특히 유용합니다. 분명히 말하면 : 이것은 OpenBSD에만 해당되는 것이 아니며 트래픽이 많은 웹 사이트에서 널리 사용됩니다.

잡았다 :

  • DSR을 사용하기 때문에 최종 사용자는 프런트 엔드 서버에 직접 연결됩니다. 어쩌면 이미 그런 경우 였을 수도 있지만 그렇지 않은 경우에는 제대로 고정되어 있는지 확인해야합니다.
  • OpenBSD를 사용하는 경우 커널이 단일 스레드이므로 단일 CPU 코어의 성능으로 인해 방화벽의 처리량이 제한됩니다. NIC 유형과보고있는 패킷 속도에 따라 문제가 될 수 있습니다. 이 문제를 해결하는 방법이 있습니다 (자세한 내용은 아래 참조).

두 번째 전략 : 방화벽없이

이 전략은 사용하는 라우터의 특성에 따라 달라 지므로보다 효율적이지만 설정하기가 어렵습니다. 아이디어는 위의 방화벽을 무시하고 라우터가 방화벽이 수행 한 모든 작업을 수행하도록하는 것입니다.

포트 별 L3 / L4 ACL, BGPECMP정책 기반 라우팅 (PBR) 을 지원하는 라우터가 필요합니다 . 고급 라우터 만 이러한 기능을 지원하며 종종 BGP를 사용하기 위해 추가 라이센스 비용이 부과됩니다. 이는 일반적으로 하드웨어로드 밸런서보다 저렴하며 확장하기가 훨씬 쉽습니다. 이 하이 엔드 라우터의 장점은 회선 속도 (예 : 10GbE 인터페이스에서도 링크를 최대한 활용할 수 있음)는 모든 결정이 ASIC에 의해 하드웨어에서 이루어지기 때문입니다.

ISP 업 링크가있는 포트에서 방화벽에있는 ACL을 적용하십시오 (예 : "이 특정 IP 주소로가는 80 / tcp 및 443 / tcp 만 허용"). 그런 다음 각 프론트 엔드가 라우터와 BGP 세션을 유지하도록하십시오. 우수한 OpenBGPD (프런트 엔드가 OpenBSD에있는 경우) 또는 Quagga를 사용할 수 있습니다 . 라우터는 BGP 세션을 유지하고 있기 때문에 정상인 프론트 엔드에 대한 트래픽을 ECMP합니다. 라우터는 또한 PBR을 사용하여 트래픽을 적절히 라우팅합니다.

개선

  • 방화벽 쌍 솔루션을 사용하면 방화벽을 통해 TCP 상태를 동기화 할 수있어 한 방화벽이 실패 할 때 모든 방화벽이 다른 방화벽으로 원활하게 실패 할 수 있습니다. 으로이 작업을 수행 할 수 있습니다 pfsync.
    • 마음에 베어 pfsync일반적으로 방화벽의 패킷 속도를 두 배로.
    • HTTP는 상태 비 저장 프로토콜이므로을 사용하지 않기 때문에 방화벽 장애 조치 (failover) 중에 모든 연결을 재설정하면 끝이 아닙니다 pfsync.
  • 단일 방화벽을 능가하는 경우 라우터에서 ECMP를 사용하여 트래픽을 둘 이상의 방화벽 쌍으로 라우팅 할 수 있습니다.
  • 둘 이상의 방화벽 쌍을 사용하는 경우 방화벽을 모두 활성 / 활성으로 만들 수도 있습니다. 방화벽이 라우터와의 BGP 세션을 유지하도록함으로써 방화벽을 만들지 않고도 프런트 엔드가 2 차 설계에서 1을 유지해야하는 것처럼 방화벽을 확보 할 수 있습니다.

샘플 relayd구성

https://calomel.org/relayd.html의 HOWTO도 참조 하십시오

vip = "1.2.3.4"# 퍼블릭 IP 주소
               # (하나 이상 가질 수 있지만 반드시 그럴 필요는 없습니다)
fe1 = "10.1.2.101"
fe2 = "10.1.2.102"
fe3 = "10.1.2.103"
fe4 = "10.1.2.104"# 여러 프런트 엔드를 가질 수 있습니다.
int_if = "em0"
표 <fe> {$ fe1 재시도 2, $ fe2 재시도 2, $ fe3 재시도 2, $ fe4 재시도 2}
테이블 <fallback> {127.0.0.1}

웹 트래픽 리디렉션 {
        $ vip 포트 80으로 청취
        세션 시간 초과 60
        <fe> 라우트 http "/healthcheck.html"다이제스트 "(healthcheck.html의 sha1sum)"인터페이스 $ int_if
}

2

개인적으로 저는 그 시점에서 Cisco의 ACE / ASA, Foundry ServerIrons, Zeus ZXTM (무거운로드를 위해 설계된 SW LB)와 같은 구성이 간단하고 구성이 덜한 하드웨어로드 밸런서로갑니다.


다시 말해서 스케일 ? 이러한 LB는 몇 개의 연결 등에서 계속 최대로 유지됩니다. 그럼 뭐야? 정말 내 질문입니다. 감사!
z8000

1
실제로 큰 사이트는 특정 형태의 DNS 라운드 로빈에서 실행되는 많은 양의 LB를 사용합니다. 이는 현재로서는 충분하고 수억 개의 연결을 처리 할 수 ​​있습니다. 그것은 왜 그렇게 많은 연결이 당연히 열려 있어야 하는가에 대한 의문이 있다고 말했다.
Chopper3

내부 뜻 RRDNS는? 깔끔한, 나는 그것을 생각하지 않았다. 다시 : 연결 열기 ... 이벤트가 백엔드에서 발생하면 시간이 지남에 따라 연결된 클라이언트에 업데이트를 보내야하는 앱 옵션을 탐색 중입니다. 사용자 정의 TCP 서버 또는 SLB 뒤의 많은 개방형 HTTP 연결 사이에서 찢어졌습니다. 귀하의 의견에 감사드립니다.
z8000

외부 RRDNS 여야한다고 생각합니다. 예를 들어 Twitter.com은 RRDNS를 사용하여 요청을 해결하고 많은 대형 LB 중 하나에 분배 한 다음 서버에로드를 분배합니다.
Robert

예. Robert, 맞습니다. 예를 들어 Cisco GSS 박스를 사용하여 사이트 별 RR을 수행합니다.
Chopper3

1

답장을 보내기 위해 열려있는 연결을 지속적으로 많이 유지하는 대신 클라이언트가 필요할 때마다 서버를 정기적으로 폴링하는 방식으로 응용 프로그램을 코딩 하시겠습니까?

실제로 수행하는 작업에 매우 밀리 초가 걸리거나 클라이언트가 다음 폴링 기간까지 15/20 초를 기다릴 수 있습니까?


0

일반적인 접근 방식은 필요한로드를 처리 할 수있을만큼 충분히 큰 클러스터를 만들고 결정적인로드 균형 조정을 수행 할 수있는 SLB를 사용하는 것입니다 (영구 연결의 경우).

CARP와 같은 것은 요청하는 IP의 해시를 사용하여 요청을 처리 할 백엔드 웹 서버를 결정합니다. 결정 론적이지만로드 밸런서 앞에 방화벽이나 NAT가있는 경우에는 유용하지 않습니다. Linux에서 실행중인 경우 IPVS
와 같은 것이 유용 할 수도 있습니다 .


잉어에 대해 당신이 주장하는 것은 그것이 작동하는 방식과는 거리가 멀기 때문에 어디서부터 시작 해야할지 모르겠습니다! IPVS를 언급하면 ​​+ -0입니다.
3molo

@ 3molo ... 응? linux.com/archive/feed/35482 에서 net.inet.carp.arpbalance를 참조하십시오. "..CARP 소스는 요청의 원래 IP를 해시합니다. 그런 다음 해시는 사용 가능한 풀에서 가상 호스트를 선택하여 요청을 처리합니다. "
Paul
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.