Meilleures pratiques d'équilibrage de charge pour la persistance

8

Nous exécutons une application Web servant des API Web pour un nombre croissant de clients. Pour commencer, les clients étaient généralement à la maison, au bureau ou sur d'autres réseaux sans fil soumettant des téléchargements HTTP par blocs à notre API. Nous nous sommes maintenant diversifiés pour gérer davantage de clients mobiles. Les fichiers allant de quelques k à plusieurs concerts, décomposés en plus petits morceaux et remontés sur notre API.

Notre équilibrage de charge actuel est effectué sur deux couches, nous utilisons d'abord le DNS à tour de rôle pour publier plusieurs enregistrements A pour notre adresse api.company.com. À chaque adresse IP, nous hébergeons un LVS Linux: http://www.linuxvirtualserver.org/ , équilibreur de charge qui examine l'adresse IP source d'une demande pour déterminer à quel serveur d'API la connexion doit être transmise. Ces boîtiers LVS sont configurés avec heartbeatd pour prendre en charge les VIP externes et les IP de passerelle internes les uns des autres.

Dernièrement, nous avons vu deux nouvelles conditions d'erreur.

La première erreur est lorsque les clients oscillent ou migrent d'un LVS à un autre, à mi-téléchargement. Cela entraîne à son tour nos équilibreurs de charge à perdre la trace de la connexion persistante et à envoyer le trafic vers un nouveau serveur API, interrompant ainsi le téléchargement en bloc sur deux ou plusieurs serveurs. Notre intention était que la valeur Round Robin DNS TTL pour notre api.company.com (que nous avons fixée à 1 heure) soit honorée par les serveurs de noms de mise en cache en aval, les couches de mise en cache du système d'exploitation et les couches d'application client. Cette erreur se produit pour environ 15% de nos téléchargements.

La deuxième erreur que nous avons vue beaucoup moins fréquemment. Un client initiera le trafic vers une boîte LVS et sera acheminé vers le serveur réel A derrière. Par la suite, le client entrera via une nouvelle adresse IP source, que la boîte LVS ne reconnaît pas, acheminant ainsi le trafic en cours vers le serveur réel B également derrière ce LVS.

Compte tenu de notre architecture telle que décrite dans la partie ci-dessus, j'aimerais savoir quelles sont les expériences des gens avec une meilleure approche qui nous permettra de traiter chacun des cas d'erreur ci-dessus plus gracieusement?

Modifier le 3/5/2010:

Cela ressemble à ce dont nous avons besoin. Hachage GSLB pondéré sur l'adresse IP source.

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

dmourati
la source
Votre question n'est pas vraiment spécifique au mobile pour le moment. Peut-être envisageriez-vous de le réviser et de le simplifier?
Jesper M

Réponses:

11

La solution canonique à cela est de ne pas s'appuyer sur l'adresse IP de l'utilisateur final, mais d' utiliser à la place un équilibreur de charge de couche 7 (HTTP / HTTPS) avec "Sticky Sessions" via un cookie.

