Architektur für verteilte Arbeiter

7

Wir erstellen eine Website, die Aufgaben auf mehrere geografische Standorte verteilen kann. Die Website sollte in der Lage sein:

  • Erstellen Sie eine Aufgabe,
  • setze es in eine Warteschlange,
  • Ordnen Sie sie einem Mitarbeiter je nach geografischen Kriterien zu,
  • Aktualisieren Sie die Weboberfläche entsprechend dem Arbeitsstatus (Schritt 1, 2 3 usw.),
  • Speichern Sie das Endergebnis in mongodb und beachten Sie die Webschnittstelle.

Wir können parallel arbeiten, solange sie nicht dieselben geographischen Kriterien haben.

Wir können einen Job löschen, solange er sich nicht im Bearbeitungsstatus befindet.

Unser aktueller Stapel ist: Angulajs - nodejs - mongodb.

Unsere erste Idee war, ein HTTP-Pooling von den entfernten Arbeitern zur mongodb-Aufgabe zu machen. Der Punkt ist, dass wir mehr als 20 entfernte Arbeiter haben werden und wir möchten eine Hochfrequenz-Aktualisierung (& lt; 1s). Wir denken, dass diese Lösung leicht zu implementieren ist, aber schwer zu warten ist und eine Überlastung der Datenbank verursacht. Diese Lösung hängt stark vom Netzwerk-Ping ab.

Nach einigen Recherchen im Internet haben wir Dokumentation über rabbitMQ und das Nachrichtensystem gefunden. Dies scheint die meisten unserer Anforderungen zu erfüllen, aber ich sehe nicht, wie wir einen bestimmten Job in einer Warteschlange im Status "Anstehend" löschen können und wie wir die Aktualisierung des Aufgabenstatus problemlos durchführen können.

Wir haben auch eine Dokumentation über redis gefunden, ein KV-System im RAM. Dadurch wird das Problem gelöst, dass eine bestimmte Aufgabe in einer Warteschlange gelöscht werden kann und die Mongodb-Last reduziert wird. Wir können jedoch nicht erkennen, wie weit entfernt arbeitende Mitarbeiter die Aufgabe erledigen können. Wenn es HTTP-Pooling ist, haben wir alle Vorteile verloren.

Unsere Situation scheint ein übliches Problem zu sein und ich würde gerne wissen, was die beste Lösung ist?

    
Julio 25.03.2014, 13:42
quelle

6 Antworten

3

Die Architektur ist interessant und ich denke, dass Sie RabbitMQ verwenden können.

  

1. "Erstelle eine Aufgabe"

Sie können eine AMQP-Nachricht erstellen

  

2. "Stellen Sie es in eine Warteschlange"

Sie können es in eine Warteschlange oder vielleicht besser zu einem Exchange

setzen
  

3. Weisen Sie es einem Mitarbeiter zu, abhängig von geografischen Kriterien:

Sie können das Schaufel-Plug-In verwenden und die Aufgabe mit dem Routing-Schlüssel zuweisen. Das Plug-in ist so konzipiert, dass es langsame und geografische Netzwerke toleriert.

  

4. Aktualisieren Sie das Web-Interface entsprechend dem Arbeitsstatus (Schritt 1, 2 3 usw.)

Das ist einfach, Sie können die Nachricht über den Web-Socket auf die Webseite umleiten, oder Sie können das JavaScript-Web-STOMP-Plugin "rabbitmq-plugins aktivieren rabbitmq_web_stomp" aktivieren und es direkt zum Aktualisieren des Seite.

  

5. Speichern Sie das Ergebnis in mongodb und beachten Sie die Web-Oberfläche:

Sobald Sie die Nachricht erhalten, können Sie sie in der Datenbank speichern.

Die einzigen Dinge, die nur ein bisschen schwer sind, sind das Löschen einer Nachricht, Sie könnten die Nachrichten ohne die Bestätigung erhalten, dann senden Sie die Bestätigung an die Nachricht, die Sie löschen möchten. Wie auch immer, das ist kein richtiger Weg, um RabbitMQ zu benutzen, ich kenne Ihre Umgebung nicht genau, aber Sie könnten es erwägen, die Expire-Nachricht über eine TTL-Nachricht zu verwenden ( Ссылка ).

Um eine Aufgabe zu aktualisieren, sollten Sie die Nachricht nicht in der Warteschlange aktualisieren, sondern eine andere Nachricht mit den "update" Informationen senden, dann sollte Ihre Anwendung den Aufgabenstatus beispielsweise in Ihrer internen Liste aktualisieren.

>

Ich hoffe, es kann nützlich sein.

    
Gabriele 29.03.2014, 12:40
quelle
10

Redis

Redis ist großartig, weil Sie es neben Job Queuing auch für andere Funktionen wie Caching verwenden können. Ich persönlich benutze Kue . Kueing-Jobs in Rechenzentren sind möglicherweise nicht die beste Entscheidung. Obwohl ich Ihre Umstände nicht verstehe, ist es allgemein akzeptiert, dass Ihr Datenmodell zentralisiert ist, wenn Ihre Inhalte verteilt werden. Ich betreibe einen Service, der eine API in San Fransisco hostet, und hat CDN-Knoten in San Fran und NYC. Meine Inhalte sind Server-seitige Vorlagen, Bilder, Skripte, CSS usw., die vollständig von meiner API ausgefüllt werden können.

