In unse­rem letz­ten Bei­trag zu Tal­end haben wir uns inten­siv mit der Kom­po­nente tMap befasst. In die­sem Bei­trag wer­den wir erneut nicht ohne diese Kom­po­nente aus­kom­men, wir wol­len jedoch den Schwer­punkt auf das typi­sche Ende eines ETL Jobs set­zen: Die Lade­stra­te­gie in eine Daten­bank. Sie ist abhän­gig von vie­len Fak­to­ren, wie bei­spiels­weise der Umset­zung des Daten­mo­dells, der Daten­menge, Lade­zeit und ‑rhyth­mus, allei­ni­ger Zugriff, unit-of-work sowie Art und Per­for­mance der Daten­bank bzw. Per­for­mance­ver­hält­nis zwi­schen Daten­bank und Tal­end Jobserver.

Durch die viel­sei­ti­gen Ein­satz­mög­lich­kei­ten von Tal­end ist es kei­nes­falls mög­lich, in die­sem Arti­kel alle denk­ba­ren Sze­na­rien zu betrach­ten, viel­mehr wird der Fokus auf typi­sche ETL Jobs auf der dis­po­si­ti­ven Seite inklu­sive des Meta­da­ten­ma­nage­ments gelegt.

Im Fol­gen­den wer­den zunächst die Tal­end Kom­po­nen­ten zum Bela­den der Ziel­da­ten­bank auf­ge­zeigt und beschrie­ben mit wel­chen Optio­nen sie ver­füg­bar sind. Anschlie­ßend wer­den meh­rere Anwen­dungs­fälle betrach­tet, die sich mit die­sen Rah­men­be­din­gun­gen umset­zen lassen.

Tal­end Kom­po­nen­ten zum Bela­den einer Datenbank

Für jede Daten­bank bie­tet Tal­end DI in der Regel jeweils zwei Kom­po­nen­ten zum Laden an: Zum einen tDB­Out­put und zum ande­ren tDBBulkExec.

tDB­Out­put

Die tDB­Out­put ist das Pen­dant zur tDBIn­put Kom­po­nente. Hier­bei wird die Daten­bank­ta­belle direkt aus dem Daten­strom des Tal­end DI Jobs mit­tels pre­pared State­ments bela­den. Die Ein­stel­lungs­mög­lich­kei­ten die­ser Kom­po­nente sind viel­sei­tig, sodass ein brei­tes Spek­trum an Anwen­dungs­sze­na­rien abge­deckt wer­den kann.

Data stream - Die extrahierten Daten aus der tDBInput werden Zeile für Zeile direkt wieder in die Zieldatenbank via tDBOutput geladen.
Abbil­dung 1: Data stream – Die extra­hier­ten Daten aus der tDBIn­put wer­den Zeile für Zeile direkt wie­der in die Ziel­da­ten­bank via tDB­Out­put geladen.

Für die­sen Arti­kel sind ins­be­son­dere fol­gende Optio­nen relevant:

  • Action on table: Im Nor­mal­fall ist hier “default” die rich­tige Wahl. Diese setzt vor­aus, dass eine Tabelle exis­tiert und diese via „action on data“ (s.u.) bela­den wer­den kann. Es kann jedoch auch für das Bela­den einer tem­po­rä­ren Tabelle oder auch für zykli­sche Voll­la­de­stra­te­gien ein „drop and create“ oder „trun­cate“ gewählt wer­den – je nach­dem, ob die DDL von Tal­end oder von einem exter­nen Tool vor­ge­ge­ben bzw. defi­niert wer­den soll.
  • Action on data: Diese Option defi­niert, wie die Daten in die Tabelle gela­den wer­den sol­len bzw. kön­nen: INSERT, UPDATE, UPSERT (UPDATE and INSERT) oder DELETE. Falls nur INSERTs durch­ge­führt wer­den sol­len, so muss nicht zwangs­läu­fig ein Schlüs­sel in den Meta­da­ten oder in den „Use Fields“ Optio­nen defi­niert sein, für alle ande­ren Lade­stra­te­gien jedoch schon!
  • Batch Size: In den Advan­ced Set­tings lässt sich nach Set­zen von “Use Batch Size” eben diese defi­nie­ren. Diese Option ist nur mög­lich, wenn in “Action on data” INSERT, UPDATE oder DELETE gewählt wurde. Ist eine Batch Size gesetzt, so wird eine defi­nierte Zei­len­an­zahl als gan­zes Paket ver­ar­bei­tet, wodurch eine Per­for­man­cestei­ge­rung ermög­licht wird. Nach­tei­lig ist jedoch die dann not­wen­dige Ein­schrän­kung, dass keine Ein­zel­satz­ver­ar­bei­tun­gen durch­ge­führt wer­den kön­nen. Das bedeu­tet, dass auf keine spe­zi­fi­schen REJECTS der Daten­bank reagiert wer­den kann und dar­über hin­aus i.d.R. der gesamte Batch nicht fest­ge­schrie­ben wird.
  • Com­mit every: Das Com­mit­in­ter­vall ist eben­falls ein essen­ti­el­ler Para­me­ter. Die­ser defi­niert, nach wie vie­len gela­de­nen Zei­len ein COMMIT durch­ge­führt wer­den soll, also die Daten­menge fest­ge­schrie­ben wird. Wird die Ver­bin­dung zur Daten­bank über eine tDBCon­nec­tion auf­ge­baut, ist diese Option nicht ver­füg­bar und die Com­mit­stra­te­gie muss ent­we­der über „auto com­mit“ in der tDBCon­nec­tion oder via expli­zi­ter tDBCom­mit Kom­po­nente defi­niert wer­den. Mit der auto com­mit Funk­tion wird min­des­tens nach jedem batch ein COMMIT durchgeführt.