Les sessions persistantes signifient que l'équilibreur de charge dirigera toujours un client donné vers le même serveur principal. Via cookie signifie que l'équilibreur de charge (qui est lui-même un périphérique HTTP entièrement capable) insère un cookie (que l'équilibreur de charge crée et gère automatiquement) pour se souvenir du serveur principal qu'une connexion HTTP donnée doit utiliser.

Le principal inconvénient des sessions persistantes est que la charge du serveur beckend peut devenir quelque peu inégale. L'équilibreur de charge peut uniquement répartir la charge équitablement lorsque de nouvelles connexions sont établies, mais étant donné que les connexions existantes peuvent durer longtemps dans votre scénario, la charge ne sera pas distribuée de manière entièrement équitable à certaines périodes.

À peu près tous les équilibreurs de charge de couche 7 devraient être en mesure de le faire. Sur Unix / Linux, quelques exemples courants sont nginx, HAProxy, Apsis Pound, Apache 2.2 avec mod_proxy, et bien d'autres. Sous Windows 2008+, il existe le routage des demandes d'application Microsoft. En tant qu'appareils, Coyote Point, loadbalancer.org, Kemp et Barracuda sont courants dans l'espace bas de gamme; et F5, Citrix NetScaler et autres en haut de gamme.

Willy Tarreau, l'auteur de HAProxy, a un bon aperçu des techniques d'équilibrage de charge ici .

À propos du DNS Round Robin:

Notre intention était que la valeur Round Robin DNS TTL pour notre api.company.com (que nous avons fixée à 1 heure) soit honorée par les serveurs de noms de mise en cache en aval, les couches de mise en cache du système d'exploitation et les couches d'application client.

Ce ne sera pas le cas . Et DNS Round Robin n'est pas une bonne solution pour l'équilibrage de charge . Et si rien d'autre ne vous convainc, gardez à l'esprit que les clients modernes peuvent préférer un hôte à tous les autres en raison de la plus longue correspondance de préfixe , donc si le client mobile change d'adresse IP, il peut choisir de basculer vers un autre hôte RR.

Fondamentalement, il est acceptable d'utiliser le round robin DNS comme une distribution de charge à granularité grossière, en pointant 2 enregistrements RR ou plus vers des adresses IP hautement disponibles, gérées par des équilibreurs de charge réels en HA actif / passif ou actif / actif. Et si c'est ce que vous faites, alors vous pourriez aussi bien servir ces enregistrements DNS RR avec de longues valeurs Time To Live, car les adresses IP associées sont déjà très disponibles.

Jesper M
la source
Merci. Nous sommes en mode actif / actif avec LVS. Les adresses IP sont hautement disponibles et nous avons beaucoup de contrôle sur les clients lorsque nous les écrivons nous-mêmes et ils dépendent de notre serveur API qui n'est pas entièrement sans état comme décrit ci-dessus. J'ai testé le problème de mise en cache au niveau du système d'exploitation sur ma boîte Linux au travail (il n'a pas de mise en cache activé) ainsi que mon ordinateur portable Mac OSX à la maison (il met en cache au niveau de la couche OS, qui "épingle" l'IP à un résultat ou à l'autre) ).
dmourati
J'ai fini par écrire mon propre serveur DNS personnalisé pour résoudre le problème du round robin. Il regarde l'adresse IP source et utilise un hachage pour répondre avec un enregistrement cohérent. Semble fonctionner et a réduit notre problème de "commutateur de pop" par un facteur de 10.
dmourati
4

Pour répondre à votre question sur les alternatives: Vous pouvez obtenir un équilibrage de charge solide de couche 7 via HAProxy .

En ce qui concerne la résolution des problèmes d'affinité LVS, je suis un peu sec sur les idées solides. Cela peut être aussi simple qu'un timeout ou un débordement. Certains clients mobiles changent d'adresse IP lorsqu'ils sont connectés au réseau; c'est peut-être la source de vos malheurs? Je suggère, à tout le moins, que vous étaliez la granularité d'affinité à au moins une classe C.

Hyppy
la source
HAProxy était définitivement dans ma ligne de mire. J'ai lu un article assez intéressant sur l'équilibrage de charge L4 contre L7. blog.loadbalancer.org/why-layer-7-sucks Mon avis: je voudrais laisser cela entre les mains de l'application. Tout "smarts" supplémentaire que j'ajoute à la couche LB devra simplement être corrigé / réadressé lorsque nous changerons notre application. La résolution du problème dans l'application elle-même signifie que nous pouvons optimiser et affiner les choses au niveau du LB tout en restant confiants que même en cas de faux pas du LB, nous obtiendrons toujours les données.
dmourati
@dmourati: Désolé, mais ce billet de blog est plein d'hypothèses inexactes. Ne le suivez pas aveuglément. Il est absolument vrai qu'une architecture «rien partagé» pour les serveurs d'applications Web est «la meilleure». Dans ce cas, vous devez utiliser l'équilibrage de charge Round Robin ou Random. Mais, tant que vous avez des téléchargements HTTP de plusieurs Go, vous avez des conversations HTTP de longue durée, et un équilibreur de charge HTTP est juste mieux placé pour comprendre ce long échange HTTP et agir correctement. L'utilisation d'un équilibreur HTTP n'empêche pas de rendre le code de votre application backend `` plus intelligent '', vous êtes toujours libre de le faire à tout moment.
Jesper M