Für das gleichzeitige Verarbeiten mehrerer MSCONS-Dateien, wurde nach Wegen zur Parallelisierung gesucht unter Berücksichtigung der Lauffähigkeit der Umgebung.

Ausgangssituation

Als Ausgangslage für die Parallelisierung, wurde ein Prozess gewählt der den Nachrichtenaustausch zwischen zwei Unternehmen mittels Dateitransfer realisiert, wobei Datei mehrere Nachrichten enthalten kann (siehe Abbildung). Aus der Abbildung werden auch die verschiedenen verwendeten Technologieschichten ersichtlich.


Die Datei wird im EDI-Format übermittelt. EDI ist ein Branchen-übergreifendes Standardformat zum elektronischen Datenaustausch zwischen Geschäftspartnern. Die SOA kann dieses Format nicht interpretieren, aus diesem Grund muss die Datei im ersten Schritt in ein verarbeitbares Format überführt werden. Im zweiten Prozess der Verarbeitbarkeitsprüfung wird jede Nachricht aus der Datei einzeln validiert und in einer Datenbank persistiert. Der Prozess Verarbeitbarkeitsprüfung (Validierung und das Schreiben in die Datenbank) bietet sich für die parallele Verarbeitung an, da die Nachrichten unabhängig voneinander verarbeitet werden können. Fehler in der Validierung führen dazu, dass die Nachrichten nicht in der Datenbank (DB) erfasst werden. In diesem Fall werden Nachrichten ID und Validierungsfehler in einem Listenobjekt festgehalten.
Wenn alle Dateien verarbeitet wurden, soll der Prozess eine Liste liefern, welche die einzelnen Nachrichten-IDs und die dazugehörige ID aus der Datenbank beinhaltet, sowie die Fehlerliste der nicht verarbeitbaren Nachrichten, wobei Letztere im Idealfall leer ist.

Für die in den folgenden Abschnitten beschriebenen Testdurchläufen. Wurde eine Datei mit folgenden Kennzahlen verarbeitet:

  • Größe der Datei:           14.827 KiB
  • Anzahl der Messages:             7863

Als Prozessbeschreibungssprache wurde BPEL gewählt. BPEL bietet die Option der Validierung einzelner Variablen und mit der ForEach-Schleife ist die Möglichkeit gegeben über die Nachrichten zu iterieren.

Voreinstellungen

Um Massendaten zu verarbeiten müssen einige Server Einstellungen verändert werden. Die Default Werte sind auf dem Admin und SOA-Server zu niedrig eingestellt, um größere Datei zu verarbeiten. Es würde zu Transaction-Timeouts kommen oder dazu, dass die Datei aufgrund ihrer Größe nicht eingelesen werden kann.

In unserem Fall haben wir folgende Parameter angepasst:


Bei den Timeouts ist folgender Sachverhalt unbedingt einzuhalten, andernfalls könnte es zu Laufzeitfehlern kommen.

SyncMaxWaitTime < BPEL EJB’s transaction timeout < Global Transaction Timeout

Des Weiteren wurden folgende Änderungen bezüglich des Connection Pools vorgenommen:

BAMDataSource = 100
SOADataSource = 50
SOALocalTxDataSource = 50

In der SOA wurde die HeapSize auf 8 GB angehoben. Die HeapSize sollte in Abhängigkeit vom Speicherbedarf gewählt werden. Nicht nur zu wenig Speicher kann Probleme, z.Bsp. Swapping, bei der Verarbeitung verursachen, auch zu viel Speicher verursacht Laufzeitprobleme.

Erster Lasttest: Sequentielle Verarbeitung:

