370 votes

Le nombre de threads est trop ?

Je suis en train d'écrire un serveur, et je branche chaque action dans un thread lorsque la demande est entrant. Je le fais parce que presque chaque requête est une requête de base de données. Je suis à l'aide d'un pool de threads de la bibliothèque de couper vers le bas sur la construction/destruction de threads.

Ma question est - ce qui est un bon point de coupure pour les I/O fils comme ceux-ci? Je sais que c'était juste une estimation approximative, mais sommes-nous parler des centaines? des milliers?


EDIT:

Merci à tous pour vos réponses, il me semble que je vais juste avoir à le tester afin de savoir mon nombre de threads plafond. La question est: comment savoir si j'ai atteint ce plafond? Exactement ce que dois-je mesurer?

255voto

paxdiablo Points 341644

Certains pourraient dire que les deux threads est trop, je ne suis pas tout à fait dans ce camp :-)

Voici mon conseil: mesurez, n'essayez pas de deviner. Une suggestion est de le rendre configurable et initialement fixé à 100, puis relâchez votre logiciel à l'état sauvage et de surveiller ce qui se passe.

Si votre utilisation du thread des pics à 3, puis à 100, c'est trop. Si elle reste à 100 pour la plupart de la journée, elle bosse jusqu'à 200 et de voir ce qui se passe.

Vous pourrait en fait avoir votre code d'utilisation du moniteur et ajustez la configuration pour la prochaine fois qu'il démarre, mais c'est probablement excessif.


Pour clarifier et préciser:

Je ne dis pas rouler votre propre thread sous-système de mise en commun, par tous les moyens d'utiliser celui que vous avez. Mais, puisque vous posiez des questions sur un bon point de coupure pour les threads, je suppose que votre pool de threads mise en oeuvre a la possibilité de limiter le nombre maximal de threads créés (ce qui est une bonne chose).

J'ai écrit fil et la connexion à la base groupement de code et ils ont les caractéristiques suivantes (qui, je crois, sont essentielles pour la performance):

  • un nombre minimum de threads actifs.
  • un nombre maximal de threads.
  • l'arrêt de threads qui n'ont pas été utilisés pendant un certain temps.

La première établit une base de référence pour les performances minimales en termes de pool de threads client (nombre de threads est toujours disponible pour une utilisation). La seconde définit une restriction sur l'utilisation des ressources par les threads actifs. La troisième renvoie à la ligne de base dans le calme et le temps de façon à minimiser l'utilisation des ressources.

Vous avez besoin d'équilibrer l'utilisation des ressources de l'avoir inutilisés threads (Un) contre l'utilisation de la ressource de ne pas avoir assez de fils pour faire le travail (B).

(A) est généralement l'utilisation de la mémoire (les piles et ainsi de suite) depuis un thread ne faire aucun travail ne sera pas en utilisant une grande partie de la CPU. (B) sera généralement un retard dans le traitement des demandes qu'ils arrivent comme vous avez besoin d'attendre pour un thread pour devenir disponible.

C'est pourquoi vous mesurer. Comme vous le dites, la grande majorité de vos fils seront en attente d'une réponse de la base de données de sorte qu'ils ne seront pas en cours d'exécution. Il y a deux facteurs qui influent sur le nombre de threads que vous devrait permettre un.

La première est le nombre de DB connexions disponibles. Cela peut être une dure limite, sauf si vous pouvez l'augmenter au SGBD - je vais supposer que votre SGBD peut prendre un nombre illimité de connexions dans ce cas (bien que vous devriez idéalement être en mesure de que ainsi).

Ensuite, le nombre de threads, vous devez avoir dépend de votre utilisation historique. Le minimum que vous devriez avoir en cours d'exécution est le nombre minimum que vous avez jamais eu de course +%, avec un minimum absolu de (par exemple, et de le rendre configurable comme Une) 5.

Le nombre maximal de threads doit être votre historique de maximum + B%.

Vous devez également être suivi par des changements de comportement. Si, pour quelque raison, de l'utilisation à 100% de disponible pour un temps significatif (de sorte qu'il aurait une incidence sur les performances des clients), vous devez remonter le maximum autorisé jusqu'à ce qu'il est, une fois encore, B% plus élevé.


En réponse à la "exactement ce que dois-je mesurer?" question:

