Einlesen großer Dateien mit Camel

    Wissensbeitrag

    Wenden wir uns einmal der Situation zu, dass eine relativ große Datei über eine simple Java Anwendung zerlegt und die so gewonnen Daten in eine Datenbank geschrieben werden sollen. Dazu gibt es verschiedene Ansätze, die sowohl Vor- als auch Nachteile aufweisen.

    Möglichkeit 1: plain Java

    Java bietet hierzu eine relativ simple Möglichkeit: Den FileReader. Mit diesem FileReader wird die Datei in das Java Programm eingelesen, in welchem dann verschiedene Bearbeitungsschritte vorgenommen werden können. Zum Schluss wird die Datei in die Datenbank geschrieben. Einen Haken hat diese einfache Prozedur allerdings: Der FileReader lädt die gesamte Datei in den Puffer. Dadurch entstehen – je nach Dateigrößen – immens große Laufzeiten. Im Worst-Case führt dieses Verfahren sogar zu einem Programmabsturz und wird damit vollständig unbrauchbar.

    Tippen auf Tastatur

    Ein Workaround für dieses Problem besteht darin, jeweils nur einzelne Zeilen mit Hilfe des Java-Integrierten Scanner Tools auszulesen und zu bearbeiten. So wird ein geringerer Anteil an Speicher auf einmal benötigt. Nun ergibt sich jedoch das Problem, dass diese Anwendung nachträgliche Anpassungen oder Erweiterungen deutlich schwierig gestaltet. Ein weiterer Nachteil besteht darin, dass erst immer eine komplette Zeile bearbeitet werden muss bevor die nächste Zeile eingelesen wird:

    Zeile auslesen -> Bearbeitung und Daten herausfiltern -> Datenbank füllen

    Der gesamte Vorgang muss außerdem an einem Stück passieren, da zwischendurch nicht einfach pausiert werden kann.

    Plain Java eignet sich somit eher dafür, kleinere Dateien zu verarbeiten. Für größere Dateien empfehle ich andere Varianten – wie zum Beispiel über ActiveMQ und Camel, Open Source-Techniken.

    Möglichkeit 2: Open Source (Apache ActiveMQ & Camel)

    Rechner mit Programmiercode

    Mit Apache Camel besteht in Verbindung mit ActiveMQ die Möglichkeit, oben angesprochene Thematik in zwei „Routen“ zu teilen und diese gleichzeitig laufen zu lassen. „Routen“ sind dabei Handlungsstränge in Camel, welche zum Beispiel eine Datei von A nach B schieben und zwischendurch noch andere Bearbeitungsschritte durchführen:

    – Route 1 liest die Zeilen einzeln aus und schreibt diese auf eine Queue

    – Route 2 nimmt sich die Messages aus der Queue und schreibt die gewollten Daten in die Datenbank

    Ein Vorteil hierbei ist, dass die Routen simultan bearbeitet werden. Das bedeutet, dass Route 2 dauerhaft auf die Queue achtet. Sobald von Route 1 eine Message auf die Queue geschrieben wird, wird diese dadurch von Route 2 bearbeitet. Die fertig bearbeiteten Daten wandern im Anschluss direkt in die Datenbank.

    Ein zweiter Vorteil dieser Variante: Asynchronität. Sollte Route 2 zum Beispiel einmal nicht auf die Queue lauschen, kann Route 1 trotzdem noch Messages in die Queue einreihen. Sobald Route 2 wieder verfügbar ist, holt sie sich die bereits vorhandenen Messages einfach ab. Letztlich kann diese Lösung noch durch Transaktionssicherheit ergänzt werden (ein weiterer Vorteil, den Camel von Haus aus bietet), sodass bei einem Ausfall die Daten trotzdem erhalten bleiben.

    Ebenso ermöglicht diese Variante eine deutlich einfachere, nachträgliche Anpassung bzw. Erweiterung um zum Beispiel weitere Anbindungen, wie: Die Daten nicht nur in eine Datenbank schreiben, sondern verschiedene Daten zusätzlich noch an andere Stellen weiterzuleiten um beispielsweise eine Stückzahl einer Bestellung ans Lager weiterzugeben.

    Welche Varianten nutzen Sie zum Einschreiben von Dateien in Datenbanken? Ich freue mich auf Ihre Erfahrungen, Meinungen und – selbstverständlich – auch Fragen zu diesem Thema.

    Autor

    Wolfgang Schmidt
    GeschäftsführerX-INTEGRATE Software & Consulting GmbHKontakt