Um Vergleichswerte für die Verarbeitungsdauer paralleler Prozesse zu bekommen, wurde eine sequentielle Dateiverarbeitung durchgeführt.
Vorgehensweise: In der Datei enthaltenen Nachrichten werden in einer ForEach-Schleife verarbeitet. Nach 1000 Nachrichten wird eine Dehydration angestoßen. Diese wurde eingebaut um den Speicher zu entlasten damit nicht alle Nachrichten vorgehalten werden müssen. Durch die Dehydration wird die Transaktion beendet und ein Commit in der Datenbank durchgeführt. In späteren Testdurchläufen wird die Dehydration Zeitgesteuert ausgeführt.

Ergebnisse: Die nachfolgende Grafik zeigt die Datenbankschreibrate, d.h. die Anzahl der pro Sekunde in die Datenbank geschrieben werden. Die benötigte Gesamtzeit für das schreiben in die DB ca.13min. Die Zeitdauer für die Validierung kann außeracht gelassen werden. Da diese, nach ersten Untersuchungen, deutlich weniger als eine 1s pro Nachricht dauert.


Die Abbildung unten, zeigt die CPU Auslastung und die Heap Auslastung


Erkenntnisse:

  • Zeitspanne beim dehydrieren wird immer Größer
  • Die Datenbankschreibrate fällt mit zunehmender Laufzeit deutlich ab
  • Garbage Collection wird sehr häufig durchgeführt
  • CPU Auslastung stagniert um die 20 %

Die Ergebnisse können verschiedene Ursachen haben, zu denen die nachfolgenden Absätze verschiedene Erklärungen liefern sollen.

Mögliche Ursache für die größer werdende Zeitspanne beim Dehydrieren und die häufig durchgeführte Garbage Collection (GC), könnte ein stetig wachsendes Element sein. Wie in der Einleitung beschrieben werden die Nachrichten-ID und der dazugehörige Datenbankschlüssel in ein Listen-Element geschrieben. Das Element wächst mit jedem Schleifen durchlauf an. Daraus folgt, dass die Dehydration mit der Zeit immer mehr Speicher benötigt.

Dass die CPU Performance bei einem Wert um 20 % stagnierte lag daran, dass die Dateiverarbeitung innerhalb einer von nur einer Instanz durchgeführt wurde.

Schlussfolgerung:

Um eine Aussagefähige Schlussfolgerung über die Laufzeiten sowie die Auslastung einer sequentiellen der Dateiverarbeitung geben zu können, sollten vorher die identifizierten Laufzeitprobleme usw. behoben werden.

Sequentieller Testdurchlauf ohne stetig wachsendes Element

Vorgehensweise: In diesem Testdurchlauf wurde die Nachrichten-Datei sequentiell verarbeitet, jedoch ohne dabei ein stetig wachsendes Element, das mit jedem Schleifen durchlauf größer wird, zu Erzeugen. Dies wurde dadurch erreicht, indem eine Datenbank-Abfrage, am Ende der Dateiverarbeitung, ausgeführt wird. Die Abfrage liefert alle aktuell committeden Nachrichten ID’s mit den dazugehörigen Datenbankschlüsseln als ein Nachrichtenset in einer Liste.
Ergebnisse: Das Ergebnis des Durchlaufes wird aus der folgenden Grafik ersichtlich. Die Zeiten für die Dehydrierung sind im vergleich zum vorherigen Durchlauf deutlich geringer. Ursache für die etwas größere Zeitspanne in der keine Nachrichten geschrieben wurden, war ein vom System durchgeführter Heap Dump. Die Zeitdauer für den Gesamtdurchlauf ist um 3 min von 12 auf 9 min gesunken.


 

Schlussfolgerung: Die bei der sequentiellen Dateiverarbeitung gewonnen Erkenntnisse und Eckdaten können im Folgenden als Ausgangswerte für die Parallelisierung verwendet werden.

Parallele Testdurchläufe
Erste Ansätze sahen vor, die Nachrichten innerhalb der Dateiverarbeitung zu parallelisieren. Anschließend wurde jedoch dazu übergegangen, stattdessen einzelne Dateien parallel zu verarbeiten.