tDBBulk­Exec

Die tDBBulk­Exec Kom­po­nente lädt aus­schließ­lich von einer flat file aus­ge­hend über eine daten­bank­spe­zi­fi­sche Lade­stra­te­gie. Diese Stra­te­gie ist haupt­säch­lich bei gro­ßen Daten­men­gen von Vor­teil. In sel­te­nen Fäl­len steht die flat file bereits lokal oder in einem gemoun­te­tem Netz­werk­ord­ner zur Ver­fü­gung, so dass diese direkt in die Daten­bank gela­den wer­den kann. In der Regel muss diese Datei erst aus einer Quell­da­ten­bank extra­hiert wer­den oder die flat files müs­sen zunächst in ein bestimm­tes For­mat über­führt oder zusam­men­ge­fasst wer­den. Die­ser erste Schritt wird ent­we­der über die gene­ri­sche tFi­le­Out­put­De­li­mi­ted Kom­po­nente oder, falls für die spe­zi­fi­sche Daten­bank ver­füg­bar, über die Kom­po­nente tDB­Out­put­Bulk durchgeführt.

Batch Import - Die extrahierten Daten werden zunächst auf dem Jobserver zwischengespeichert und anschließend über tDBBulkExec im Ganzen importiert.
Abbil­dung 2: Batch Import – Die extra­hier­ten Daten wer­den zunächst auf dem Job­ser­ver zwi­schen­ge­spei­chert und anschlie­ßend über tDBBulk­Exec im Gan­zen importiert.

Wie die flat file in die Tabelle gela­den wird ist abhän­gig von der jewei­li­gen Daten­bank. Im Fall der Exa­sol wird das effi­zi­ente IMPORT State­ment abge­setzt, im Fall einer DB2 wird ent­we­der ein LOAD oder ein INGEST ver­wen­det, im Fall einer Post­greSQL wird COPY verwendet.

Anwen­dungs­sze­na­rien

Mas­sen­da­ten

Die Ver­ar­bei­tung von Mas­sen­da­ten, sei es im Del­ta­be­trieb oder in regel­mä­ßi­gen Voll­la­de­läu­fen, ist ein typi­scher Anwen­dungs­fall von Tal­end DI Jobs. Die Daten­menge ist hier­bei so groß, dass sie in der Ziel­da­ten­bank nicht in eine unit-of-work passt, und daher eine opti­male batch und com­mit Größe gefun­den wer­den muss. Eben­falls ent­schei­dend sind fol­gende essen­zi­el­len Rahmenbedingungen:

  • Könn­ten aus der Quelle Dublet­ten extra­hiert wer­den bzw. müss­ten diese gefil­tert wer­den?
    Eine mög­li­che Lösung für die­ses Pro­blem ist eine zei­len­ba­sierte Dublet­ten­ent­fer­nung (hier ein Bei­spiel mit Infor­ma­tica Power­Cen­ter, wel­ches sich ana­log auch in Tal­end in einer tMap oder tJa­va­Row umset­zen lässt).
  • Muss beim Laden in die Ziel­da­ten­bank auf exis­tie­rende Daten geprüft wer­den bzw. sol­len UPDATES abge­setzt wer­den?
    An die­ser Stelle auf die Rejects der Daten­bank zu set­zen, schei­det als Lösungs­sze­na­rio aus, da auf­grund der Daten­menge auf batch-INSERTs gesetzt wer­den muss. Der Lookup auf die Ziel­da­ten­menge lässt sich im Tal­end­job durch­füh­ren, siehe fol­gende Abbildung.
  • Muss der Job restart­fä­hig sein? Wenn der Tal­end­job wäh­rend der Ver­ar­bei­tung abbricht, soll an die­ser Stelle ein Restart mög­lich sein, der ent­we­der alle zuvor gela­de­nen Daten igno­riert oder genau an die­ser Stelle wie­der auf­set­zen kann?
  • Muss die Lade­ge­schwin­dig­keit durch par­al­lele Ver­ar­bei­tung erhöht werden?
