Best Practices für den Lastausgleich für die Persistenz

8

Wir führen eine Webanwendung aus, die Web-APIs für eine zunehmende Anzahl von Clients bereitstellt. Zu Beginn waren die Clients in der Regel zu Hause, im Büro oder in anderen drahtlosen Netzwerken, die blockierte http-Uploads an unsere API sendeten. Wir haben uns jetzt darauf konzentriert, mehr mobile Clients zu verwalten. Die Dateien reichen von einigen k bis zu mehreren Gigs, werden in kleinere Teile zerlegt und auf unserer API wieder zusammengesetzt.

Unser aktueller Lastausgleich wird auf zwei Ebenen durchgeführt. Zuerst verwenden wir Round-Robin-DNS, um mehrere A-Einträge für unsere Adresse api.company.com anzukündigen. An jeder IP- Adresse hosten wir ein Linux-LVS: http://www.linuxvirtualserver.org/ , einen Load-Balancer, der anhand der Quell-IP-Adresse einer Anforderung ermittelt, an welchen API-Server die Verbindung übergeben werden soll. Diese LVS-Boxen sind mit heartbeatd konfiguriert, um externe VIPs und interne Gateway-IPs voneinander zu übernehmen.

In letzter Zeit haben wir zwei neue Fehlerbedingungen gesehen.

Der erste Fehler besteht darin, dass Clients während des Uploads von einem LVS zu einem anderen oszillieren oder migrieren. Dies wiederum führt dazu, dass unsere Load Balancer den Überblick über die dauerhafte Verbindung verlieren und den Datenverkehr an einen neuen API-Server senden, wodurch der Chunk-Upload auf zwei oder mehr Servern unterbrochen wird. Unsere Absicht war es, den Round Robin DNS TTL-Wert für api.company.com (den wir auf 1 Stunde festgelegt haben) von den nachgeschalteten Caching-Nameservern, OS-Caching-Layern und Client-Anwendungs-Layern zu berücksichtigen. Dieser Fehler tritt bei ungefähr 15% unserer Uploads auf.

Der zweite Fehler, den wir viel seltener gesehen haben. Ein Client initiiert Datenverkehr zu einer LVS-Box und wird an den dahinter liegenden Realserver A weitergeleitet. Danach kommt der Client über eine neue Quell-IP-Adresse herein, die die LVS-Box nicht erkennt, wodurch der laufende Verkehr auch hinter diesem LVS an den Realserver B weitergeleitet wird.

Angesichts unserer Architektur, wie oben beschrieben, möchte ich wissen, welche Erfahrungen die Menschen mit einem besseren Ansatz gemacht haben, der es uns ermöglicht, jeden der oben genannten Fehlerfälle eleganter zu behandeln.

Bearbeiten 03.05.2010:

Das sieht so aus, wie wir es brauchen. Gewichtetes GSLB-Hashing für die Quell-IP-Adresse.

http://www.brocade.com/support/Product_Manuals/ServerIron_ADXGlobalServer_LoadBalancingGuide/gslb.2.11.html#271674

dmourati
quelle
Ihre Frage ist momentan nicht wirklich spezifisch für Mobilgeräte. Vielleicht würden Sie überlegen, es zu überarbeiten und zu vereinfachen?
Jesper M

Antworten:

11

Die kanonische Lösung hierfür besteht darin, sich nicht auf die IP-Adresse des Endbenutzers zu verlassen, sondern stattdessen einen Layer 7 (HTTP / HTTPS) -Lastausgleich mit "Sticky Sessions" über ein Cookie zu verwenden.

Sticky Sessions bedeutet, dass der Load Balancer einen bestimmten Client immer an denselben Backend-Server weiterleitet. Über Cookie bedeutet, dass der Load Balancer (der selbst ein voll funktionsfähiges HTTP-Gerät ist) ein Cookie einfügt (das der Load Balancer automatisch erstellt und verwaltet), um sich zu merken, welchen Backend-Server eine bestimmte HTTP-Verbindung verwenden soll.

Der Hauptnachteil von Sticky Sessions ist, dass die Beckend-Serverlast etwas ungleichmäßig werden kann. Der Load Balancer kann die Last nur dann fair verteilen, wenn neue Verbindungen hergestellt werden. Da jedoch vorhandene Verbindungen in Ihrem Szenario möglicherweise eine lange Lebensdauer haben, wird die Last in einigen Zeiträumen nicht vollständig gerecht verteilt.

Nahezu jeder Layer 7 Load Balancer sollte dazu in der Lage sein. Unter Unix / Linux sind einige gängige Beispiele Nginx, HAProxy, Apsis Pound, Apache 2.2 mit mod_proxy und viele mehr. Unter Windows 2008+ gibt es Microsoft Application Request Routing. Als Geräte sind Coyote Point, loadbalancer.org, Kemp und Barracuda im Low-End-Bereich üblich. und F5, Citrix NetScaler und andere im High-End-Bereich.

