2010-10-03 5 views
6

J'écris un logiciel qui va gérer quelques centaines small systems dans "le champ" sur une connexion intermittente 3G (ou similaire).Est-ce que le céleri convient à de nombreux petits systèmes distribués?

La base d'accueil devra envoyer des tâches aux systèmes sur le terrain (par exemple, «signaler votre état», «mettre à jour votre logiciel», etc.), et les systèmes sur le terrain devront renvoyer les tâches au système. serveur (par exemple, "une défaillance a été détectée", "voici quelques données", etc.).

J'ai passé un certain temps à Celery et il semble être un ajustement parfait: celeryd en cours d'exécution à la base de la maison pourrait recueillir des emplois pour les systèmes dans le domaine, un celeryd en cours d'exécution sur les systèmes de terrain pourrait recueillir des emplois pour les le serveur, et ces emplois pourraient être échangés lorsque les clients deviennent disponibles.

Alors, le céleri convient-il bien à ce problème? Plus précisément:

  • La majorité des tâches seront dirigées vers un travailleur individuel (par exemple, "envoyez le travail 'get_status' à 'system51'") - cela posera-t-il un problème? Est-ce qu'il gère avec élégance les conditions de réseau défavorables (comme, par exemple, les connexions meurent)?
  • Quelle fonctionnalité n'est disponible que si RabbitMQ est utilisé comme backend? (Je préfère ne pas utiliser RabbitMQ sur les systèmes de terrain)
  • Y a-t-il une autre raison pour laquelle Celery pourrait rendre ma vie difficile si je l'utilise comme je l'ai décrit?

Merci!

(il serait valable de suggérer que Céleri est exagéré, mais il y a d'autres raisons pour lesquelles il me faciliter la vie, donc je voudrais considérer)

Répondre

12

La majorité des tâches sera dirigée à un travailleur (par exemple, « envoyer le emploi « get_status » à 'system51 ») - sera-ce un problème?

Pas du tout. Créez simplement une file d'attente pour chaque travailleur, par ex.dire chaque noeud écoute une file d'attente de round robin appelé default et chaque noeud a sa propre file d'attente du nom de son nom de noeud:

(a)$ celeryd -n a.example.com -Q default,a.example.com 
(b)$ celeryd -n b.example.com -Q default,b.example.com 
(c)$ celeryd -n c.example.com -Q default,c.example.com 

Routage une tâche directement à un nœud est simple:

$ get_status.apply_async(args, kwargs, queue="a.example.com") 

ou par configuration à l'aide d'un Router:

# Always route "app.get_status" to "a.example.com" 
CELERY_ROUTES = {"app.get_status": {"queue": "a.example.com"}} 

-t-il gérer avec élégance défavorable conditions réseau (par exemple, connexions en train de mourir)?

Le travailleur récupère gracieusement des échecs de connexion de courtier. (au moins de RabbitMQ, je ne suis pas sûr de tous les autres backends, mais ce est facile à tester et corriger (il vous suffit d'ajouter Pour le client, vous pouvez toujours les exceptions liées à une liste)

une nouvelle tentative d'envoyer la tâche si la connexion est en panne, ou vous pouvez configurer HA avec RabbitMQ: http://www.rabbitmq.com/pacemaker.html

Quelle fonctionnalité est uniquement disponible si RabbitMQ est utilisé comme back-end (je préfère ne pas courir Sur les systèmes de terrain)

Les commandes de contrôle à distance, et seulement les échanges "directs" sont pris en charge (pas "topic" ou "fanout"). Mais cela sera pris en charge dans Kombu (http://github.com/ask/kombu).

Je reconsidérer sérieusement en utilisant RabbitMQ. Pourquoi pensez-vous que ce n'est pas un bon ajustement? IMHO Je ne chercherais pas ailleurs pour un système comme celui-ci, (sauf peut-être ZeroMQ si le système est transitoire et vous n'avez pas besoin de persistance de message).

Y at-il une autre raison pour laquelle Celery pourrait rendre ma vie difficile si je l'utilise comme je l'ai décrit?

Je ne peux penser à rien de ce que vous décrivez ci-dessus. Comme le modèle de simultanéité est multitraitement, il nécessite de la mémoire (je travaille sur l'ajout de la prise en charge des pools d'unités d'exécution , ce qui peut être utile dans certains cas).

il serait valable de suggérer que Céleri est surpuissant, mais il y a d'autres raisons que cela rendrait ma vie plus facile, donc je voudrais considérer)

Dans ce cas, je pense que tu utilises le mot overkill à la légère. Cela dépend vraiment de la quantité de code et de tests dont vous avez besoin pour écrire sans lui. Je pense qu'il est préférable d'améliorer une solution générale déjà existante, et en théorie, il semble comme cela devrait bien fonctionner pour votre application.

+0

* Pourquoi pensez-vous que [RabbitMQ n'est pas] un bon choix? * Parce que mon Erlang + RabbitMQ foo est faible, et ce serait encore une chose que je devrais construire + configurer + maintenir sur les systèmes de terrain, mais ils aura déjà Python + SQLite sur eux. –

+0

* Mais cela sera pris en charge dans Kombu (http://github.com/ask/kombu)* cool - Je vais vérifier Kombu. * Dans ce cas, je pense que vous utilisez le mot overkill à la légère ... * true - J'ai surtout ajouté que parce que l'une de mes plus grandes bêtes noires sur StackOverflow est la réponse "vous le faites mal, vous devriez le faire autrement". Génial, merci beaucoup pour votre aide. –

+2

Je vous le promets, RabbitMQ est vraiment facile à installer et à entretenir. C'est quelque chose que j'installe et que j'oublie ensuite. – asksol

1

je ne serais probablement mis en place un (django) service Web pour accepter les demandes. Le service Web pourrait faire le travail de valider les demandes et de détourner les mauvaises demandes. Alors le céleri peut juste faire le travail.

Cela nécessiterait que les périphériques distants interrogent le service Web pour voir si leurs travaux ont été effectués. Cela peut ou non être approprié, selon ce que vous faites exactement.

+0

Je l'avais considéré, mais je préfèrerais éviter d'interroger si possible; Dans certaines circonstances, la communication en temps réel serait très agréable à utiliser, et les sondages pourraient coûter cher si je payais par la KB pour des données 3D. –

Questions connexes