Java-Threads über mehrere Server verteilen?

8

Ich bin ziemlich neu in Java und genieße es wirklich, darüber zu lernen. Ich habe ein Programm erstellt, das gut funktioniert, aber ein wenig dauert, wenn ich weitere Daten für die Verarbeitung hinzufüge. Ich habe es eingefädelt und es hat es wirklich sehr beschleunigt, aber jetzt denke ich darüber nach, es schneller zu machen (offensichtlich müssen mehr Daten verarbeitet werden, je länger es dauert). Nur ein fyi, mein Programm teilt keine Daten zwischen den Threads, es bekommt ein Element einer Liste und macht etwas Mathe und lädt das Ergebnis in eine Datenbank hoch. Im Idealfall erhalten ein paar Arbeitscomputer ein paar Elemente der Liste und machen dann ihre Arbeit und bekommen dann mehr Arbeit, bis sie erledigt ist.

Ich habe ein wenig recherchiert und Warteschlangen gefunden und bin mir nicht sicher, ob es das ist, was ich brauche oder ob es da draußen noch etwas gibt (auch ich dachte, dass Integrität / Überwachung von Arbeitern zu viel für mich wäre, um es zu schreiben Neuling). Ich habe 4 Computer zu Hause (einige Linux, Mac und Windows .. aber ich kann Linux VMs auf allen nonlinux-Systemen installieren, wenn diese Lösungen os spezifisch sind) und wollte versuchen, sie dazu zu bringen, mit dieser Aufgabe zu arbeiten. Ich dachte über das Erstellen von Java-Warteschlangen nach, die die anderen Clients ein Stück nehmen und verarbeiten, aber ich sah auch Bibliotheken (rabbitmq). Ich habe auch kurz über Grid Computing nachgedacht.

Ist das der richtige Weg oder gibt es einen besseren Weg? Ich brauche keinen Code oder irgendetwas will nur wissen, was die Lösungen für das Verteilen von Threads sind oder welche Faktoren bei der Auswertung zu verwenden sind.

    
Lostsoul 02.03.2012, 15:01
quelle

4 Antworten

7

Nur zum Schluss - Sie haben bereits hochskaliert , jetzt möchten Sie horizontal skalieren . Von ganz oben:

  • : Sie können ein Java erstellen Queue Das wird automatisch über den gesamten Cluster verteilt. Im Grunde führen Sie dieselbe Anwendung mit wenigen Threads aus, die Daten aus der Warteschlange lesen. Terrakotta verteilt diese Schlange magisch, so dass sie sich wie ein lokales Objekt anfühlt.

  • - ähnliche Herangehensweise an Terracotta, verteilte Datenstrukturen und Testamentsvollstrecker

  • - senden Sie eine Nachricht mit einem Stück Arbeit in eine JMS-Warteschlange (wieder Warteschlange) und haben mehrere Listener. Jeder Listener ist mehr oder weniger ein einzelner Thread. Listener können auf verschiedenen Rechnern eingerichtet werden.

  • - Map / Reduce Java-Framework zum einfachen Skalieren große Datenmengen aus. Wird normalerweise zum Verarbeiten von Daten und zum Zusammenfassen von Ergebnissen verwendet.

Tomasz Nurkiewicz 02.03.2012, 15:08
quelle
9

Sie können JMS oder Hazelcast (z. B. verteilten ExecutorService) verwenden, um Arbeit zwischen Computern zu verteilen.

Was ich zuerst tun würde, ist, die Algorithmen zu verbessern. Sie werden vielleicht feststellen, dass Sie 2-4 Mal schneller mit 4 Maschinen arbeiten können, aber Sie können eine Leistungsverbesserung von 10-1000x durch Performance Profiling, Refactoring und Tunings erreichen, oft mit weniger Komplexität.

    
Peter Lawrey 02.03.2012 15:06
quelle
2

Im Allgemeinen ist die Verwendung einer Warteschlange (wie RabbitMQ) zum Laden von "Jobs" und das Absetzen von Jobs aus der Warteschlange für die Verarbeitung das am besten skalierbare Muster, das nicht zu viel Arbeit in Anspruch nimmt .

Sobald das vorhanden ist, können Sie die Arbeiter, die Sie brauchen, beliebig erweitern und auf alle Maschinen verteilen, die Sie benötigen.

Nachdem die allgemeine "Message Passing" -Architektur eingerichtet wurde, besteht der nächste Schritt immer darin, herauszufinden, wodurch der Prozess langsam wird. Nicht alle Probleme können gelöst werden, indem einfach mehr Threads auf eine Box oder mehrere Boxen in einem Cluster geworfen werden (viele können es jedoch).

Wenn die Jobs beispielsweise an die CPU gebunden sind, ist es nicht sinnvoll, mehr Threads auf einer einzelnen Box auszuführen als auf Kernen, auf denen sie ausgeführt werden (-1 Core, der zum Verwalten der Threads verwendet wird).

Wenn die Vorgänge jedoch festplatten- oder netzwerkgebunden sind, können diese Jobs asynchron intern erstellt werden, sodass andere Threads gestartet werden können, während der erste darauf wartet, dass der Datenträger oder das Netzwerk zurückkommt mit was es verlangt.

Letztlich ist die Message-Passing-Architektur das wichtigste Stück, und danach geht es darum, die Jobs zu optimieren und Ihre Ressourcen effizient zu nutzen, was eine genaue Kenntnis der Domäne erfordert.

Wenn Sie den Großteil der Joboptimierung durchmachen, können Sie sich Interprozess-Caching-Techniken mit schnellen Schlüsselwert-Caches wie Redis ansehen, so dass Sie Daten, die Sie immer wieder benötigen, nicht erneut berechnen.

    
cdeszaq 02.03.2012 15:09
quelle
1

Sie benötigen keine virtuelle VM, um Java auszuführen. Höchstwahrscheinlich wird Ihr Programm ohne Probleme auf allen drei Hauptbetriebssystemen laufen.

Ich würde mit der einfachsten Lösung gehen. Lassen Sie einen Masterprozess Aufgaben abrufen, verteilen sie an Arbeitscomputer, sammeln Ergebnisse und reichen sie in eine Datenbank ein.

Verbinden Sie die Computer mit Sockets. Jeder Worker kann n+1 threads umfassen, wobei n die Anzahl der CPU-Kerne auf diesem Computer ist.

    
Boris Pavlović 02.03.2012 15:07
quelle