Willy Tarreau, der Autor von HAProxy, hat hier einen schönen Überblick über Lastausgleichstechniken .

Über den DNS Round Robin:

Unsere Absicht war es, den Round Robin DNS TTL-Wert für api.company.com (den wir auf 1 Stunde festgelegt haben) von den nachgeschalteten Caching-Nameservern, OS-Caching-Layern und Client-Anwendungs-Layern zu berücksichtigen.

Es wird nicht sein . Und DNS Round Robin eignet sich nicht für den Lastausgleich . Und wenn Sie sonst nichts überzeugt, denken Sie daran, dass moderne Clients aufgrund der längsten Präfix-Übereinstimmungs- Fixierung möglicherweise einen Host allen anderen vorziehen. Wenn der mobile Client also die IP-Adresse ändert, kann er zu einem anderen RR-Host wechseln.

Grundsätzlich ist es in Ordnung, DNS-Round-Robin als grobkörnige Lastverteilung zu verwenden, indem zwei oder mehr RR-Einträge auf hochverfügbare IP-Adressen verweisen, die von echten Lastausgleichern in aktivem / passivem oder aktivem / aktivem HA verarbeitet werden. Und wenn Sie dies tun, können Sie diese DNS-RR-Einträge auch mit langen Time To Live-Werten bereitstellen, da die zugehörigen IP-Adressen bereits hoch verfügbar sind.

Jesper M.
quelle
Vielen Dank. Wir sind im Aktiv / Aktiv-Modus mit LVS. Die IPs sind hoch verfügbar und wir haben viel Kontrolle über die Clients, während wir sie selbst schreiben. Sie verlassen sich auf unseren API-Server, der nicht wie oben beschrieben vollständig zustandslos ist. Ich habe das Caching-Problem auf Betriebssystemebene auf meiner Linux-Box bei der Arbeit getestet (es ist kein Caching aktiviert) sowie auf meinem Mac OSX-Laptop zu Hause (es wird auf der Betriebssystemebene zwischengespeichert, wodurch die IP an das eine oder andere Ergebnis "gebunden" wird ).
Dmourati
Am Ende habe ich meinen eigenen DNS-Server geschrieben, um das Round-Robin-Problem zu beheben. Es überprüft die Quell-IP-Adresse und verwendet einen Hash, um mit einem konsistenten Datensatz zu antworten. Scheint zu funktionieren und hat unser "Pop-Switch" -Problem um den Faktor 10
reduziert
4

So beantworten Sie Ihre Frage zu Alternativen: Über HAProxy können Sie einen soliden Lastausgleich der Schicht 7 erzielen .

Was die Behebung der LVS-Affinitätsprobleme angeht, bin ich ein bisschen trocken bei soliden Ideen. Dies kann so einfach wie eine Zeitüberschreitung oder ein Überlauf sein. Einige mobile Clients wechseln die IP-Adressen, während sie mit dem Netzwerk verbunden sind. Vielleicht ist dies die Quelle Ihrer Leiden? Ich würde zumindest vorschlagen, dass Sie die Affinitätsgranularität auf mindestens eine Klasse C verteilen.

Hyppy
quelle
HAProxy war definitiv in meinen Augen. Ich habe einen ziemlich interessanten Artikel über L4 v L7 Load Balancing gelesen. blog.loadbalancer.org/why-layer-7-sucks Meine Meinung : Ich möchte dies in den Händen der Anwendung lassen. Alle zusätzlichen "Smarts", die ich der LB-Ebene hinzufüge, müssen nur gepatcht / neu adressiert werden, wenn wir unsere Anwendung ändern. Die Lösung des Problems in der Anwendung selbst bedeutet, dass wir die Dinge in der LB optimieren und optimieren können, während wir zuversichtlich bleiben, dass wir die Daten auch dann erhalten, wenn ein LB-Fehltritt vorliegt.
dmourati
@dmourati: Sorry, aber dieser Blog-Beitrag ist voller ungenauer Annahmen. Folge ihm nicht blindlings. Es ist absolut richtig, dass eine "Shared Nothing" -Architektur für die Webanwendungsserver "am besten" ist. In diesem Fall sollten Sie Round Robin oder Random Load Balancing verwenden. Solange Sie jedoch HTTP-Uploads mit mehreren GB haben, haben Sie langlebige HTTP-Konversationen, und ein HTTP-Load-Balancer ist nur besser positioniert, um diesen langen HTTP-Austausch zu verstehen und korrekt zu handeln. Die Verwendung eines HTTP-Balancers schließt nicht aus, dass Ihr Backend-App-Code „intelligenter“ wird. Sie können dies jedoch jederzeit tun.
Jesper M