2010-12-08 15 views
2

Ich versuche, ein Stück Code in Java zu entwickeln, das in der Lage sein wird, große Datenmengen von JDBC-Treiber aus SQL-Datenbank abgerufen und dann in DB gespeichert.Ein Leser-Thread, ein Writer-Thread, n Worker-Threads

Ich dachte an die Erstellung eines Managers mit einem Reader-Thread, einem Writer-Thread und einer anpassbaren Anzahl von Worker-Threads, die Daten verarbeiten. Der Leser-Thread würde Daten zu DTOs lesen und sie an eine Queue weiterleiten, die als "bereit zur Verarbeitung" gekennzeichnet ist. Worker-Threads würden DTOs verarbeiten und verarbeitete Objekte in eine andere Warteschlange stellen, die als "Ready for Persistence" gekennzeichnet ist. Der Writer-Thread würde die Daten an die DB weitergeben. Ist ein solcher Ansatz optimal? Oder sollte ich vielleicht mehr Lesern erlauben, Daten zu holen? Gibt es in Java fertige Bibliotheken für solche Dinge, die mir nicht bekannt sind?

Antwort

3

Ob Ihr vorgeschlagener Ansatz optimal ist, hängt entscheidend davon ab, wie teuer die Verarbeitung der Daten im Verhältnis zu den Kosten ist, die aus der Datenbank abgerufen werden müssen, und die Ergebnisse zurück in die Datenbank zu schreiben. Wenn die Verarbeitung relativ teuer ist, kann dies gut funktionieren; Wenn dies nicht der Fall ist, führen Sie möglicherweise eine beträchtliche Menge an Komplexität mit geringem Nutzen ein (Sie erhalten immer noch Pipeline-Parallelität, die für den Gesamtdurchsatz von Bedeutung sein kann).

Die einzige Möglichkeit, sicher zu sein, ist ein Benchmark die drei Stufen getrennt, und dann auf das optimale Design zu entscheiden.

Vorausgesetzt, der Multithreading-Ansatz ist der Weg zu gehen, klingt Ihr Design mit zwei Warteschlangen sinnvoll. Eine weitere Sache, die Sie in Betracht ziehen sollten, ist die Begrenzung der Größe jeder Warteschlange.

1

Eine Alternative zur Verwendung einer expliziten Warteschlange besteht darin, über einen ExecutorService zu verfügen und Aufgaben hinzuzufügen. Auf diese Weise lassen Sie den Java-Manager den Pool von Threads.

1

Sie beschreiben etwas, das der Funktionalität ähnelt, die Spring Batch bietet. Ich würde das überprüfen, wenn ich du wäre. Ich hatte großes Glück, Operationen zu machen, die dem ähneln, was Sie beschreiben. Parallele und Multithreading-Verarbeitung und mehrere verschiedene Datenbankleser/-schreiber und eine ganze Reihe anderer Dinge werden bereitgestellt.

2

Ich höre Echos aus meiner Vergangenheit und möchte Ihnen einen anderen Ansatz anbieten, nur für den Fall, dass Sie meinen Fehler wiederholen wollen. Es kann oder kann nicht auf Ihre Situation anwendbar sein.

Sie haben geschrieben, dass Sie eine große Menge an Daten aus der Datenbank abrufen müssen und dann in der Datenbank verbleiben.

Wäre es möglich, alle externen Daten, die Sie benötigen, vorübergehend in die Datenbank einzufügen und die gesamte Verarbeitung in der Datenbank durchzuführen? Dies würde die folgenden Vorteile bieten:

  1. Es entfällt die Notwendigkeit, große Mengen an Daten
  2. es die Notwendigkeit, große Datenmengen
  3. Es mengenbasierte ermöglicht zu anhalten eliminiert zu extrahieren Verarbeitung (die Verfahrenstrifft)
  4. Wenn Ihre Datenbank dies unterstützt, können Sie die parallele Ausführung verwenden
  5. Es gibt Ihnen ein Framework (Tabellen und SQL), um Berichte über alle Fehler während des Prozesses zu erstellen.

Um ein Beispiel zu geben. Vor langer Zeit habe ich ein (Java) -Programm implementiert, dessen Zweck es war, Einkäufe, Zahlungen und zugehörige Kundendaten aus Dateien in eine zentrale Datenbank zu laden.Zu dieser Zeit (und ich bedauere es zutiefst) entwarf ich die Last, um die Transaktionen nacheinander zu verarbeiten, und führte für jedes Datenstück mehrere Datenbank-Abfragen (sql) und schließlich eine Anzahl von Einfügungen in geeignete Tabellen durch. Natürlich wurde dies nicht größer, sobald das Volumen anstieg.

Dann machte ich einen weiteren Fehler. Ich dachte, dass es die Datenbank war, die das Problem war (weil ich gehört hörte, dass die SELECT langsam ist), so entschied ich mich, alle Daten aus der Datenbank herauszuziehen und ALLE Verarbeitung in Java zu tun. Und dann behalte endlich alle Daten in der Datenbank zurück. Ich habe alle Arten von Schichten mit Callback-Mechanismen implementiert, um den Ladeprozess einfach zu erweitern, aber ich konnte einfach nicht erreichen, dass es gut funktioniert.

Wenn ich in den Rückspiegel schaue, hätte ich die (lächerlich kleine Menge) 100.000 Zeilen provisorisch in eine Tabelle einfügen und von dort verarbeiten sollen. Was fast einen halben Tag in Anspruch nahm, hätte höchstens ein paar Minuten gedauert, wenn ich mit der Stärke aller mir zur Verfügung stehenden Technologien gespielt hätte.

1

Springcharge verwenden! Genau das brauchen Sie

Verwandte Themen