Ce que vous devez mesurer plus précisément, c'est le montant maximal de threads dans l'utilisation concomitante (p. ex., en attente sur un retour de la DB appel) sous la charge. Puis ajouter un facteur de sécurité de 10% par exemple (souligné, puisque d'autres affiches semblent prendre mes exemples fixe des recommandations).

En outre, cela devrait être fait dans l'environnement de production pour le réglage. Il est normal d'obtenir une estimation à l'avance, mais vous ne savez jamais ce que la production de jeter votre chemin (c'est pourquoi toutes ces choses doit être configurable à l'exécution). C'est d'attraper une situation inattendue doublement de la client appels entrant.

43voto

Jay D Points 1670

Cette question a été évoquée tout à fait à fond et je n'ai pas eu la chance de lire toutes les réponses. Mais voici quelques choses à prendre en considération lors de la recherche à la limite supérieure sur le nombre de threads simultanés qui peuvent co-exister pacifiquement dans un système donné.

  1. La Taille de la Pile : Dans Linux par défaut la taille de la pile est de 8 mo (vous pouvez utiliser ulimit-a la trouver).
  2. Max de mémoire Virtuelle que l'OS variante prend en charge. Noyau Linux 2.4 prend en charge un espace d'adressage de mémoire de 2 GO. avec le Noyau 2.6 , j'ai un peu plus grand (3 GO )
  3. [1] montre les calculs pour le nombre maximum de threads par donnée Max VM pris en charge. 2.4 il s'avère être d'environ 255 threads. pour 2.6 le nombre est un peu plus grand.
  4. Ce kindda noyau planificateur, vous avez . En comparant le noyau Linux 2.4 planificateur de 2,6 , le plus tard vous donne un O(1) planification avec pas de dépendance sur le nombre de tâches existantes dans un système alors que la première est plus de O(n). Aussi, les SMP Capacités du noyau de l'annexe également jouer un bon rôle dans nombre max de durable threads dans un système.

Maintenant, vous pouvez régler la taille de votre tapis d'intégrer plus de threads, mais alors vous devez prendre en compte les frais généraux de la gestion des threads(création/destruction et de la planification). Vous pouvez appliquer de l'Affinité CPU d'un processus et un thread donné pour les amarrer à des Cpu spécifiques pour éviter la migration de thread frais généraux entre les Processeurs et d'éviter le froid de trésorerie questions.

Notez que l'on peut créer des milliers de threads à sa volonté , mais quand Linux est à court de VM juste au hasard commence à tuer les processus (et donc de threads). C'est pour garder l'utilitaire de profil à partir de l'être au maximum. (La fonction d'utilité raconte l'échelle du système de l'utilitaire pour une quantité donnée de ressources. Avec un taux constant de ressources dans ce cas, les Cycles CPU et de la Mémoire, de l'utilité de la courbe s'aplatit avec le nombre de plus en plus de tâches ).

Je suis sûr noyau de windows planificateur aussi fait quelque chose de ce genre à traiter au cours de l'utilisation des ressources

[1] http://adywicaksono.wordpress.com/2007/07/10/i-can-not-create-more-than-255-threads-on-linux-what-is-the-solutions/

19voto

Andrew Grant Points 35305

Si vos fils sont à effectuer n'importe quel type de ressources à forte intensité de travail (CPU/Disque), alors vous aurez rarement vu des avantages au-delà de un ou deux, et beaucoup trop de va tuer des performances très rapidement.

Le "meilleur des cas" est que plus tard votre threads de décrochage tandis que les premiers complète, ou certains auront une faible surcharge des blocs sur les ressources avec des bas de contention. Le pire des cas, c'est que vous commencez à agiter le cache/disque/réseau et de votre débit global baisse à travers le plancher.

Une bonne solution est de faire des demandes dans une piscine qui sont ensuite envoyés vers les threads de travail à partir d'un thread-piscine (et oui, en évitant de fil continu de création/destruction est une grande première étape).

Le nombre de threads actifs dans cette piscine peut ensuite être modifié et mis à l'échelle sur la base des conclusions de votre profilage, le matériel que vous exécutez, et d'autres choses qui peuvent se produire sur la machine.

12voto

Chad Okere Points 3181

Une chose vous devriez garder à l’esprit est que python (au moins la version C basé) utilise ce qu’on appelle un verrou global interprète qui peut avoir un énorme impact sur les performances sur les machines de mult-core.

Si vous devez vraiment le meilleur parti de python multithread, vous pouvez envisager d’utiliser Jython ou quelque chose.

9voto

bortzmeyer Points 12246

Comme Pax dit à juste titre, de mesurer, de ne pas le deviner. Que ce que j'ai fait pour DNSwitness et les résultats ont été surprenants: l'idéal nombre de threads a été beaucoup plus élevé que ce que je pensais, quelque chose comme 15 000 de threads pour obtenir les résultats les plus rapides.

Bien sûr, cela dépend de beaucoup de choses, c'est pourquoi vous devez vous mesurer.

Mesures (en français seulement) dans combien doit de fils d'exécution ?.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X