Test der Parallel Execution in der ForEach-Schleife

Vorgehensweise: Als erstes wurde die Option einer parallelen Ausführung innerhalb einer ForEach-Schleife gewählt. Im Vergleich zur Sequentiellen Verarbeitung blieb der Prozessaufbau dabei unverändert.

 


Ergebnisse: Der Testdurchlauf wurde aufgrund eines Transaction Timeouts beendet, siehe nachfolgende Fehlermeldung:

<failed to handle message weblogic.transaction.internal.TimedOutException: Transaction timed out after 3001 seconds BEA1-4AD96AAC474B3FB65372

 Der Transaction Timeout ist aufgetreten, obwohl wie Einführend beschrieben mehrere Timeouts deutlich angehoben wurden. Dieser Timeout wurde nach 3000s, umgerechnet 50 min, ausgelöst. Die CPU Performance lag stetig bei 30 % und die Garbage Collection war im Vergleich zur Sequentiellen Verarbeitung sehr viel häufiger.

Erkenntnisse:

  • Es wurde nicht dehydriert
  • Sehr hohe Speicherbelastung
  • Keine hohe CPU Auslastung
  • Sehr hohe Verarbeitungszeit

Bei paralleler Ausführung kann die Funktionsweise der ForEach-Schleife, wie folgt beschrieben werden: Die Schleife holt sich alle abzuarbeitenden Knoten, in diesem fall so viele, wie Nachrichten in der Datei vorhanden sind. Daraus folgt das die Speicherbelastung sehr hoch ist. Des Weiteren werden die Knoten nicht parallel verarbeitet, sondern ein Schleifendurchlauf nach dem anderen. Siehe auch andere Beiträge zu diesem Thema: http://technology.amis.nl/2008/10/23/investigation-into-the-true-parallellism-of-the-oracle-bpel-pm-flow-activity-in-11g-technical-preview-4-on-flow-sequence-wait-and-asynchronous-calls/

Der Grund warum die CPU Auslastung stets bei 30 % lag, ist derselbe wie im vorherigen Testdurchlauf: Die Dateiverarbeitung findet innerhalb derselben Instanz statt.

Schlussfolgerung: Die parallele Ausführung innerhalb einer ForEach-Schleife eignet sich nicht für eine größere Anzahl von Schleifendurchläufen.

Parallelverarbeitung auf mehreren Instanzen

Vorgehensweise: Die in der ForEach-Schleife implementierte Logik wird in einen asynchronen BPEL-Prozess ausgelagert. Dieser wurde als Proxy-Service im OSB publiziert und als Webservice-Aufruf in die Composite eingebunden. Ziel dieser Vorgehensweise ist die Dateiverarbeitung auf mehreren Instanzen durchzuführen.
Im eigentlichen Prozess wird der Webservice in einer neuen ForEach-Schleife mehrmals Aufgerufen. Da ein asynchroner Prozess aufgerufen wird und deshalb nicht auf einen Response gewartet wird, starten die Instanzen nur leicht Zeitverzögert. In unserem Beispiel haben wir festgelegt, dass der asynchrone BPEL-Prozess dreimal aufgerufen wird. Die aufgerufenen Prozesse teilen sich die in der Datei enthaltenden Nachrichten untereinander auf. Mit Hilfe eines mathematischen Algorithmus wurden die Nachrichten auf die drei Prozesse aufgeteilt und somit eine näherungsweise gleiche Auslastung erreicht.

Ergebnisse: Aus der nachfolgenden Grafik wird ersichtlich wann die einzelnen Instanzen gestartet sind und das in der Zeit keine neuen Nachrichten in die DB geschrieben wurden (Ausnahme die dritte Lücke dort wurde ein Heap Dump auf dem Server durchgeführt). Aus der Grafik wird des Weiteren ersichtlich das sehr viel mehr Messages in einer Sekunde geschrieben als in den anderen Testläufen zuvor. Außerdem ist auch die gesamte Verarbeitungszeit deutlich gesunken.
Die CPU- (70 %) und Heap-Auslastung waren im Vergleich zu den vorherigen Lasttests deutlich erhöht.

