Ein­lei­tung

Mit der Ver­wal­tung von Daten kommt auch immer das Risiko, dass die Daten feh­ler­haft sind. Daher sind für eine hohe Daten­qua­li­tät Vali­die­run­gen uner­läss­lich. Vali­die­run­gen kön­nen pri­mi­tive Checks sein, bei­spiels­weise ob ein Ein­trag fünf Buch­sta­ben hat, das Zah­len­feld wirk­lich eine Zahl ent­hält, aber auch weni­ger hart defi­nierte Bedin­gun­gen wie z.B. ob der Ein­trag in einer Refe­renz­ta­belle ange­legt ist. Beim Nach­schla­gen von Refe­renz­da­ten kann es zu Ände­run­gen die­ser kom­men, was eine erneute Über­prü­fung vor­her abge­lehn­ter Daten­sätze nötig macht.

Im Fol­gen­den soll unsere auto­ma­ti­sierte Lösung sol­cher Pro­blem­stel­lun­gen vor­ge­stellt wer­den. Die Vali­die­run­gen fin­den auf einer Azure Dat­ab­ricks Del­talake Platt­form statt. Die Pro­zesse sind mit Apa­che Air­flow orches­triert, und die Daten wer­den mit PySpark verarbeitet.

Auf­ga­ben der Fehlerlöselogik

Das Lösen von Feh­lern erfor­dert zunächst ein­mal Kennt­nis der zu lösen­den Feh­ler. Wir log­gen feh­ler­hafte Daten­sätze in unter­schied­li­chen, jeweils pro Pro­zess ange­leg­ten, Feh­ler­ta­bel­len , vor­erst ohne eine zen­trale Über­sicht. Die erste Auf­gabe ist es, aus den Ein­tra­gun­gen der Feh­ler­ta­bel­len und Ziel­ta­bel­len unge­löste und gelöste Feh­ler zu bestim­men. Infor­ma­tio­nen über die Sta­tus der Feh­ler wer­den im Anschluss in einer zen­tra­len Meta­da­ten­ta­belle zusam­men­ge­tra­gen. In unse­rem Sys­tem wur­den wer­den die Prü­fun­gen und Feh­ler indi­vi­du­ell und manu­ell ange­legt, daher müs­sen die Meta­da­ten zur Prü­fung der Lös­bar­keit eines Feh­lers eben­falls indi­vi­du­ell je Feh­ler ange­legt wer­den. Diese Meta­da­ten­sätze wer­den am bes­ten direkt beim Anle­gen der Vali­die­rung mit erstellt. Sie kön­nen aber auch im Nach­hin­ein ange­legt wer­den. Das erfor­dert jedoch Ana­ly­sen der bestehen­den Vali­die­run­gen. Wir haben durch die Ana­ly­sen einige unbe­merkte Imple­men­tie­rungs­lü­cken offen­ge­legt und konn­ten diese schlie­ßen noch bevor Feh­ler auf­tre­ten konn­ten. Ins­be­son­dere in gro­ßen und/oder kom­ple­xen Sys­te­men kön­nen sol­che spe­zi­fi­schen Ana­ly­sen Feh­ler auf­de­cken und hel­fen dabei, das Sys­tem für die Zukunft resi­li­en­ter zu machen.

Um Feh­ler auch effek­tiv lösen zu kön­nen, braucht es einen Mecha­nis­mus, der jenen Pro­zess star­ten kann, der den Vali­die­rungs­feh­ler ursprüng­lich auf­ge­zeigt hat. Der Lade­pro­zess lädt den Feh­ler aus der Feh­ler­ta­belle und schreibt ihn nach erneu­ter Vali­die­rung in die Zieltabelle.

Zusam­men­fas­send erge­ben sich die fol­gen­den zu lösen­den Aufgaben:

  • Auf­bau einer zen­tra­len Über­sicht für gegen­wär­tig offene Fehler.
  • Auf­bau eines Meta­da­ten­kon­strukts, das die Lösungs­be­din­gun­gen der indi­vi­du­el­len Feh­ler abbildet.
  • Auf­bau einer Funk­tion zum Aus­le­sen offe­ner Feh­ler und Nut­zung des Meta­da­ten­kon­strukts zur Prü­fung auf Lös­bar­keit der offe­nen Fehler.
  • Auf­bau einer Funk­tion, um ent­spre­chend Lade­pro­zesse mit lös­ba­ren Feh­lern erneut star­ten zu können.

Archi­tek­tur

Das Grund­kon­zept der Logik ist im fol­gen­den Bild dargestellt:

Unsere Imple­men­tie­rung ent­hält einige Kernkomponenten:

  • Auf­ruf der Löse­lo­gik nach jedem rele­van­ten Prozess
  • Eine Tabelle mit Ein­trä­gen über offene Feh­ler­ty­pen, als Über­sicht für der­zeit offene Fehler
  • Eine Tabelle mit den Bedin­gun­gen für die Lös­bar­keit von Fehlern
  • Eine Trig­ger-Mecha­nik für die Ladeprozesse

Meta­da­ten, sowie zu ver­ar­bei­tende und ver­ar­bei­tete Daten wer­den auf Micro­soft Azure Sto­rage Accounts als Blobs gespei­chert. Die Ver­wal­tung die­ser erfolgt über Azure Dat­ab­ricks als externe Tabel­len. Die Selek­tion der Meta­da­ten für die Pro­zesse wird über Python geleis­tet. Sie wer­den beim Start an das dem Pro­zess zuge­hö­rige Note­book über­ge­ben. Im Note­book fin­det dann die Daten­ver­ar­bei­tung über PySpark Data­frames statt.

Die meis­ten Pro­zesse wer­den ange­sto­ßen infolge der Regis­trie­rung eines ange­lie­fer­ten Files durch einen Apa­che Air­flow Sen­sor Ope­ra­tor. Diese Mecha­nik wurde auf ok-Files erwei­tert, wel­che durch die Trig­ger-Mecha­nik der Feh­ler­lö­se­lo­gik erzeugt wer­den. Der, durch das ok-File spe­zi­fi­zierte, Pro­zess wird gestar­tet, und poten­zi­ell wei­tere Pro­zesse fluss­ab­wärts wer­den eben­falls gestartet.

Lebens­zy­klus eines Validierungsfehlers

Fol­gen wir nun einem bei­spiel­haf­ten Daten­satz ein­mal durch die Logi­ken. Es han­delt sich um eine Zah­lung mit den Fel­dern SENDER, RECEIVER, DATE und AMOUNT (z.B. „Marc, Peter, 20240101, 12.3“). Das File mit dem Daten­satz wird in den Ein­gangs­spei­cher geliefert.

Die auf einer Micro­soft Azure Vir­tual Maschine lau­fende Air­flow Instanz ent­hält einen DAG, des­sen Sen­sor im Ein­gangs­be­reich nach ok-Files und Daten-Files für die zuge­hö­ri­gen Pro­zesse sucht.

Das Daten-File wird bemerkt, und der zuge­hö­ri­gen Lade­pro­zess in die Glo­bal Sta­ging Area (GSA) wird gestar­tet. Die­ser vali­diert, dass die Daten des Files in das zuge­hö­rige Schema pas­sen. Wäh­rend des Lade­pro­zes­ses in die Valid Data Area (VDA) wird über­prüft, ob der RECEIVER in der Refe­renz­ta­belle REF_RECEIVER ent­hal­ten ist, ob SENDER in REF_SENDER ent­hal­ten ist, und ob DATE ein vali­des Datum ist. Im Bei­spiel ist „Peter“ nicht in der REF_RECEIVER hin­ter­legt, und der Ein­trag wird in die Feh­ler­ta­belle geschrie­ben mit dem Feh­ler­code „INVALID_RECEIVER“. Beim nächs­ten Pro­zess­durch­lauf wird der Daten­satz aus der Feh­ler­ta­belle zusam­men mit neuen Daten der GSA gela­den. In der Feh­ler­über­sichts­ta­belle wird ein Ein­trag ange­legt, dass für den Lade­pro­zess der Feh­ler „INVALDI_RECIEVER“ aktiv ist. Der Feh­ler wird zusätz­lich über unsere Log­ging Lösung rap­por­tiert, siehe hierzu „Ein intel­li­gen­tes Cloud Log­ging-Frame­work: Effi­zi­enz und Erwei­ter­bar­keit mit Azure Func­tions“.