Batch UPSERT - In der tMap werden die Eingangsdaten mit der zuvor geladenen Zieltabelle gejoint.
Abbil­dung 3: Batch UPSERT – In der tMap wer­den die Ein­gangs­da­ten mit der zuvor gela­de­nen Ziel­ta­belle gejoint. Falls der (inner) Join nicht trifft, wird diese Zeile über “Catch inner join reject”-Output an die INSERT Out­put-Kom­po­nente wei­ter­ge­ge­ben. Optio­nal lässt sich über einen DIFF-HASH ent­schei­den, ob ein UPDATE nötig ist.
Talend LOAD and MERGE - Durch das Importieren der Daten mittels der tDBBulkExec Komponente lässt sich performant eine große Datenmenge in die Datenbank importieren.
Abbil­dung 4: Tal­end LOAD and MERGE – Durch das Impor­tie­ren der Daten mit­tels der tDBBulk­Exec Kom­po­nente lässt sich per­for­mant eine große Daten­menge in die Daten­bank impor­tie­ren. Mit Hilfe eines anschlie­ßen­den MERGE State­ments kann diese per WHEN MATCHED THEN UPDATE und WHEN NOT MATCHED THEN INSERT in die Ziel­ta­belle inte­griert wer­den. Diese Stra­te­gie ist nur bei einer hin­rei­chend poten­ten bzw. OLAP ori­en­tier­ten Daten­bank sinn­voll, wie bei­spiels­weise Snow­flake oder Exa­sol. Das MERGE State­ment lässt sich bei einem gene­ri­schen Vor­ge­hen auch mit Hilfe von Tal­end para­me­tri­sie­ren und zen­tral als Joblet Kom­po­nente ablegen.
Ein­zelin­serts & Commitstrategie

Es exis­tie­ren eine Menge Ein­satz­sze­na­rien für ETL-Pro­zesse, in denen die zu ver­ar­bei­tende Daten­menge nicht groß ist. Es kann (und in vie­len Fäl­len muss) ver­stärkt auf die Daten­in­te­gri­tät geach­tet wer­den. Wird in der tDB­Out­put Kom­po­nente keine Batch Size ange­ge­ben, so wer­den die Zei­len alle ein­zeln behan­delt und es kann aus der Out­put Kom­po­nente ein neuer Daten­strang gezo­gen wer­den. Rejects ent­ste­hen durch die Daten­bank, bei­spiels­weise wenn eine PK oder FK Beschrän­kung ver­letzt wird. Diese abge­wie­se­nen Daten kön­nen im Tal­end Job je nach Anwen­dungs­zweck behan­delt wer­den: Soll der Job unter Angabe des abge­wie­se­nen Datums hart abbre­chen? Sol­len alle abge­wie­se­nen Daten in eine sepa­rate “Reject­ta­belle” geschrie­ben werden?

Talend single INSERTS - Falls keine Batch Size in der Output Komponente angegeben wird, kann auf die Rejects der Datenbank individuell reagiert werden. In diesem Beispiel werden die fehlerhaften Daten in eine Rejecttabelle ausgeschleust und zusätzlich wird per tWarn darüber informiert.
Abbil­dung 5: Tal­end sin­gle INSERTS – Falls keine Batch Size in der Out­put Kom­po­nente ange­ge­ben wird, kann auf die Rejects der Daten­bank indi­vi­du­ell reagiert wer­den. In die­sem Bei­spiel wer­den die feh­ler­haf­ten Daten in eine Reject­ta­belle aus­ge­schleust und zusätz­lich wird per tWarn dar­über infor­miert. Nach erfolg­rei­cher Bela­dung der Ziel­ta­belle wer­den die Daten per expli­zi­tem COMMIT festgeschrieben.

Good to know

Was gibt es zu beach­ten, falls aus einem Daten­fluss meh­rere Tabel­len bela­den wer­den sol­len? Im obi­gen Bild zum “Batch UPSERT” ist sicht­bar in wel­cher Rei­hen­folge die Daten­links bear­bei­tet wer­den: Main order: 1 oder 2. Diese bei­den Daten­flüsse ver­lau­fen nicht unab­hän­gig von­ein­an­der. Tal­end arbei­tet wei­ter­hin Zeile für Zeile und zwar immer in der ange­ge­be­nen Rei­hen­folge. Könnte eine Ziel­ta­belle prin­zi­pi­ell schnel­ler bela­den wer­den, wird der Lade­vor­gang durch das par­al­lele Laden der ande­ren Tabelle aus­ge­bremst. Sind Abhän­gig­kei­ten, wie zum Bei­spiel FK Bezie­hun­gen, vor­han­den, so muss zwin­gend die rich­tige Lade­rei­hen­folge gesetzt werden.

Zusam­men­fas­sung und Ausblick

Tal­end bie­tet mit den zwei Kom­po­nen­ten tDB­Out­put und tDBBulk­Exec sehr fle­xi­ble Mög­lich­kei­ten an, Daten in eine Daten­bank zu laden. Es kön­nen sowohl große Daten­men­gen im batch mög­lichst per­for­mant, als auch kon­trol­liert auf Ein­zel­satz­ba­sis gela­den wer­den. Mit wel­cher genauen Com­mit­size oder Batch Size gear­bei­tet wer­den sollte; ob ein Lookup im Tal­end­job durch­ge­führt wird, oder direkt über die Daten­bank; ob eine LOAD Stra­te­gie sinn­voll ist, oder direkte INSERTs, ist immer stark abhän­gig vom Use Case und der Infrastruktur. Wir unter­stüt­zen Sie dabei den opti­ma­len Weg zu finden.