web-dev-qa-db-fra.com

Conception du système: serveur de chat évolutif

Supposons que vous ayez demandé de concevoir un serveur de discussion évolutif avec les exigences suivantes:

  1. Le principal cas d'utilisation est le suivant: Le joueur A voit B en ligne, un envoie un message à B, B le reçoit.
  2. Le boîtier d'utilisation secondaire est: le joueur A voit b hors ligne , a envoie un message à B. Lorsque B revient en ligne, B reçoit le message. (Pas de notifications push).
  3. L'objectif est de minimiser la latence. La vitesse compte.
  4. Les messages devraient arriver dans l'ordre. Nous ne pouvons pas perdre de messages, mais recevoir des doublons de temps en temps c'est bien.
  5. Juste des données texte, aucune donnée binaire.
  6. Pas besoin de stocker l'historique de discussion. Une fois envoyé, les messages peuvent être détruits.

J'ai lu cet article: Comment la Société des légendes a échoué à la discussion à 70 millions de joueurs et je pense avoir manqué l'architecture principale qu'ils utilisaient dans le jeu. Mais de toute façon voici mon "processus de pensée". Quelqu'un peut-il regarder un coup d'oeil?

  • Si l'étui d'utilisation secondaire n'existait pas, je n'aurais pas à stocker quoi que ce soit. Je pense que je pourrais utiliser un réseau P2P, dans lequel un utilisateur envoie régulièrement un message Ping "Je suis en ligne" à tous ses amis en notifiant la présence.
  • Mais puisque je dois stocker des messages pour pouvoir les livrer plus tard, j'ai besoin de mes propres serveurs qui stockent la présence de l'utilisateur, les listes d'amitié des utilisateurs et les messages.
  • L'objectif de la latence minimisée peut être obtenu en plaçant des serveurs proches des utilisateurs. Cela signifie qu'il y aura plus d'un serveur afin de pouvoir rester en synchronisation. De plus, nous devons les charger de l'équilibre afin qu'un serveur ne stocke pas tout.
  • J'ai lu quelque part sur Internet qu'un moyen de charger la balance des serveurs est d'attribuer un serveur à chaque utilisateur. Donc, par exemple, Server 1 est attribué tout ce qui concerne l'utilisateur A, et Server 2 est attribué tout ce qui concerne l'utilisateur B. Nous pourrions décider de cette proximité.
  • Lorsqu'un envoi de quelque chose à B, il doit y avoir un moyen de dépêcher le message au serveur 2. Peut-être utiliser un bus de service pour communiquer des serveurs.
  • Donc, le flux serait quelque chose comme ça:

    1. Un message écrit "Bonjour B!"
    2. Server 1 reçoit un message et B. Étant donné qu'il ne trouve pas B dans sa base d'utilisateurs, il transfère le message au bus de service. Il stocke une copie du message.
    3. Le bus de service demande à tous les serveurs de rechercher l'utilisateur B.
    4. Le serveur 2 répond qu'il a B dans sa base d'utilisateurs.
    5. Le serveur 2 reçoit le message et le stocke.
    6. Server 2 envoie un message à l'utilisateur B.
    7. Server 2 signaux au bus de service que le message a été envoyé. Il détruit le message.
    8. Le serveur 1 détruit sa copie du message.
  • Si B était hors ligne, tout jusqu'à l'étape 5 resterait la même chose. La différence est que le serveur 1 peut détruire sa copie du message mais le serveur 2 ne peut pas.

  • Maintenant, stockage ... Je suppose que chaque serveur devrait avoir son propre stockage persistant, mais je ne sais pas ce qui devrait être optimisé ici (vitesse des lectures? Vitesse d'écrivies?). En outre, je ne sais pas si un magasin MySQL ou un magasin NOSQL serait mieux. Puisque NOSQL est optimisé pour être partitionné et il n'y a pas besoin ici, je suppose que mysql suffirait.
  • Si un serveur se bloque, nous avons besoin d'un moyen de basculer rapidement. Je suppose que nous pouvions placer comme un serveur "primaire" et "secondaire" à chaque emplacement, le primaire serait connecté au stockage primaire et aux données secondaires aux données répliquées.

Donc, l'architecture globale ressemblerait à ceci:

architecture

Je me rends compte que je manque beaucoup beaucoup de choses ici, ai-je manqué quelque chose d'évident? Y a-t-il une partie de mon processus de pensée tout simplement faux?

6

Vous CAN Utilisez un réseau P2P, mais il est architecturalement intéressant.

En utilisant quelque chose comme Kademlia en tant que DHT pour la découverte de pairs signifie parler à un nombre limité de nœuds avant d'atteindre votre cible. Si vous avez enregistré votre message à chacun de ces sauts, vous auriez une redondance pour votre magasin de messages qui peut être suffisamment fiable pour vos besoins. La livraison hors ligne signifierait des tentatives de transfert périodique pour chaque message tamponné. Cela garantirait une latence assez faible en termes de découverte de pairs, qui est probablement la partie la plus coûteuse du problème.

Une fois qu'une connexion P2P directe est établie, vous êtes clairement en mode en ligne et vous pouvez ignorer le stockage hors ligne (ou non).

Vous pouvez également exécuter des nœuds qui stockent de manière persistante les messages, mais agissent comme des participants DHT réguliers. Cela donnerait plus de fiabilité, au prix d'exécution d'une poignée de nœuds.

Comme @Aridlehoover écrit, cependant, il y a tellement de réponses possibles que vous ne pouvez pas vraiment fournir une dernière.

1
Jens Finkhaeuser

Je concevrais cela dans le nuage et utiliserais quelque chose comme MongoDb ou Azure Cosmos DB. La hausse est que la base de données gère la mise à l'échelle du côté des données, de sorte que vous n'avez pas à vous en soucier.

Tout ce qui serait laissé, c'est écrire une API Web au-dessus du magasin de données que vous avez choisi et, comme cela pourrait également être basé sur le cloud, votre fournisseur de cloud pourrait traiter automatiquement la mise à l'échelle des demandes.

Si le nuage n'est pas une option pour une raison quelconque (ne peut penser à aucun moment), vous réalisez que les deux plates-formes de base de données sont également hébergées sur place. Cela vous laisserait la mise à l'échelle de l'API Web, qui peut être faite facilement avec des conteneurs et quelque chose comme Kubernettes, que BTW serait également ma recommandation d'héberger la plate-forme de base de données elle-même.

0