Aktua­li­sie­ren der Referenzdaten

Der Fach­be­reich wird nun fest­le­gen, dass „Peter“ ein vali­der Emp­fän­ger ist, und nur der Ein­trag in der Refe­renz­ta­belle ver­ges­sen wurde. „Peter“ wird als Emp­fän­ger ange­legt, die Refe­renz­da­ten erneut ange­lie­fert und in GSA sowie VDA gela­den. Am Ende des VDA-Lade­pro­zes­ses wird über­prüft, wel­che Feh­ler in der Feh­ler­über­sichts­ta­belle als offen regis­triert sind, und wel­che davon als durch den VDA-Lade­pro­zess der REF_RECEIVER lös­bar im Meta­da­ten­kon­strukt hin­ter­legt sind. Der Feh­ler „INVALID_RECEIVER“ ist hin­ter­legt und es wird geprüft, ob der auf­ge­tre­tene Feh­ler gelöst wer­den kann. In den Meta­da­ten kön­nen für die Prü­fung not­wen­dige Infor­ma­tio­nen hin­ter­legt sein:

  • Wel­che Funk­tion muss für die Prü­fung genutzt werden.
  • Auf wel­che Spal­ten soll ein Join durch­ge­führt werden.
  • Wel­che Spal­ten müs­sen her­ge­lei­tet werden.
  • Zusätz­li­che Bedin­gun­gen, die erfüllt sein müssen.

Erhält man am Ende der Prü­fung min­des­tens einen vali­den Ein­trag, so gilt die Prü­fung als erfolgreich.

In unse­rem Fall ist „Peter“ jetzt hin­ter­legt, und die Prü­fung war erfolg­reich. Da der Feh­ler nun lös­bar ist, wird ein ok-File für den Pro­zess ange­legt, der den Feh­ler warf. 

Lösen des Fehlers

Wie zuvor das Daten­file, regis­triert der­selbe DAG das ok-File, über­springt den GSA-Lade­pro­zess und star­tet direkt den VDA-Ladeprozess.

Der Ein­trag wird aus der Feh­ler­ta­belle gela­den und erfolg­reich vali­diert. Am Ende des VDA-Lade­pro­zes­ses wird der Ein­trag in die Ziel­ta­belle geschrie­ben, und in der Feh­ler­ta­belle wer­den die kor­re­spon­die­ren­den Ein­träge als gelöst mar­kiert. Die Log­ging-Logik der Feh­ler prüft die Updates und Inserts und stellt fest, dass der Feh­ler gelöst ist und mar­kiert in der Feh­ler­über­sichts­ta­belle den Feh­ler als gelöst, damit keine unnö­ti­gen wei­te­ren Über­prü­fun­gen stattfinden.

Da man hier die Orches­trie­rung dop­pelt ver­wen­det, wer­den auch poten­zi­ell not­wen­dige wei­tere Lade­pro­zesse fluss­ab­wärts mit ausgeführt.

In der Pra­xis gibt es zudem Feh­ler, die durch fluss­auf­wärts lie­gende Pro­zesse gelöst wer­den kön­nen. In die­sen Fäl­len wer­den keine Meta­da­ten für die Lösungs­be­din­gun­gen hin­ter­legt. Es kommt zu kei­nen unnö­ti­gen zwei­ten Durch­läu­fen der Prozesse.

Die Trig­ger-Mecha­nik ist auch ander­wei­tig nutz­bar. Wenn z.B. ein Job zu bestimm­ten Zeit­punk­ten lau­fen soll, kann ein zwei­ter DAG zu die­sen Zeit­punk­ten die Trig­ger-Mecha­nik auf­ru­fen und so die pro­zess­star­ten­den ok-Files erzeugen.

Vor­teile und Nachteile

Unsere Lösung bie­tet einige attrak­tive Vor­teile, wie z.B.:

  • Unser Frame­work ist zu 90% Meta­da­ten getrie­ben, sodass mit nur 3 Prüf­funk­tio­nen über 100 Feh­ler auf Lös­bar­keit geprüft wer­den können.
  • Ein­fa­che Nach­schla­ge­feh­ler kön­nen auto­ma­ti­siert gelöst werden.
  • Durch eine auto­ma­ti­sierte Prü­fung löst das Sys­tem offene Feh­ler schnel­ler, als wenn ein Mensch den Pro­zess manu­ell ansto­ßen müsste. In dem Zusam­men­hang ist die auto­ma­ti­sierte Lösung auch weni­ger fehleranfällig.
  • Es wird weni­ger Per­so­nal zum Lösen von Feh­lern benö­tigt, wodurch mehr Zeit in andere Ver­bes­se­run­gen inves­tiert wer­den kann.

Ein Nach­teil der Imple­men­tie­rung ist der Folgende:

  • Für jede Feh­ler­art ist ein eige­ner manu­ell erzeug­ter Ein­trag im Meta­da­ten­kon­strukt notwendig.

Neben den gelis­te­ten Vor- und Nach­tei­len ver­fügt das Kon­zept über einige Aspekte, die sich einer kla­ren Zuord­nung verweigern:

  • Die Abgren­zung ein­zel­ner Feh­ler und ihre genaue Erzeu­gung muss in den Daten wider­ge­spie­gelt wer­den. Ein Wie­der­ver­wen­den von Feh­ler­codes für meh­rere ähn­li­che, aber nicht iden­ti­sche Feh­ler, ist nicht mehr mög­lich. Je nach bis­he­ri­ger Ver­gabe von Feh­ler­codes, kann dies ein Vor­teil oder Nach­teil sein. Ist jedoch erst­mal jeder Feh­ler indi­vi­dua­li­siert, ist es defi­ni­tiv ein Vor­teil, da man zu einer sau­be­ren Feh­ler­ver­wal­tung gezwun­gen ist.
  • In unse­rem Fall war es rat­sam teils neue Spal­ten für Werte in den Feh­ler­ta­bel­len anzu­le­gen, die zur Her­lei­tung wei­te­rer Werte benö­tigt wer­den. Die neuen Spal­ten haben zu einer bes­se­ren Nach­voll­zieh­bar­keit der Feh­ler geführt, im Ver­gleich zu dem Fall, dass ein Mensch sich die Daten noch­mal genauer anse­hen muss. Dies kann daher als Vor­teil und Nach­teil gewer­tet werden.

Fazit

Unsere Lösung für auto­ma­ti­sier­tes Feh­ler­lö­sen beschleu­nigt das Lösen von Feh­lern. Die Auto­ma­ti­sie­rung redu­ziert lang­fris­tig Kos­ten, da der Betrieb vom Sys­tem ver­ein­facht wird. Eine kon­se­quente Imple­men­tie­rung führt zu gepfleg­ten Meta­da­ten, was eine bes­sere Über­sicht im Sys­tem ermög­licht. Die Tren­nung von Orches­trie­rung in Air­flow und Feh­ler­lö­se­lo­gik in Dat­ab­ricks ermög­licht eine Seg­men­tie­rung der Air­flow-DAGs in kleine logi­sche Einheiten.

Aus dem Betrieb des Sys­tems, in dem es gerade im Ein­satz ist, ist das auto­ma­ti­sierte Feh­ler­lö­sen nicht mehr wegzudenken.