Spring Batch : Tasklet mit multi-threaded Testamentsvollstrecker hat sehr schlechte Leistungen im Zusammenhang Drosselung Algorithmus
Mit Spring batch 2.2.1 habe ich konfiguriert und Spring Batch Job, ich habe diesen Ansatz:
Konfiguration ist folgende:
-
Tasklet verwendet ThreadPoolTaskExecutor begrenzt auf 15 threads
-
Drossel-limit ist gleich der Anzahl der threads
-
Chunk verwendet wird, mit:
-
1 synchronisiert adapter von JdbcCursorItemReader, um es zu ermöglichen die Nutzung von vielen threads als pro Spring Batch Dokumentation Empfehlung
Können Sie Sie synchronisieren Aufruf von read() und so lange, wie die Verarbeitung und das schreiben ist der teuerste Teil der chunk Ihrem Schritt können noch abgeschlossen viel schneller als in einem single-threaded-Konfiguration.
-
saveState ist falsch auf JdbcCursorItemReader
-
Einer Benutzerdefinierten ItemWriter basierend auf JPA. Beachten Sie, dass die Verarbeitung eines Elements kann variieren in Bezug auf die Bearbeitungszeit, es kann paar millis zu wenigen Sekunden ( > 60).
-
commit-interval auf 1 gesetzt (ich weiß, es könnte besser sein, aber es ist nicht das Problem)
-
-
Alle jdbc-pools sind in Ordnung, in Bezug auf Spring Batch doc Empfehlung
Ausführen der batch führt zu sehr seltsamen und schlechten Ergebnissen aufgrund der folgenden:
- an irgendeinem Schritt wird, wenn die Gegenstände einige Zeit dauern, zu verarbeiten, indem ein Schriftsteller, fast alle threads im thread-pool am Ende gar nichts tun, anstatt der Verarbeitung, nur die langsame Schriftsteller arbeitet.
Blick auf Spring Batch code, Ursache zu sein scheint, in dieses Paket ein:
- org/springframework/batch/wiederholen/support/
Ist diese Art zu arbeiten eine Funktion oder ist es eine Einschränkung/Fehler ?
Wenn es ein feature ist, was ist die Art von Konfiguration, um alle threads ohne ausgehungert durch die lange Verarbeitung die zimmerreserviereung, ohne das alles umschreiben ?
Beachten Sie, dass, wenn alle Elemente die gleiche Zeit, alles funktioniert einwandfrei und multi-threading ist OK, aber wenn einem der Artikel, die Verarbeitung braucht viel mehr Zeit, dann wird multi-threading ist fast nutzlos für die Zeit der langsame Prozess funktioniert.
Beachten, öffnete ich dieses Problem:
Du musst angemeldet sein, um einen Kommentar abzugeben.
Als Alex sagte, es scheint dieses Verhalten ein Vertrag nach javadocs von :
Betrachten:
Weitere option für Sie wäre, um die Partitionierung verwenden :
Michael Minella erklärt in Kapitel 11 seines Buches Pro Spring Batch:
Partitioner.java:
Hier ist, was ich denke, ist Los:
In anderen Worten, für diese multi-threaded-Ansatz in Spring Batch, um nützlich zu sein, jeder thread verarbeitet werden muss, in etwa die gleiche Menge an Zeit. Ihr Szenario, in dem es eine riesige Diskrepanz zwischen der Bearbeitungszeit für bestimmte Elemente, Sie erleben eine Einschränkung, wo viele Ihre threads sind abgeschlossen und warten auf eine lang andauernde Geschwister-thread zu sein, in der Lage zu bewegen auf die nächste Stück der Verarbeitung.
Mein Vorschlag:
In meinem Fall, wenn ich nicht die throttle-Grenze, dann nur 4 threads kommen in der read () - Methode der ItemReader, was auch der Standardwert für die Anzahl der threads, wenn nicht anders angegeben in tasklet-tag als pro Spring Batch Dokumentation.
Wenn ich hier mehr threads.e.g 10 oder 20 oder 100, dann nur 8 threads kommen in der read () - Methode der ItemReader
Die Grenze von 8 aktiven threads unabhängig vom Wert des Drossel-Grenze sein könnte, verursacht durch Konflikte auf Spring Batch Job-repository. Jedes mal, wenn ein chunk ist bearbeitet, ein paar Infos geschrieben in job repository. Steigern Sie Ihre pool-Größe für die Anzahl der threads, die Sie brauchen!