web-dev-qa-db-fra.com

Quelle est la différence entre les travailleurs et les threads à Puma

Quelle est la différence entre un travailleur de puma et un fil de puma dans le contexte d'un dyno heroku?

Ce que je sais (veuillez me corriger si je me trompe):

  • Thin n'est pas simultané, donc un processus Web ne peut faire qu'une seule demande à la fois

  • Dans Unicorn, je sais que je peux avoir plusieurs travailleurs Unicorn dans un processus pour ajouter la concurrence.

Mais chez puma il y a des fils et des ouvriers. Un ouvrier n'est-il pas un fil à l'intérieur du processus puma?

Puis-je utiliser plus de travailleurs/threads pour ajouter une concurrence Web dans Heroku?

45
Nick Ginanto

Comme l'indique l'autre réponse, cette article Herok est assez bonne avec des explications sur certains éléments de configuration.

Cependant, si vous avez besoin de régler votre application sur Heroku, ou n'importe où, il est utile de savoir comment les choses fonctionnent.

Je pense que vous avez presque raison quand vous dites "un travailleur est un thread à l'intérieur du processus puma", je crois qu'un travailleur est un processus au niveau du système d'exploitation issu de puma qui peut alors utiliser des threads en interne.

Autant que je sache - puma va bifurquer le processus de son système d'exploitation, cependant, plusieurs fois vous définissez via la configuration workers pour répondre aux requêtes http. Cela vous donne le parallélisme en termes de traitement de plusieurs demandes, mais cela prendra généralement plus de mémoire car il "copiera" votre code d'application pour chaque travailleur.

Chaque travailleur puma utilisera ensuite plusieurs threads dans son processus de système d'exploitation en fonction de la configuration threads. Ceux-ci ajoutent la concurrence en permettant au processus puma de répondre lui-même à plusieurs demandes de sorte que si un thread est bloqué, c'est-à-dire en traitant une demande, il peut gérer une nouvelle demande avec un autre thread. Comme indiqué, cela nécessite que toute votre application soit threadsafe afin que, par exemple, toute configuration globale d'une demande ne "coule" pas dans une autre.

Vous devez régler puma pour que le nombre de travailleurs soit adéquat pour le nombre de processeurs et de mémoire disponibles, puis régler les threads en fonction de la quantité que vous souhaitez saturer l'hôte exécutant votre application et du comportement de votre application - plus n'est pas toujours égal débit de demande plus rapide/plus.

38
robert_murray

C'est un grand domaine et je ne suis pas un expert, cependant ...

Puma peut générer de nombreux travailleurs et chaque travailleur peut utiliser plusieurs threads pour traiter la demande.

Pour autant que je sache, la licorne n'a pas de fils, elle a juste le modèle de travailleur.

Si vous utilisez des threads, vous devez vous assurer que votre code est thread-safe. Cela signifie Rails, tout bijou sur lequel vous comptez et votre propre code.

Pour des performances maximales, vous voudrez peut-être également examiner JRuby ou Rubinius qui ont un support de thread approprié. L'IRM est limitée par son GIL.

Il y a un bon article sur Herok qui explique comment Puma utilise les travailleurs et les threads. Vous devriez probablement lire cela et m'ignorer :)

15
jordelver

Je veux juste souligner la ligne la plus importante de l'article Heroku/Puma qui a été référencé ici:

Rails gère son propre pool de connexions à la base de données, avec un nouveau pool créé pour chaque processus de travail. Les threads au sein d'un travailleur fonctionneront sur le même pool.

Il indique que chaque travailleur aura son propre pool. Toutefois:

Les threads au sein d'un travailleur fonctionneront sur le même pool.

C'est très important de comprendre. Si un Puma Worker utilise 5 threads par travailleur, alors le fichier database.yml doit être configuré sur un pool de connexions de 5, car chaque thread peut éventuellement établir une connexion à la base de données.

Étant donné que chaque Worker est généré par un fork système (), le nouveau travailleur aura son propre ensemble de 5 threads avec lesquels travailler, et donc pour la nouvelle instance Rails créée, le database.yml sera être toujours défini sur un pool de connexions de 5.

Maintenant, le pool de connexions database.yml et votre pool de bases de données réel sont deux choses différentes. Les connexions TOTALES à votre base de données devront utiliser une formule spécifique mentionnée par les documents Heroku:

Une bonne formule pour déterminer le nombre de connexions dont chaque application aura besoin est de multiplier Rails_MAX_THREADS par WEB_CONCURRENCY.

Cela signifie que si vous utilisez 2 Workers, chacun avec 5 threads, puis 2 * 5 = 10, votre base de données doit donc être configurée pour accepter 10 connexions simultanées.

3
Donato