Supposons que nous ayons une application erlang qui implique des milliers de processus. Supposons qu'il y ait une seule ressource X qui peut être un tuple, une liste, ou tout autre terme erlang, que tous ces processus peuvent avoir besoin de lire/extraire quelque chose, à tout moment.
Un exemple d'une telle occurrence, disons, un système d'API, dans lequel les processus client peuvent avoir besoin de lire et d'écrire sur une machine distante. Ant il arrive que vous ne voulez pas, pour chaque demande de lecture/écriture, une nouvelle connexion à créer. Donc, ce que vous faites, vous créez un pool de connexions, considérez-les comme un pool de canaux/sockets/canaux ouverts.
Maintenant, ce pool de ressources doit être partagé par des milliers de processus de sorte que, pour chaque demande de lecture ou d'écriture, vous souhaitiez que ce processus récupère tout canal/ressource ouvert disponible. La question est, et si j'ai un processus (un seul processus) détenir cette information, que ce soit dans son dictionnaire de processus ou dans sa boucle de réception. Cela signifierait que tous les processus devraient envoyer un message à ce processus chaque fois qu'ils ont besoin d'une ressource gratuite. Ce processus unique aurait une énorme boîte aux lettres à tout moment en raison de la forte demande pour cette seule ressource.
OU Je pourrais utiliser une table ETS et avoir une seule ligne, disons #resources{key=pool,value= List_of_openSockets_or_channels}
. Mais cela signifierait que tous nos processus tenteraient de faire une lecture à partir de la table ETS pour la même ligne à (probabilité élevée) les mêmes instants instantanés.
Comment la table ETS gérerait-elle, si 10 000 processus atttempt une lecture, pour la même ligne/enregistrement de lui, en même temps/à peu près au même moment? et pourtant, si j'utilise un processus, sa boîte aux lettres, si 10 000 processus lui envoient un message, en même temps, pour la même ressource (et qu'il faudrait répondre à chaque demandeur). Et rappelez-vous que cette action peut se produire si souvent. Quelle option (dis-concernant les problèmes de disponibilité du processus descendant bla bla), fournirait un débit plus élevé, de sorte que les processus obtiendraient ce dont ils ont besoin plus rapidement?
Existe-t-il un autre meilleur moyen de gérer les structures de données à forte demande dans la machine virtuelle Erlang de manière à fournir un accès très rapide à des millions de processus, même s'ils ont tous besoin de cette ressource?Débit de récupération de données - Recherche ETS par rapport à la messagerie inter-processus
Répondre
Réponse courte: profil. Essayez différentes approches et vérifiez le comportement de votre système.
Tout d'abord, je regarderais l'option {read_concurrency, true}
d'ETS. De the documentation:
{read_concurrency, Boolean()} Réglage des performances. La valeur par défaut est false. Lorsque cette propriété est définie sur true, la table est optimisée pour les opérations de lecture simultanées . Lorsque cette option est activée sur un système d'exécution avec le support SMP , les opérations de lecture deviennent beaucoup moins coûteuses; en particulier sur les systèmes avec plusieurs processeurs physiques. Cependant, la commutation entre les opérations d'écriture en lecture et devient plus coûteuse. Vous voulez généralement activer cette option lorsque les opérations de lecture simultanées sont beaucoup plus fréquentes que les opérations d'écriture ou lorsque les lectures et écritures simultanées sont en grandes lectures et écritures (c'est-à-dire beaucoup de lectures non interrompues par écritures, et beaucoup de écrit non interrompu par des lectures). En général, ne souhaite pas activer cette option lorsque le modèle d'accès commun correspond à quelques opérations de lecture entrelacées avec quelques opérations d'écriture répétées. Dans ce cas, vous obtiendrez une dégradation des performances en activant cette option . L'option read_concurrency peut être combinée avec l'option write_concurrency.Vous souhaitez généralement les combiner lorsque de grandes rafales de lecture simultanées et de grandes rafales d'écriture simultanées sont commun.
Deuxièmement, je regarderais cache possibilités. Les processus lisent-ils cette information une seule fois ou plusieurs fois? S'ils y accèdent plusieurs fois, vous pouvez le lire une fois et le stocker dans votre état de processus. Troisièmement, vous pouvez essayer de répliquer et distribuer cette information à travers votre système. Divide et impera.
merci @Roberto –
Si vous utilisez l'approche de processus, afin d'éviter que toutes les demandes de lecture sérialisées dans la file d'attente de messages du processus 'serveur', doivent être répliquées. Utiliser une table ETS avec read_concurrency
me semble plus naturel et c'est quelque chose que j'ai utilisé lors du développement de la version parallèle de Dialyzer. Cependant, l'accès ETS n'a jamais été un goulot d'étranglement dans ce cas.
Merci @aronisstav –
- 1. Performances de la récupération des données de base par rapport à la recherche de disque
- 2. JSONPath - Débit par rapport Goessner
- 3. Recherche de données Ember par rapport à la charge
- 4. Jmeter: Rapport de synthèse: Débit
- 5. Recherche de données de base par rapport à Plist
- 6. Récupération des données de la file d'attente de messagerie
- 7. Stockage dans la session par rapport à la récupération de la base de données
- 8. Calcul du débit dans jmeter par rapport au rapport agrégé
- 9. Composant de messagerie par rapport à PHPMailer avec cakePHP
- 10. Recherche de fichier() par rapport à playbook
- 11. Édition de la mémoire interprocessus - Recherche d'adresses modifiées
- 12. dessine un graphique du débit binaire codé de la vidéo par rapport à l'emplacement de lecture
- 13. ets: Erreur dans ets (timeseries, model = "MAM"): données non-saisonnières
- 14. PHP Recherche plusieurs mots dans la requête par rapport à la table de base de données
- 15. Recherche de dates manquantes par rapport à la période
- 16. Enum par rapport à la table de recherche
- 17. Recherche par texte et récupération de l'ID
- 18. Valeur de débit dans le rapport agrégé
- 19. JqGrid Options de recherche: recherche d'outils par rapport à la fenêtre de recherche standard
- 20. Débit de données NodeJS
- 21. Récupération des données de la requête dans la recherche élastique
- 22. Modélisation de la messagerie unifiée: Classe d'analyse (classe de limite par rapport à classe de contrôle)
- 23. Comment filtrer la table ETS sans ets: sélectionnez
- 24. Récupération asynchrone par rapport à plusieurs données de base de contexte d'objet géré qui est préférable?
- 25. efficacité de la recherche binaire par rapport à l'efficacité de la recherche linéaire Fortran
- 26. Question de conception Recherche d'enregistrements actifs par rapport à la recherche de Javascript
- 27. Récupération de l'ID de messagerie dans Connexion à Facebook?
- 28. Arbre de recherche binaire par rapport à un MultiMap
- 29. Récupération d'éléments d'un tableau par rapport à un paramètre cumulatif
- 30. Recherche par rapport à un attribut virtuel
Dans d'autres langues, peut-être, ce serait dans une variable globale. –
Je suppose que vous avez déjà joué avec l'option ''{read_concurrency, true}' d'ETS? Si vous n'avez pas beaucoup de commutateurs entre les opérations de lecture et d'écriture, cela pourrait aider. –
merci @Robert, j'ai déjà regardé cette option, mais, voyez-vous, j'ai un problème de comparaison entre 'ETS' et' Process messaging'. Comment expliquez-vous les deux? Certainement, l'un d'entre eux peut être une meilleure option, mais, théoriquement, avant de faire des tests, comment pensez-vous que chacun se comporte, compte tenu de votre expérience en erlang? –