Erkenntnisse:

  • Deutlich gestiegene CPU- und Heap-Auslastungen
  • Geringere Verarbeitungszeit
  • Ergebnisse der 3 asynchronen Prozesse lassen sich nicht wieder in einem Prozess vereinigen

Schlussfolgerung: Eine Performance-Steigerung durch Parallelverarbeitung mit Hilfe von asynchronen BPEL-Prozessen ist nur dann möglich, wenn die betreffenden Prozesse vollständig voneinander unabhängig sind. Wenn deren Ergebnisse jedoch anschließend wieder zusammengeführt werden müssen, ist der Ansatz ungeeignet.
Ein, auf diesem Ansatz, basierender Versuch es mit synchronen Prozessen zu konstruieren hat nicht funktioniert, da innerhalb der ForEach-Schleife keine Parallelisierung möglich ist würde ein Service Aufruf nach dem anderen abgearbeitet werden.

Parallelverarbeitung im OSB

Vorgehensweise: Der Steuerprozess ruft einen Proxyservice im Oracle Service Bus (OSB) auf, welcher eine SplitJoin Operation enthält. Deren Funktionsweise ist ähnlich der parallelen Ausführung in der BPEL ForEach-Schleife. Die SplitJoin Operation beinhaltet eine ForEach-Schleife, mit einem Start- und Endcounter. Die Idee war innerhalb der OSB ForEach-Schleife einen synchronen BPEL Prozess aufzurufen, welcher die Validierung und das schreiben in die Datenbank übernimmt.

Ergebnisse: Die CPU Auslastung und der Speicher Bedarf waren im Vergleich zu den vorherigen Test hoch. Die Verarbeitungszeit ist sich im Vergleich zur sequentiellen Verarbeitung ungefähr gleich, obwohl die Auslastung höher war.

Erkenntnisse:

  • Hoher Ressourcen Verbrauch
  • Verarbeitungszeit vergleichbar mit der sequentiellen Verarbeitung

Schlussfolgerung: Aufgrund der hohen CPU Auslastung und auch der Zeiten beim Schreiben in die DB hat eine Parallelisierung durch die SplitJoin Operation stattgefunden, jedoch hat dieser Parallelisierungsansatz keine Vorteile für die Verarbeitungszeit.

 

Parallelisierung auf File-Ebene

Vorgehensweise: Zum Testen der Parallelisierung wurde der Prozess so umgebaut das dieser mittels einer Trigger-Datei angestoßen wird. Für jede Datei im Verzeichnis wird eine eigene Prozess Instanz angelegt und der Prozess arbeitet die Nachrichten der jeweiligen Dateien sequentiell ab. Einfach Ausgedrückt der sequentielle Testdurchlauf vom Anfang des Artikels wird jetzt parallel Ausgeführt.

Ergebnisse: Die Ergebnisse dieses Testdurchlaufs basieren auf die Verarbeitung zweier nachrichten-Dateien, es ist jedoch auch möglich so viele Dateien parallel zu verarbeiten wie Worker-Threads vorhanden sind. Die CPU Auslastung (~40%) sowie die Belastung des Heaps waren ungefähr doppelt so hoch wie bei der einfachen sequentiellen Verarbeitung. Die Verarbeitungszeit hat sich im Vergleich zur Auslastung nicht verdoppelt, gestiegen von 9min auf 13min.

Schlussfolgerung: Die Parallelisierung auf File-Ebene funktioniert einwandfrei. Die Speicher und CPU Auslastungen steigen ungefähr linear mit der Anzahl parallel gestarteten Instanzen an.

Teile diesen Artikel:
Tagged with →  

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *