Best practice per il bilanciamento del carico per la persistenza


8

Eseguiamo un'applicazione Web che serve API Web per un numero crescente di client. Per iniziare, i clienti erano generalmente a casa, in ufficio o in altre reti wireless che inviano caricamenti HTTP a pezzi alla nostra API. Ora abbiamo deciso di gestire più client mobili. I file vanno da pochi k a diversi concerti, suddivisi in blocchi più piccoli e riassemblati nella nostra API.

Il nostro attuale bilanciamento del carico viene eseguito su due livelli, in primo luogo utilizziamo DNS round robin per pubblicizzare più record A per il nostro indirizzo api.company.com. Ad ogni IP, ospitiamo un LVS Linux: http://www.linuxvirtualserver.org/ , bilanciamento del carico che esamina l'indirizzo IP di origine di una richiesta per determinare a quale server API gestire la connessione. Queste caselle LVS sono configurate con heartbeatd per rilevare l'IP reciproco tra VIP esterni e IP gateway interni.

Ultimamente, abbiamo visto due nuove condizioni di errore.

Il primo errore è quando i client oscillano o migrano da un LVS a un altro, durante il caricamento. Ciò a sua volta fa sì che i nostri sistemi di bilanciamento del carico perdano la traccia della connessione persistente e inviino il traffico a un nuovo server API, interrompendo in tal modo il caricamento in blocco su due o più server. Il nostro intento era che il valore TTL DNS di Round Robin per il nostro api.company.com (che abbiamo impostato a 1 ora) fosse onorato dai nameserver della cache a valle, dai livelli di cache del sistema operativo e dai livelli dell'applicazione client. Questo errore si verifica per circa il 15% dei nostri caricamenti.

Il secondo errore che abbiamo visto molto meno comunemente. Un client avvierà il traffico verso un box LVS e verrà instradato al realserver A dietro di esso. Successivamente, il client arriverà tramite un nuovo indirizzo IP di origine, che la casella LVS non riconosce, indirizzando in tal modo il traffico in corso al realserver B anche dietro tale LVS.

Data la nostra architettura come descritto in parte sopra, mi piacerebbe sapere quali sono le esperienze delle persone con un approccio migliore che ci permetterà di gestire ciascuno dei casi di errore sopra con più grazia?

Modifica il 03/05/2010:

Questo sembra ciò di cui abbiamo bisogno. Hash GSLB ponderato sull'indirizzo IP di origine.

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


La tua domanda non è davvero specifica per il cellulare in questo momento. Forse valuteresti di rivederlo e semplificarlo?
Jesper M,

Risposte:


11

La soluzione canonica a questo non è fare affidamento sull'indirizzo IP dell'utente finale, ma utilizzare invece un bilanciamento del carico Layer 7 (HTTP / HTTPS) con "Sticky Session" tramite un cookie.

Le sessioni permanenti indicano che il bilanciamento del carico indirizzerà sempre un determinato client allo stesso server back-end. Tramite cookie si intende che il bilanciamento del carico (che è esso stesso un dispositivo HTTP pienamente capace) inserisce un cookie (che il bilanciamento del carico crea e gestisce automagicamente) per ricordare quale server back-end deve utilizzare una determinata connessione HTTP.

Il principale svantaggio di sessioni appiccicose è che il carico del server beckend può diventare in qualche modo disomogeneo. Il bilanciamento del carico può distribuire il carico in modo equo solo quando vengono effettuate nuove connessioni, ma dato che le connessioni esistenti possono durare a lungo nel proprio scenario, in alcuni periodi il carico non verrà distribuito in modo completamente equo.

Quasi ogni bilanciamento del carico di livello 7 dovrebbe essere in grado di farlo. Su Unix / Linux, alcuni esempi comuni sono nginx, HAProxy, Apsis Pound, Apache 2.2 con mod_proxy e molti altri. Su Windows 2008+ è disponibile il routing delle richieste di applicazioni Microsoft. Come elettrodomestici, Coyote Point, loadbalancer.org, Kemp e Barracuda sono comuni nello spazio di fascia bassa; e F5, Citrix NetScaler e altri di fascia alta.

Willy Tarreau, l'autore di HAProxy, ha una bella panoramica delle tecniche di bilanciamento del carico qui .

Informazioni sul Round Robin DNS:

Il nostro intento era che il valore TTL DNS di Round Robin per il nostro api.company.com (che abbiamo impostato a 1 ora) fosse onorato dai nameserver della cache a valle, dai livelli di cache del sistema operativo e dai livelli dell'applicazione client.

Non lo sarà . E DNS Round Robin non è adatto per il bilanciamento del carico . E se nient'altro ti convince, tieni presente che i client moderni potrebbero preferire un host rispetto a tutti gli altri a causa del blocco dei prefissi più lungo , quindi se il client mobile cambia indirizzo IP, potrebbe scegliere di passare a un altro host RR.

Fondamentalmente, va bene usare il round robin DNS come distribuzione di carico a grana grossa, indicando 2 o più record RR verso indirizzi IP altamente disponibili, gestiti da bilanciatori di carico reali in HA attivo / passivo o attivo / attivo. E se è quello che stai facendo, allora potresti anche servire quei record RR DNS con valori Time To Live lunghi, poiché gli indirizzi IP associati sono già altamente disponibili.


Grazie. Siamo in modalità Attivo / Attivo con LVS. Gli IP sono altamente disponibili e abbiamo un sacco di controllo sui client mentre li scriviamo noi stessi e si affidano al nostro server API che non è completamente apolide come descritto sopra. Ho testato il problema di memorizzazione nella cache a livello di sistema operativo sul mio box Linux al lavoro (non ha la cache attivata) e sul mio laptop Mac OSX a casa (memorizza nella cache a livello del sistema operativo, che "blocca" l'IP a un risultato o all'altro ).
dmourati,

Ho finito per scrivere il mio server DNS personalizzato per risolvere il problema del round robin. Guarda l'indirizzo IP di origine e utilizza un hash per rispondere con un record coerente. Sembra funzionare e ha ridotto il nostro problema di "pop switch" di un fattore 10.
dmourati,

4

Per rispondere alla tua domanda sulle alternative: puoi ottenere un solido bilanciamento del carico di livello 7 tramite HAProxy .

Per quanto riguarda la risoluzione dei problemi di affinità LVS, sono un po 'asciutto con idee solide. Potrebbe essere semplice come un timeout o un overflow. Alcuni client mobili cambieranno gli indirizzi IP mentre sono connessi alla rete; forse questa potrebbe essere la fonte dei tuoi guai? Suggerirei almeno di distribuire la granularità dell'affinità almeno in una classe C.


HAProxy era decisamente ai miei occhi. Ho letto un articolo piuttosto interessante sul bilanciamento del carico L4 contro L7. blog.loadbalancer.org/why-layer-7-sucks La mia opinione : vorrei lasciarlo nelle mani dell'applicazione. Ogni ulteriore "intelligenza" che aggiungo al livello LB dovrà solo essere rattoppata / ritoccata mentre cambiamo la nostra applicazione. Risolvere il problema nell'applicazione stessa significa che possiamo ottimizzare e mettere a punto le cose nell'LB pur rimanendo sicuri che anche se c'è un passo falso LB avremo comunque i dati.
dmourati,

@dmourati: mi dispiace, ma quel post sul blog è pieno di ipotesi imprecise. Non seguirlo ciecamente. È assolutamente vero che un'architettura "nulla condivisa" per i server di applicazioni Web è "migliore". In tal caso, è necessario utilizzare Round Robin o Bilanciamento del carico casuale. Ma finché hai caricamenti HTTP multi-GB hai conversazioni HTTP di lunga durata e un bilanciamento del carico HTTP è semplicemente meglio posizionato per comprendere questo lungo scambio HTTP e agire correttamente. L'uso di un bilanciamento HTTP non impedisce di rendere il codice dell'app back-end "più intelligente", sei comunque libero di farlo in qualsiasi momento.
Jesper M,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.