Le céleri parallèle distribué tâche avec le multitraitement
J'ai un CPU intensive de Céleri tâche. Je voudrais utiliser toute la puissance de traitement (cœurs) sur beaucoup d'instances EC2 pour faire ce travail plus rapide (céleri parallèle distribué tâche avec le multitraitement - je pense que).
Les termes, filetage, multitraitement, de calcul distribué, traitement distribué parallèle sont tous des termes que je suis en train d'essayer de mieux comprendre.
Exemple de tâche:
@app.task
for item in list_of_millions_of_ids:
id = item # do some long complicated equation here very CPU heavy!!!!!!!
database.objects(newid=id).save()
À l'aide du code ci-dessus (avec un exemple si possible) comment il y a distribué cette tâche à l'aide de Céleri en permettant à celle-ci la tâche de diviser jusqu'à utiliser toute la puissance de calcul du CPU de puissance dans l'ensemble de la machine dans le cloud?
- Je pensais que MapReduce a été conçu pour votre type de demande à l'esprit: console.aws.amazon.com/elasticmapreduce/vnext/...:
Vous devez vous connecter pour publier un commentaire.
Vos objectifs sont:
informatique/traitement distribué parallèle)
(multitraitement/threading)
Le céleri peut faire les deux pour vous assez facilement. La première chose à comprendre est que chaque céleri travailleur est configuré par défaut pour exécuter de nombreuses tâches comme il y a de cœurs de processeurs disponibles sur un système:
Cela signifie que chaque individu tâche n'a pas besoin de s'inquiéter à propos de l'utilisation du multitraitement/filetage de rendre l'utilisation de plusieurs Processeurs/cœurs. Au lieu de cela, le céleri sera exécuté assez de tâches simultanément à utiliser chaque PROCESSEUR disponible.
Avec cela de la façon, la prochaine étape est de créer une tâche qui gère le traitement des sous-ensembles de votre
list_of_millions_of_ids
. Vous avez deux options ici est d'avoir chaque tâche de gérer un ID unique, de sorte que vous exécutez N tâches, oùN == len(list_of_millions_of_ids)
. Cela permettra de garantir que le travail est répartie uniformément entre toutes vos tâches, car il ne sera jamais le cas où un travailleur se termine tôt et est juste en attente; si elle a besoin de travail, il peut extraire l'id de la file d'attente. Vous pouvez le faire (comme mentionné par John Doe) à l'aide de l'un de célerigroup
.tasks.py:
Et d'exécuter les tâches:
Une autre option est de briser la liste en petits morceaux, et de distribuer les pièces de vos travailleurs. Cette approche risque de perdre quelques cycles, parce que vous pouvez vous retrouver avec certains travailleurs attente autour tandis que d'autres sont encore en train de faire le travail. Cependant, la le céleri notes de documentation que cette préoccupation est souvent infondées:
Vous pouvez trouver que la segmentation de la liste et de distribuer les morceaux de chaque tâche est plus performante, en raison de la réduction de messagerie frais généraux. Vous pouvez probablement aussi d'alléger la charge sur la base de données un peu de cette façon, en calculant pour chaque id, de les stocker dans une liste, puis en ajoutant l'ensemble de la liste dans la base une fois que vous avez terminé, plutôt que de le faire une id à la fois. Le chunking approche devrait ressembler à quelque chose comme ceci
tasks.py:
Et pour démarrer les tâches:
Vous pouvez expérimenter un peu avec ce que chunking taille vous donne le meilleur résultat. Vous souhaitez trouver un sweet spot où vous êtes à la coupe de messagerie frais généraux, tout en gardant la taille assez petit pour que vous ne finissent pas avec les travailleurs de la fin de leurs morceau beaucoup plus rapidement qu'un autre travailleur, et puis juste attendre et ne rien faire.
threading
oumultiprocessing
. Au lieu de cela, chacun de nous a le céleri travailleur frayer autant de tâches qu'il y a des cœurs disponibles sur la machine (ce qui arrive par défaut dans le céleri). Cela signifie que dans l'ensemble de votre cluster, chaque noyau qui peut être utilisé pour le traitement de votrelist_of_million_ids
, par le fait, pour chaque tâche en utilisant un seul cœur. Ainsi, plutôt que d'avoir une seule des tâches les utiliser de nombreux cœurs, nous allons avoir beaucoup de tâches à chaque utilisation d'une base. Cela fait-il sens?threading
oumultiprocessing
". En supposant que nous ne pouvons pas diviser cette lourde tâche en plusieurs, comment voulez-vous utiliser le filetage ou le multitraitement pour obtenir le céleri à diviser la tâche entre plusieurs instances? mercimultiprocessing
de répartir le travail en place à partir de l'intérieur de la tâche elle-même, puisque les deux approches en fin de compte nécessite de faire la même chose: décomposition d'une tâche en petites tâches qui peuvent être exécutées en parallèle. Vous êtes vraiment en changeant seulement de l'endroit où vous êtes en train de faire la division.multiprocessing
à l'intérieur un Céleri tâche. Le céleri est lui-même à l'aide debilliard
(unmultiprocessing
fourche) pour l'exécution de vos tâches dans des processus séparés. Vous n'êtes pas autorisé à utiliser ensuitemultiprocessing
à l'intérieur d'eux.Dans le monde de la distribution il y a une seule chose que vous devez retenir avant tout :
Je sais que cela semble évident, mais avant de distribuer de vérifier si vous êtes en utilisant l'algorithme le mieux adapté (si elle existe...).
Cela dit, l'optimisation de la distribution est une question d'équilibre entre les 3 choses:
Ordinateurs sont faits de sorte que le plus vous vous rapprochez de votre unité de traitement (3) le plus rapide et le plus performant (1) et (2) sera. L'ordre classique de cluster sera : disque dur, réseau, disque dur, RAM, à l'intérieur de l'unité de traitement du territoire...
Aujourd'hui, les processeurs sont de plus assez sophistiquée pour être considéré comme un ensemble de matériel indépendants des unités de traitement communément appelé cœurs, ces cœurs de données de processus (3) par le biais de fils (2).
Imaginez que votre cœur est si rapide que lorsque vous envoyez des données avec un fil que vous êtes en utilisant 50% de l'alimentation de l'ordinateur, si le noyau a 2 fils vous pourrez ensuite utiliser à 100%. Deux threads par noyau est appelée hyper-threading, et votre système d'exploitation va voir les 2 Processeurs par hyper filetée de base.
La gestion des threads dans un processeur qui est communément appelé le multi-threading.
La gestion des Processeurs à partir de l'OS qui est communément appelé multi-processing.
La gestion de tâches simultanées dans un cluster qui est communément appelé la programmation parallèle.
La gestion de tâches dépendantes dans un cluster qui est communément appelé la programmation distribuée.
Alors, où est votre goulot d'étranglement ?
Ce sujet de Céleri ?
Le céleri est une messagerie cadre de la programmation distribuée, qui aura recours à un courtier module de communication (2) et un module backend pour la persistance (1), cela signifie que vous serez en mesure par la modification de la configuration d'éviter la plupart des goulots d'étranglement (si possible) sur votre réseau et uniquement sur votre réseau.
D'abord le profil de votre code pour obtenir les meilleures performances dans un seul ordinateur.
Utilisez ensuite le céleri dans votre cluster avec la configuration par défaut et définir
CELERY_RESULT_PERSISTENT=True
:Lors de l'exécution d'ouvrir votre favori des outils de surveillance, j'ai utiliser la valeur par défaut pour rabbitMQ et fleur, le céleri et le top pour les processeurs, vos résultats seront enregistrés dans votre backend. Un exemple de goulot d'étranglement du réseau des tâches de la file d'attente de plus en plus afin qu'ils de retard d'exécution, vous pouvez procéder à la modification des modules ou du céleri de configuration, si ce n'est votre goulot d'étranglement est ailleurs.
Pourquoi ne pas utiliser
group
céleri tâche pour cela?http://celery.readthedocs.org/en/latest/userguide/canvas.html#groups
Fondamentalement, vous devriez diviser
ids
en morceaux (ou gammes) et de leur donner à tout un tas de tâches dansgroup
.Pour qch plus sophistiqués, comme l'agrégation des résultats de particulier céleri tâches, je les ai utilisé avec succès
chord
tâche pour but similaire:http://celery.readthedocs.org/en/latest/userguide/canvas.html#chords
Augmentation
settings.CELERYD_CONCURRENCY
à un nombre raisonnable, et vous pouvez vous le permettre, ces le céleri travailleurs gardera l'exécution de vos tâches dans un groupe ou un accord jusqu'à ce que fait.Remarque: en raison d'un bogue dans
kombu
il y avait des problèmes avec la réutilisation des travailleurs pour le nombre élevé de tâches dans le passé, je ne sais pas si c'est corrigé maintenant. C'est peut-être, mais si pas, réduire CELERYD_MAX_TASKS_PER_CHILD.Exemple simplifié et modifié le code, je run:
summarize
obtient des résultats de tous lessingle_batch_processor
tâches. Chaque tâche s'exécute sur n'importe quel Céleri travailleur,kombu
coordonnées.Je comprends maintenant:
single_batch_processor
etsummarize
AUSSI être céleri tâches, ce n'est pas une des fonctions - sinon, bien sûr, il ne sera pas parallélisé (je ne suis même pas sûr d'accords constructeur de l'accepter si ce n'est pas un céleri tâche).chord
(avec CELERYD_CONCURRENCY ensemble à des dizaines de travailleurs == logique cpu / threads matériels) est la façon dont je traite un grand nombre de fichier journal des lots en parallèle sur plusieurs cœurs.L'ajout de plus de céleri travailleurs va certainement accélérer l'exécution de la tâche. Vous pourriez avoir un autre goulot d'étranglement: la base de données. Assurez-vous qu'il peut gérer simultanément les insertions et mises à jour.
Sujet de votre question: Vous ajoutez le céleri travailleurs par l'affectation d'un autre processus sur vos instances EC2 comme
celeryd
. En fonction du nombre de travailleurs vous avez besoin, vous pouvez ajouter encore plus de cas.