outsourcen

Wenn Sie diese Funktionalität unbedingt benötigen, würde ich iron.io persönlich empfehlen. Sie bieten 2 Dienste an, die Ihr Problem möglicherweise lösen können. Erstens bieten sie ein MQ-System über eine REST-konforme API, die sehr einfach zu verwenden ist und perfekt mit Knoten funktioniert. Sie bieten außerdem einen Worker-Dienst, mit dem Sie Aufgaben auf ihrem Stack in die Warteschlange stellen, planen und ausführen können. Dies wäre begrenzt, wenn Sie auf Ressourcen aus Ihrer eigenen Cloud zugreifen müssten. In diesem Fall würde ich ironMQ empfehlen.

Insource

Wenn Sie Ihren Service nicht auslagern möchten und einen MQ hosten möchten, würde ich rabbitMQ nicht für Job-Queuing empfehlen. Ich würde etwas wie beanstalkd empfehlen, das mehr auf job queuing ausgerichtet ist, wo RabbitMQ mehr ist ausgerichtet auf Nachrichtenwarteschlange (wer hat das schon gehört?).

Zusätzlich:

Nachdem ich einige der Kommentare zu einigen anderen Antworten gelesen habe, scheint mir Bohnenstange der beste Ansatz zu sein. Es ist spezifischer für Job-Queuing, während viele andere MQ-Systeme Nachrichten über Updates senden und neue Daten in Ihrer Cloud in Echtzeit pushen müssen. Außerdem müssen Sie Ihr eigenes Job-Queuing-System implementieren.

    
tsturzl 30.03.2014 10:13
quelle
5

Rabbit MQ, Redis und ZeroMQ sind großartig, aber du kannst es ohne leave mongoDB machen. Es gibt spezielle Sammlungen mit dem Namen gecappte Sammlungen , die Streaming ermöglichen, und sie sind sowohl extrem schnell als auch billig, um sie zu bearbeiten für Ihre Datenbank. Sie können veranlassen, dass Ihre Mitarbeiter (oder ein anderer Prozess) die Warteschlange abhören und dann die Aufgaben ausführen.

Stellen Sie sich zum Beispiel vor, dass Sie für jede Region einen Arbeiter haben und diese Regionen mit Strings versehen sind. Dann müssen wir nur eine interne Warteschlange erstellen, um die Updates in Ihrer Hauptlogik zu verarbeiten. Wir werden mongoose und async verwenden, um es zu zeigen :

%Vor%

Vielleicht möchten Sie keine Mungose ​​oder Async verwenden oder Geoabfragen verwenden oder mehr als ein Arbeiter pro Region, aber Sie können es mit den Werkzeugen tun, die Sie bereits haben: mongoDB und Node.js

Um mit begrenzten Sammlungen zu arbeiten, verwenden Sie createCollection auf mongoDB Terminal:

%Vor%

Denken Sie nur an zwei Dinge:

  1. Daten werden basierend auf der Reihenfolge des Einfügens, nicht der Zeit oder des letzten Zugriffs auf dieses Dokument, verfallen. Ihre Sammlungen sind also groß genug.
  2. Sie können ein Dokument nicht entfernen, aber Sie können es einfach leeren
durum 31.03.2014 16:36
quelle
2

Wenn ich arbeite, verwenden wir Amazon SQS und ich kann es Ihnen sehr empfehlen. Es ist billig, zuverlässig, skaliert und spart Ihnen eine Menge Ärger (Aufrechterhaltung des Warteschlangensystems). Wir haben Arbeiter in verschiedenen Amazon Regionen auf der ganzen Welt.

Für den Knoten gibt es aws-sdk , schauen Sie hier für die Dokumentation

    
wires 27.03.2014 15:20
quelle
1

Es ist schwierig, angesichts des Umfangs Ihrer Frage nützliche Ratschläge zu geben. Aber wenn ich es wäre, würde ich wahrscheinlich ZeroMQ verwenden, ich würde einige Variationen wie Router-Req verwenden, ich Ich werde die Warteschlange und alle Daten, die mit der Arbeit auf dem Server verbunden sind, verwalten und die Aufgaben, die ich bereit war, an arbeitswillige Arbeiter weitergeben, mit dem Wissen, dass sie sofort mit der Arbeit beginnen, sobald sie sie erhalten Die einzigen Daten, die ich an den Server zurückmelden muss, sind abgeschlossene Arbeiten. Wenn Sie die Work-in-Progress-Funktion abbrechen möchten, können Sie ein zweites Socket-Paar für die Steuerkommunikation verwenden, möglicherweise eine Paar-Neu-Paarung.

Die Socket-Muster sind im verlinkten Handbuch vollständig beschrieben, und sie werden sie viel besser beschreiben, als ich hier verwenden kann, obwohl es sich um einen größeren Lesevorgang handelt.

    
Jason 28.03.2014 19:37
quelle
0

Das Modul Ссылка macht verteiltes Messaging durch die Wiederverwendung der EventEmitter-API und der STOMP-Broker sehr einfach. Sicherlich wird es Ihnen in Ihrer Messaging-Architektur sehr helfen.

    
quelle

Tags und Links