Comment découvrir les autres serveurs d'une même application

a marqué ce sujet comme résolu.

Salut tout le monde,

Pour le fun, je suis en train de jeter un oeil à l’algorithme de consensus Raft, qui permet à des serveurs de faire tourner une application et atteindre un consensus. Je comprends plutôt bien comment l’algorithme fonctionne mais ce que je ne suis pas sûr de comprendre, c’est comment les serveurs savent quels autres serveurs faisant tourner la même application existent. Pour pouvoir faire des appels HTTP à d’autres serveurs, il faut connaître leur addresse et c’est là que ça devient pas clair pour moi : comment connaître les addresses des autres participants?

Je pense que si les serveurs existants sont plutôt stables, on peut hardcoder ça quelque part, dans un fichier de propriétés par exemple. Si c’est plus dynamique, on pourrait imaginer utliser une base de données ou une cache. Et si on veut vraiment être cool, on pourrait utiliser un système de Service Discovery, style Consul.

Est-ce que ce que je dis ci-dessus est correct ? Ou existe-t-il d’autres façons, peut-être meilleures, pour répondre à ma question.

Le problème du discovery est dissocié du protocole de consensus, à mon sens.

Il y a plusieurs méthodes. Une, assez connue, est de la faire via DNS. Étant donné qu’il est possible d’attribuer plusieurs adresses IPv4 ou IPv6 dans un enregistrement A ou AAAA, ça ne pose pas de problème. Après tout, le DNS fonctionne ici comme une DB de cache.

Je crois savoir aussi qu’ElasticSearch avait une méthode assez expéditive, qui était de scanner le réseau correspondant aux interfaces du serveur (ce qui avait causé quelques soucis chez les prestataires d’hébergement qui isolaient mal les réseaux entre plusieurs clients). Je ne sais plus si c’est encore le cas, mais la méthode peut faire sens si tu es dans un même réseau privé (qui peut être fait via VPN ou RPN si besoin d’être en multi-DC).

Comme tu dis, on peut aussi indiquer ça dans un fichier. C’est une approche qui était proposée pour les clusters MariaDB/Galera. Évidemment, quand on ajoutait ou supprimait un nœud, il fallait mettre à jour le fichier partout.

À l’instar de certains protocoles décentralisés P2P, on peut aussi avoir recours à un service sur lequel les nœuds doivent se signaler et obtenir la liste des autres nœuds, pour le bootstrap initial seulement. Ça implique de maintenir un tel service.

+2 -0

Le problème du discovery est dissocié du protocole de consensus, à mon sens.

Oui, je suis d’accord et c’est bien ça mon problème :p Le papier explique bien l’algorithme de consensus mais pour l’implémenter, j’ai besoin d’une façon de connaître avec quels serveurs je peux communiquer.

Il y a plusieurs méthodes. Une, assez connue, est de la faire via DNS. Étant donné qu’il est possible d’attribuer plusieurs adresses IPv4 ou IPv6 dans un enregistrement A ou AAAA, ça ne pose pas de problème. Après tout, le DNS fonctionne ici comme une DB de cache.

Je crois savoir aussi qu’ElasticSearch avait une méthode assez expéditive, qui était de scanner le réseau correspondant aux interfaces du serveur (ce qui avait causé quelques soucis chez les prestataires d’hébergement qui isolaient mal les réseaux entre plusieurs clients). Je ne sais plus si c’est encore le cas, mais la méthode peut faire sens si tu es dans un même réseau privé (qui peut être fait via VPN ou RPN si besoin d’être en multi-DC).

Comme tu dis, on peut aussi indiquer ça dans un fichier. C’est une approche qui était proposée pour les clusters MariaDB/Galera. Évidemment, quand on ajoutait ou supprimait un nœud, il fallait mettre à jour le fichier partout.

À l’instar de certains protocoles décentralisés P2P, on peut aussi avoir recours à un service sur lequel les nœuds doivent se signaler et obtenir la liste des autres nœuds, pour le bootstrap initial seulement. Ça implique de maintenir un tel service.

sgble

Ok, merci des clarifications ! Je pense que je vais continuer avec une liste statique ou une BDD centrale pour le moment puis peut-être rendre ça plus complexe / résilient dans le futur en cas de besoin.

Je sais bien que la question est plus générale que ça, mais je pense que l’info vaut le coup d’être mentionnée.

Il y a plusieurs méthodes. Une, assez connue, est de la faire via DNS. Étant donné qu’il est possible d’attribuer plusieurs adresses IPv4 ou IPv6 dans un enregistrement A ou AAAA, ça ne pose pas de problème. Après tout, le DNS fonctionne ici comme une DB de cache.

C’est même la façon de faire "par défaut" avec Kubernetes, et c’est diaboliquement simple et efficace. Il suffit pour cela de définir un service headless (de type ClusterIP en lui passant l’option clusterIP: None), et un simple appel DNS régulier sur le nom du service permet de récupérer les adresses IP de toutes les instances qui sont actuellement en train de tourner.

Je me sers de ça dans plusieurs endroits au boulot pour faire du self-discovery, et c’est largement suffisant dans mon cas pour choisir arbitrairement un leader (en prenant l’IP la plus petite par exemple), ainsi que ses fallbacks (en essayant par IP croissante) ou implémenter un routage basé sur un algo de consistent hashing

+2 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte