# Row vs Columnar Storage: Scaling Data Infrastructure

**Podcast:** Engineering Kiosk
**Published:** 2026-02-17

## Transcript

Willkommen zu einer neuen Episode vom Engineering Kiosk Podcast.
Kennst du diesen Moment im Team, wenn jemand sagt, das skaliert nicht?
Und plötzlich steht der Datenbankwechsel schneller im Raum als die eigentliche Frage nach dem Warum?
Genau da steigen wir heute ein.
Wolfi und ich nehmen den Satz auseinander und landen ziemlich schnell bei dem, was in vielen Systemen wirklich entscheidet, ob es rund läuft oder ruckelt.
Datenlayout.
Wir sprechen darüber, warum Zeilenorientierung der Default für klassische OLTP-Workloads ist und was an Pages und Blog IO damit zu tun haben.
Danach drehen wir die Tabelle einmal um 90 Grad und schauen uns Calum Stores an.
Olaub, Aggregationen über viele Zeilen, Spaltenpruning, Kompression.
Also all die Tricks, mit denen Clickhaus, BigQuery, Snowflake und Co.
richtig Gas geben.
Und danach wird's pfeilbasiert.
CSV bekommt seit Fett weg, Parkett bekommt dein verdienten Hype und mit Iceberg reden wir über Snapshots, Time Travel und warum Storage und Compute heute gerne getrennte Wege gehen.
Plus, wie das Ganze plötzlich bei Kafka oder sogar Prometheus eingebunden wird.
Wir legen direkt los.
Viel Spaß.
Und deswegen habe ich mich mal gerade gefragt, wie lange bist du eigentlich schon in der Software-Entwicklungsindustrie unterwegs?
Entweder als Softwareengineer, als Berater oder als Engineering Manager.
Wie viele Jahre hast du hier schon auf dem Buckel?
Berufserfahrung könnte man fast so sagen.
Ist die Frage immer, wie du das rechnest natürlich, aber wenn man die Zeit rechnet, wo ich das mein erstes Geld damit verdient habe.
Nee, schon mal schon mal was relevant.
Ich sag nicht, ich habe mal irgendwie für meine World of Warcraft Guilde irgendwie eine Webseite gebaut.
Sondern lass mal richtig real werden jetzt hier.
Jetzt nicht den ersten Euro, sondern da, wo du sagen würdest, okay, ab hier ging es beruflich signifikant um etwas.
Naja, ich habe schon mit 16 erste Software geschrieben, die dann auf CDs und so delivered wurde, an im großen Stile, was dann an einem Buch dran gehängt ist oder so.
Also es geht schon von 25 Richtung 30 Jahre, würde ich fast sagen.
Okay, ich habe gerade mal den Gegencheck gemacht auf deinem LinkedIn-Profil.
Da wurde gesagt, dass in Lupus deine Firma mit deiner Selbstständigkeit im Januar 2013 gegründet wurde.
Somit sind wir dann circa bei 13 Jahren, würde ich sagen.
Kongratulation, wenn man so möchte.
Ja, ich habe davor über 10 Jahre andere Firma gehabt.
Wie dem auch sei, 13 oder 25 Jahre, macht keinen Unterschied für meine nächste Thematik.
Wie oft hast du in deiner beruflichen Laufbahn bereits den Spruch gehört, das skaliert nicht?
Und wir müssen da jetzt was machen.
Wir müssen was Fundamentales ändern.
Muss ich dir das jetzt mitzählen, wo ich das damals in meinen jungen Jahren auch gesagt habe oder nur wenn es andere gesagt haben?
Och, mich würde beides mal kurz interessieren.
Ja, Primature Optimization, das habe ich sehr früh gelernt, würde ich mal sagen, das zu machen.
Ich habe es dann erst sehr spät gelernt, dass es sinnlos ist und dass man das besser machen kann.
Aber natürlich, da junge Wolffi war natürlich immer am Start, wenn es darum ging, irgendwas zu overengineeren.
Ganz klar.
Ich glaube, durch diese Schule müssen wir ja irgendwie alle mal gehen.
Und wie oft hast du das ca.
so von deinen Kunden, von deinem Team oder von Leuten, die in einem Projekt mitgearbeitet haben, wofür du verantwortlich warst oder dass du geleitet hast, gehört?
Ja, mehrmals pro Jahr würde ich sagen.
So im Schnitt, dass man sowas mal hört.
Und wie oft wurde dann wirklich was gemacht?
Also, wie oft wurde dann eine Aktion getätigt, die dann den Austausch der Datenbank zur Folge hatte oder eine fundamentale Änderung implementiert.
Gute Frage.
Ihr müsst überlegen, ob das jemals stattgefunden hat.
Also auf diese Aussage drauf haben wir das, glaube ich, nie gemacht.
Also in dem strukturierteren Prozess vielleicht schon, aber ich glaube, dass diese Aussage nie zu einem Wechsel geführt hat.
Bei mir sieht es ein bisschen anders aus.
Und zwar, ja, der junge Andi, obwohl ich bin ja noch keine 40.
Ich wollte gerade sagen, du bist ja noch jung, ja klar.
Ich habe es schon etliche Male gehört.
Und ich habe auch etliche Male selbst gesagt.
Ich schließe mich nicht aus.
Und ich denke, es ist auch ein reife Prozess und man sollte das auch mal sagen, um zu lernen.
Und öfter mal war das Resultat dann wirklich, Datenbank A wird durch Datenbank B ausgetauscht.
Ein großer Engineeringaufwand findet statt.
Und man ersetzt eigentlich, und das sage ich jetzt nach etlichen Jahren Erfahrung, man ersetzt ein bekanntes Problem durch ein neues, ein noch unbekanntes Problem.
Auf Basis meiner Erfahrung wird die Frage, das skaliert nicht.
Warum?
Eigentlich viel zu selten gestellt.
Beziehungsweise der Satz ist auch sehr einfach gesagt.
Würdest du mir dazu stimmen?
Dass das Satz sehr einfach zu sagen ist, da stehe mir dir zu, dass das, warum nie gefragt wird.
Ich würde sagen, es gibt normalerweise schon Leute, die hoffentlich nachfragen und meistens darum bin ich auch der Meinung, dass das selten zu einer Änderung geführt hat, wie ich es mitbekommen habe, weil es eben Leute gegeben hat, die gefragt haben: hey Moment, warum eigentlich?
Und dann vielleicht auch die tiefer gegangen sind.
Aber es kommt natürlich immer darauf an, ob du dann Leute im Team hast, die sich so stark positionieren, überhaupt mal warum zu fragen und dann vielleicht auch dagegen anzukämpfen, und je nachdem, von welcher Seite das kommt, ist dann natürlich die Frage, ob du überhaupt die Position hast, da irgendwie dagegen anzukämpfen.
Natürlich bin ich ein bisschen plakativ unterwegs hier.
Dass die Frage nie gestellt wird, ist auch falsch.
Ich habe aber auch Teams gesehen, die vielleicht noch nicht so viel Erfahrung haben, wo die Aussage, das skaliert, nicht einfach so hingenommen wurde und dann sofort auf die neue Lösung gesprungen wurde, ohne das wirkliche Problem zu beachten.
Du findest ja auch immer Antworten auf das Warum.
Also wenn das Ganze Team dafür ist, die neue Datenbank einzusetzen, dann werden die schon irgendwas finden auf das Warum drauf und irgendwelche Argumente.
Genau, und vielleicht ist dann die Motivation, nicht das neue System skalierend zu machen, sondern etwas Neues auszuprobieren, eine neue Datenbank, die man gerade auf Hacker News gesehen hat und so weiter.
Aber ich war ja, ich war nicht anders.
Deswegen, ich nehme mich nicht aus.
Inzwischen würde ich sagen, man ersetzt ein bekanntes Problem durch ein neues, noch unbekanntes Problem.
Meiner Erfahrung nach liegt die ganze Sache aber oft an den fundamentalen Datenstrukturen und an den Read und Write-Patterns, also an den Lese- und Schreib-Patterns, warum ein System nicht skaliert.
Denn welches System arbeitet ohne Daten?
Ich glaube, keins.
Und da geht es immer eigentlich an die Grundfrage, wie werden denn die Daten gespeichert?
Wie werden die Daten gelesen?
Wie viel Arbeit muss der Storage Layer machen?
Und wir hatten aber mal eine schöne Episode zu.
Ich nenne es nur Big Landau-Notation oder auch bekannt als Big O-Notation, Algorithmenoptimierung und so weiter und so fort.
Wie oft werden die Daten geschrieben, wie oft werden die Daten gelesen?
Und im Datenbankenbereich, wenn ich über dieses Thema spreche, kommt man da an einem Bereich nicht vorbei, an den Normalformen.
Lieber Doktor der Datenbanken.
Nenne mir doch mal in einem Too Long Didn't Read nochmal kurz die Normalformen bei relationalen Daten.
Wir sind ja ein Wissens-Podcast und wollen wissen übermitteln.
Hast du gerade geglaubt, irgendwas ist kaputt?
Yeah.
Siehst du, so geht es mir auch oft.
Und dann brauche ich unbedingt einen Kaffee.
Oder wie der Andi sagen würde, einen Kaffee.
And für diese Koffeinenergie, die ihr uns durch diese Kaffee-Spenden bereitstellt und die es uns eigentlich erst ermöglichen, diese Episoden zu produzieren, möchten wir uns einmal bedanken.
Und zwar bei den letzten Spender.
Daniel, Jakob, Peter, Alfred, Florian, Michel, Dimo, David, Lukas, Adrian, Nico, Matthias, Wolfgang, by the way, show you.
Elias, Björn, Franco, Dominic, Paul and Fabian.
And egal if you have a cafe sponsored, or violent sort of Abo wieder Fabian, or another Monatsbedarf an Café wieder David, we schätzen jeden einzelnen Café and freuen uns wirklich über diesen Koffein-Feedback.
Vielen Dank von Andi and from me.
And jetzt geht es auch schon wieder zurück zur Episode.
Also ich werde das jetzt einfach so beantworten, dass wir nicht zu sehr in die Tiefe gehen und damit auch meine Unwissenheit caschieren.
Aber es gibt eins bis fünf Normal formen.
The ersten drei sind aber die wichtigsten.
Und im Prinzip geht es darum, that many Daten möglichst nur einmal speichert.
Das heißt, wenn du zum Beispiel und Rechnungen hast, dann wirst du die Kundendaten ja vielleicht nur einmal speichern und nicht bei jeder Rechnung mit speichern.
Wobei da sieht man schon, dass das schon wieder so ein Use Case ist, dass durch Änderungen der Adresse, vielleicht willst du es doch bei der Rechnung dazu speichern.
Das wäre dann denormalisiert.
Normalisiert wäre, ich speichere einmal die Kundendaten ab, einmal die reinen Rechnungsdaten und verknüpfe die dann über eine Relation.
Aber es sind auch so einfache Dinge wie die erste Normalform, gesagt, dass du in einer Spalte in einem Feld nicht mehrere Informationen speichern solltest.
Das heißt, du machst normalerweise Straße, Postleitzahl, Land, als drei Felder, drei Spalten und nicht eine Spalte-Adresse, wo du dann die Straße, Postleitzahl oder Land mit reinspeicherst.
Also es geht darum, die Daten möglichst nur einmal zu speichern und dann sinnvoll miteinander zu verknüpfen mit Joints, mit Relationen.
Und mit der neuen Welle von Document Stores zum Beispiel damals wie MongoDB aufgekommen ist, das war ja auch so was MongoDB, revolutioniert die Welt, alles wird leichter durch MongoDB, alles skaliert.
Das war genau so eine hippe Datenbank damals, bis dann die ersten Firmen reportet haben, dass sie alle Daten verloren haben oder so.
Das war der Klassiker damals, dann sind alle ein bisschen vorsichtiger geworden.
Aber das war so eine Datenbank, die hat alles einfach ohne irgendeine Normalisierung alles in ein Dokument geschmissen und du hast da einfach riesige Blobs mehr oder weniger gehabt, wo du die Daten reingeschmissen hast, also wo keine Normalisierung stattgefunden hat.
Würde ich so gelten lassen, in einer Klausur hätte ich gesagt, ah, da fehlt ein bisschen Fleisch, aber das passt schon so.
Aber wenn wir jetzt über den Satz, das skaliert nicht und Datenbanken sprechen, dann stehen die Normalformen eigentlich, ich sag mal, so ein bisschen im Weg.
Denn bei großen Datenmengen greift man dann in der Regel zur Denormalisierung als Oberbegriff.
Also das bedeutet Präaggregation, also Vorberechnung von Summen und Statistiken und nicht irgendwelche Sum- und Average-Funktionen über Millionen von Datensätzen zu feuern.
Man macht sogar Data Duplication, ja, also man hält explizit Daten mehrfach vor, um Joints zu vermeiden.
Man baut vielleicht sogar White Tables, also sehr breite Tabellen für sehr schnelle Reads und so weiter.
Und eine Thematik, die wir im Podcast hier und da mal immer so beiläufig erwähnt haben, und jetzt kommen wir endlich mal zu dem Thema dieser Episode, ist die Datenspeicherung, beziehungsweise das Layout der Daten, entweder Zeilen oder Spaltenbasiert.
Und ich habe festgestellt, wir sind da nie tiefer drauf eingegangen.
Deswegen gilt diese Episode auf der einen Seite mal ein Deep Dive in Row-Oriented Data Stores, also zeilen orientierten Datenbanken und spaltenorientierten Datenbanken, aber auch Dateisysteme.
Denn Herr Wolfgang, nicht Dateisystem, Dateisystem ist falsch.
Dateiformate, weil der Wolfgang sagt ja immer, wir sollen lieber Files schreiben, anstatt Datenbanken zu nutzen.
Aber Herr Doktor der Datenbank, lass uns mal einsteigen.
Wenn ich sage, gib mir mal ein Einblick in zeilenorientierte Datenbanken.
Was würdest du mir für einen Einblick geben?
Also grundsätzlich geht es ja nicht um Datenbanken, sondern um das eigentliche Format, wie Daten abgelegt werden.
Wir sagen zwar jetzt immer Datenbank dazu, aber das kann ja auch einfach eine Datei sein, die man im Endeffekt verwendet, CSV oder sowas.
Auch da gibt es Row-based, Column-based.
Aber ganz oft spricht man natürlich im Kontext von Datenbanken darüber.
Und Row-Based, also Zeilenbasiert, ist eigentlich das, was wir alle so als klassische relationale Datenbank kennen.
Postgres, MySQL, MSSQL, was es auch immer ist, die sind üblicherweise Row-based.
Das heißt, ganz klassisch, wie man es auch aus Excel zum Beispiel kennt, man sieht eine Zeile und alles wird dann auch zeilenweise gespeichert.
Das heißt, auf der Festplatte in der Datei steht zuerst die erste Spalte, dann die zweite Spalte, dann die dritte Spalte, dann die vierte Spalte, dann kommt die neue, nächste Zeile, Spalte 1, Spalte 2, Spalte 3 und so weiter geht es weiter.
Also so wie man natürlich so eine Excel-Tabelle wahrscheinlich ablegen würde, zeilenweise.
Und so funktionieren eigentlich auch alle Datenbanken, die wir so kennen, klassische relationale Datenbanken, die wir so seit den 70er Jahren eigentlich haben.
Und warum ist das jetzt so?
Es ist ganz klassisch, wir fragen ja meistens, wenn wir irgendwas von der Datenbank haben wollen, eine Zeile oder mehrere Felder von einer Zeile ab.
Also es passiert ja selten, dass du jetzt nur eine Information, eine Spalte wirklich haben willst von einem Datensatz.
Es ist ja üblicherweise mehr.
Du hast eine ID, du fragst irgendwie ein Land an, gib mir alle Kunden in Duisburg zum Beispiel.
Das heißt, du brauchst mal schon die Spalte von Duisburg, du wirst dann aber natürlich auch die Namen anzeigen von den Kunden oder vielleicht wie viel Umsatz sie gemacht haben.
Also du fragst ja üblicherweise mehrere Informationen ab aus einer Zeile und darum macht es natürlich Sinn, dass die Zeilen auch gemeinsam in irgendeiner Form abgespeichert werden.
Also die Spalten von einer Zeile.
Wenn man jetzt mal genau zugehört hat, dann hast du gesagt, die Spalten werden nacheinander geschrieben und somit ist eine Zeile, also auch eine Datenbankzeile mehr oder weniger, sehr simplifiziert gesagt, eine Repräsentation auf der Disk, als Page oder als Block.
Und das bedeutet ja auch, dass eine Abfrage von ein paar Zeilen, aber mit vielen Spalten eher vorteilhaft ist.
Weil die Performance nach unten geht, umso mehr Zeilen ich lese, weil ich dann mehr I.O.
machen muss.
Also vielleicht zur Erklärung noch, weil du Page jetzt in Raum geworfen hast, keine Ahnung, wie viele Leute überhaupt sich damit genau beschäftigen, wenn man natürlich weiter runter geht in dem ganzen Stack, wie eigentlich die Daten abgespeichert werden auf der Festplatte oder auch auf SSDs, also gar nicht Spinning-Disks wie früher, sondern SSDs, ist eigentlich immer so ein Konzept, dass es in irgendeiner Weise gewisse Blöcke gibt, die man ansprechen kann.
Früher waren die eher größer auf so Spinning-Disks.
Es war vielleicht so, wenn man sich das jetzt so vorstellen könnte, eine Umdrehung, so auf einer Spur auf der Festplatte.
Bei SSDs sind es einfach auch Blöcke, die gemeinsam gelesen werden.
Also die Daten von einem so einem Block.
Es hat einfach damit zu tun, dass man nicht bit-weise irgendwas auslesen kann, beziehungsweise kann man natürlich schon, aber es ist langsam, sondern man liest ganze Blöcke immer aus.
Und dann muss man natürlich schauen, was hat in so einem Block Platz.
Hat da jetzt eine Zeile Platz, haben da 10 Zeilen Platz, haben da 100 Zeilen Platz, je nachdem, wie groß diese Blöcke sind, sie es meistens so ein paar Kilobyte, üblicherweise heutzutage.
Und egal wie viel man von dieser Page, von dieser Seite eigentlich benötigt, man muss immer die ganze Seite laden.
Das heißt, auch wenn ich jetzt nur ein Bit wirklich eine Null oder 1 von so einer Seite benötige, kann es sein, dass ich trotzdem irgendwie 16 Kilobyte eigentlich laden muss in meinen Speicher, um dieses eine Bit herauszuholen.
Jetzt macht es natürlich Sinn, dass ich möglichst viel in eine so eine Seite hineinspeichere von Informationen, die ich brauchen könnte.
Und darum, wenn das Zeilenweise in diesen Seiten liegt, heißt es, wenn ich eine so eine Seite in meinen Speicher hole von der SSD, dann habe ich vielleicht schon fünf Zeilen eigentlich mitgelesen.
Und darum ist es auch wichtig, dass Zeilen so gespeichert werden, dass ähnliche Informationen, die oft miteinander gebraucht werden, auch in einer Seite abgelegt werden.
Das heißt, wenn ich jetzt zum Beispiel Anfragen habe, die immer auf eine Postleitzahl gehen.
Ich hole mir meine Kunden immer aus einer gewissen Postleitzahl aus Duisburg zum Beispiel oder aus München oder aus Innsbruck.
Dann macht es natürlich Sinn, dass ich die Zeilen so gruppiere, dass alle Datensätze aus Duisburg zusammenliegen, alle Datensätze aus München und alle Datensätze aus Innsbruck.
Weil ich dann schon automatisch, wenn ich irgendwas von der Festplatte hole, automatisch die anderen Zeilen auch schon mitbekomme aus Duisburg.
Und üblicherweise brauche ich halt alle Informationen aus Duisburg.
Und so wird das dann halt abgelegt, meistens eher über Indizes dann, weil die Rohdaten liegen natürlich irgendwie randomisiert auf der Festplatte.
Aber das ist die eigentliche Idee, dass man diese Seitenzugriffe optimiert und egal was man drüber für Abstraktionsebene hat, ganz ganz unten sind es immer irgendwelche Blöcke, die man liest, sei es auf den SSDs oder im RAM oder im Cache, wo auch immer alle Speicher sind in irgendeiner Form immer Block orientiert.
Das bedeutet auch, es gibt keine negativen Performance Impact, wenn ich sage, Select Spalte 1 From-Tabelle versus Select Spalte 1, Spalte 2, Spalte 3 From Tabelle, weil die Spalten ja mit in der Page liegen in der Regel und beim Page-Load sowieso geladen werden.
Also I.O.-technisch ist das genau das gleiche.
Bei Row-Oriented Data Stores.
Genau, wenn du nur eine Spalte brauchst, ist es leider der Fall, dass du trotzdem alles andere in irgendeiner Form einmal aus dem SST-Speicher holst, dann in deinen Cache legst, dann CPU und so weiter.
Also das geht alles durch deine ganze I.O.-Pipeline durch, obwohl du nur eine Spalte brauchst.
Das heißt, es ist eigentlich egal, ob du einen Stern machst oder nur eine Spalte.
Ist im Endeffekt mehr oder weniger zumindest gleich langsam, würde ich es ja mal in dem Fall sagen, weil eigentlich könnte man das schon optimieren.
Und wenn man sich da jetzt überlegt, ich habe eine Million Rows und ich will eigentlich nur wissen, wie viele Kunden ich pro Postleitzahl habe, dann ist eigentlich nur Postleitzahl wichtig, die Spalte, muss aber komplett durch alle Millionen Rows durchgehen, durch alle Namen, durch alle Straßen, durch alle Länder, durch, keine Ahnung, was ich noch dabei habe als Geschlecht, als die Anrede, irgendwelche Zusatzinformationen.
Wenn ich da 40 Felder habe, also 40 Spalten habe, dann muss ich da komplett durchwandern und durch 40 Millionen Spalten eigentlich durchgehen, nur um zu wissen, wie viele Personen pro Postleitzahl habe ich eigentlich in meiner Daten.
Also eigentlich ein Full-Tablescan.
Also ich habe irgendeinen optimierten Index, aber wenn man es mal weglässt, dann muss man komplett durch die ganze Tabelle durch.
Also natürlich.
Metastrukturen und Pointer und Co.
Jedes Datenbanksystem hat das irgendwie obendrauf implementiert.
Lass uns das mal wegabstrahieren, weil dann wird es wirklich kompliziert.
Aber zusammenfassend bedeutet das, umso mehr Zeilen ich lesen möchte, desto mehr wird die Performance, die I.O.-Performance negativ beeinträchtigt.
Die Anzahl der Spalten, die ich selektiere pro Zeile, ist irrelevant, da die ganze Zeile in der Regel geladen wird.
Genau.
Unten drunter zumindest dann auf der Datenbank-Ebene natürlich wird dann weniger verarbeitet, wenn du jetzt weniger Spalten natürlich wirklich ausgibst, das schon, aber alles drunter, die I.O.-Pipeline wird eigentlich gleich beeinflusst.
Du hattest die klassische Vertreter schon erwähnt.
MySQL, MSSQL, Oracle, SQLite.
Jetzt klären wir das mal final.
Heißt das Postgre oder Postgres oder Postgre SQL?
Weil ich kriege ja immer einen auf die Mütze von unserer Community.
Ich habe gedacht, das haben wir schon geklärt.
Also ich würde Postgres sagen, einfach.
Ohne QL auch dabei.
Postgres, Post-G, wieder wo es sein.
Jetzt hast du im Intro über MongoDB so gehatet.
Und MongoDB ist ja eine dokumentenorientierte Datenbank.
Genauso wie Elasticsearch und oder Open Search und Solar und wie sie alle heißen.
Also ich würde sagen, da ist schon nochmal ein Unterschied, weil MongoDB wirklich eine Datenbank an sich ist und jetzt irgendeine Elasticsearch ist ja jetzt nicht so dafür geeignet, dass man da jetzt voll die Update-Querys die ganze Zeit sendet und da würde jetzt keine Bank drauf implementieren.
Gott würde jetzt vielleicht mit MongoDB auch nicht, aber geht eher in die Richtung zu einem klassischen Datenbankmanagementsystem.
Aber dokumentenorientierte Datenbank, meines Wissens nach, werden ebenfalls physisch record-orientiert gespeichert, weil die halt eher optimiert sind für operative Workloads und nicht für Spaltenorientierte Scans.
Und deswegen kann man ja eigentlich auch sagen, dass MongoDB ebenfalls eine zeilenorientierte Datenbank ist, oder?
Genau, bei MongoDB weiß ich es zufällig, die verwenden auch B-Tree's.
Haben sie früher zumindest, es gibt ja auch andere Storage-Engines mittlerweile, aber die klassische läuft über einen B-Tree, ganz klassisch wie eine relationale Datenbank, einen B-Baum und die Dokumente sind dann an den Blättern quasi dran gehängt und so ein Dokument ist hier nichts anderes als eine Zeile in dem klassischen System, nur dass es halt kein Schema gibt.
Aber klar, wenn du die Dokumente ablegst, ein Dokument entspricht einer Zeile im relationalen Modell, insofern hast du eigentlich dasselbe Row-Based-Format.
Außer du hast natürlich jetzt, es gibt schon Vertreter, die natürlich dann optimieren und vielleicht auch was Spaltenorientiert machen, aber klassischerweise dokumentenorientiert heißt oder könnte man in Row-Based auch einordnen.
Und dann dieser Podcast euch natürlich auch auf eurem beruflichen Werdegang vorbereitet.
Zählt sicheres Auftreten bei völliger Ahnungslosigkeit 100% dazu.
Und deswegen bereiten wir euch auf gutes Password-Bingo.
Der Wolfgang hat zeilenorientierte Datenbank als die ganz klassische Datenbank bezeichnet.
Und dabei möchte ich jetzt ein neues Passwort in den Raum werfen.
OTLP.
Wolfgang, bereite mich doch mal auch vor, damit ich das Passwort nicht so Woche droppen kann.
Nein, also Passwort finde ich jetzt fast ein bisschen übertrieben.
Das ist die absolute Grundlage OLTP und OLAP.
Die Wörter gibt es auch seit den, ja, ich weiß nicht, wann sie erfunden worden sind, aber ich vermute mal auch in den 70ern, weil da ist das Ganze so aufgekommen mit den Datenbanken.
OLTB steht für Online Transactional Processing, hingegen OLAP, also OLAP, ist für Online Analytical Processing.
Das heißt, die eine Seite ist mehr diese ganze Data Crunching, Analytics, Analysen, ich hole irgendwelche aggregierten Werte aus meiner Datenbank heraus für ein Report zum Beispiel.
Und im Gegenzug OLTB sind wir wieder bei den klassischen Datenbanken, MySQL, Postgres, Oracle, ganz viele Transaktionen, Banktransaktionen, ich überweise Geld von Konto A nach Konto B, kurze Transaktionszeit, ein paar Millisekunden, ACIT, Atomar garantiert, ganz klassische, was man sich so unter einer Bank vorstellt, ist OLTP.
So, und weil wir natürlich jetzt von vielen kurzen Transaktionen sprechen, wo Row-Oriented Data Stores performant sind, habe ich mir ganz überlegt, lass uns das mal richtig praktisch machen.
Also in welchen Situationen werden die Stärken herausgespielt.
Und zwar ist das, wie der Wolfgang schon sagte, wenn die Abfrage wenige Zeilen betrifft oder viele Spalten pro Zeile benötigt werden.
Was bedeutet das?
Ein Primary Key-Lookup, also Select Foo from Orders, where ID gleich 4711.
Wirklich ein punktueller Request.
Da kann der Row Store wirklich in seiner Indexstruktur, im B-Tree nachgucken, weiß sofort, wo er hinspringen muss und holt wirklich einmal die komplette Zeile.
Das gleiche natürlich umgekehrt, wenn man die Zeile auch updaten möchte, ebenfalls mit einem Primary-Key Lookup, also Update-Users, Set Name gleich Wolfgang, where Account-ID gleich 4711.
Ebenfalls klassische OLTP-Query, wenige Zeilen.
Der Row Store weiß sofort, wohin es geht und kann einfach nur eine Zeile neu schreiben.
Bei einem ganz klassischen Insert, ganz klassische Inserts gelten auch als kurze Transaktionen, werden angehangen, in Index reingepackt, in ODB-Abfahrt, bei MySQL zumindestens.
Und, das hat ja wahrfangen auch schon gesagt, Range-Queries über, ich sag mal, kleine Bereiche.
Wenn die Daten relativ nah beieinander liegen, der Wolfgang hatte das Postleitzahlen-Beispiel genannt von Duisburg.
Vielen lieben Dank dafür, aber ich glaube, Duisburg hat 50 oder 60 Stadtteile oder 55.
Das bedeutet, da kommen echt eine Menge Postleitzahlen zusammen.
Ich weiß nicht, ob das da noch eine kleine Range ist, aber für eine Datenbank wahrscheinlich schon.
Aber da würde ich sagen, ist so ein Rowstore prädestiniert.
Und jetzt ist die Frage, bedeutet das, ich kann keine Art von Gruppierungsfunktionen wie Sum oder Average auf Row-Oriented Datenbanken machen oder beziehungsweise sollte ich das nicht, Wolfgang.
Weil in meiner MySQL-Welt habe ich etliche Summen gebildet und etliche GroupBy-Queries geschrieben.
Es war ja auch die Grundidee eigentlich von relationalen Datenbanken.
Das haben wir ja auch besprochen in unserer SQL-Geburtstagsfolge, wie SQL, kurz mal sich selber nachdenken, 50 geworden ist, glaube ich, oder?
Was?
Haben wir ja genau das besprochen, dass man eben die Daten ablegt in einem einheitlichen Format, Row-Based in dem Fall, und dann über SQL sich die Ansicht bauen kann, die man gerne hätte.
Und genau da kann man dann natürlich Summen machen, Group Buy, diese ganzen Operationen, um die Daten anders darzustellen.
Das war die große Stärke eigentlich von SQL und vom relationalen Modell.
Und in der Praxis funktioniert das eigentlich auch wahrscheinlich für 90% der Use Cases.
Weil, wenn wir uns ehrlich sind, wie viele Zeilen haben wir denn üblicherweise?
Wie groß ist denn unsere Datenbank?
Also es gibt wahrscheinlich wenig Datenbanken, die irgendwie größer als ein paar Gigabyte sind oder wo eine Tabelle vor allem größer ist als ein paar Gigabyte.
Und das sind ja heutzutage alles keine großen Datenbanken oder großen Mengen mehr.
Also heute, wo wir irgendwelche Speicherdurchsätze von vielen Gigabit haben in der Sekunde, sind das ja alles keine Größenordnungen mehr.
Das heißt, da kann man natürlich auch ganz klassisch, auch wenn man viel verliert, performance-technisch, einfach einen Full-Tables-Scan machen und sich irgendwas ausrechnen.
Oder man erstellt dann einen Index, der in irgendeiner Form etwas optimiert oder aggregiert oder halt schneller zugreifbar macht.
Oder vielleicht auch nur einen Index auf drei Spalten aufbaut, dann hat man eben nie nur diese drei Spalten, die man durchgehen muss, um eine Frage zu beantworten.
Ein guter Index kann das ja, wenn er für eine Abfrage optimiert ist.
Darum funktioniert es natürlich auch.
Und das ist halt die, ich würde es jetzt nicht eierlegende Wollmilchsau nennen, aber doch irgendwo ein System, was halt dann sehr viel unterstützt.
Das hat ACIT, das hat Transaktionen, das kümmert sich darum, dass meine Daten wirklich sicher irgendwo liegen und für die meisten Abfragen inklusive Urlaub-Anfragen, wo ich irgendwelchen Analysen mache für einen monatlichen Report, der läuft halt dann vielleicht nicht so performant, aber ist halt in den meisten Fällen egal, ob die Query irgendwie eine Sekunde oder vier Sekunden läuft für einen Report.
Komplett egal.
Wenn ich natürlich davon spricht, wirklich von noch mehr Daten oder ihr redet dann von Terabyte an Daten oder es sind irgendwelche Logdaten, Metriken, wo ich einfach Milliarden, viele, viele Milliarden von Daten habe, dann kommen wir natürlich in einen Bereich, wo man sagt, okay, gibt es da vielleicht Möglichkeiten, um was zu optimieren.
Und genau da sind dann eigentlich in den 2000er Jahren sehr stark die Spaltenorientierten, die Column-Based Stores eigentlich aufgetreten.
Das Konzept gibt es schon seit den 70ern, wie es so in der Datenbankwelt alles seit den 70ern gibt.
Aber so in den 2000ern ist es dann vor allem durch den guten alten Stonebreaker wieder mal auf der wissenschaftlichen Seite zumindest sehr breit getreten worden.
Da sind dann diese speziellen Workloads aufgekommen, einfach wo man mal viele Daten auch hat.
Webscale-Daten, also irgendwie haben wir ja schon öfters besprochen, Google wäre nie so groß geworden, hätten sie einfach Origil verwendet.
Das hätte einfach nicht funktioniert.
Da hat es dann einfach neue Ansätze gebraucht, man hat viele Daten, man hat viele Logdaten, man hat plötzlich im Web einfach Milliarden von Usern und muss irgendwie mit den großen Datenmengen umgehen.
Und genau da hat man sich dann überlegt, was kann man denn machen.
Und Vertica war, glaube ich, die erste kommerzielle Ausgründung von der Idee von Stonebreaker, wenn man jetzt alles täuscht hatte, C-Store geheißen, die wissenschaftliche Datenbank die erste.
Und da hat so die ganze Movement eigentlich so begonnen in Richtung Column Store, um die Daten noch für OLAP, also für Analytical Queries noch besser abzulegen und eine Datenbank zu bauen, die das eben noch besser beherrscht und mit den riesigen Datenmengen auch umgehen kann.
Vielen Dank, Opa, für die Story vom Krieg.
Aber ja, lass uns mal in den Bereich Spaltenorientierte Datenbanken gehen.
Und zwar hatte ich initial immer so das Verständnisproblem, weil ich muss mir irgendwie die ganze Sache visuell vorstellen.
Und eine klassische relationale Datenbank, du hast Zeile 1 und da sind die Spalten hintereinander, okay.
Bei der Spaltenorientierten Repräsentation dreht man eigentlich eine relationale Tabelle, um 90 Grad gegen den Uhrzeigersinn.
Kann man es so sehen, ja.
Man hat eine Zeile, die Zeile heißt ID und dann hat man 1, 2, 3, 4, 5.
Und dann hat man eine Zeile, die nennt sich Name und die heißt Andi, Wolfgang, Tim, Werner, Miriam.
Und dann hat man eine Zeile, die heißt Stadt, Berlin, München, Duisburg und so weiter.
Und das ist nämlich genau der riesengroße Unterschied, warum diese Art von Storages für OLAP, was der Wolfgang da immer sagt, erinnert mich hart an Olaf.
Ich weiß nicht, ich muss jetzt echt aufpassen, dass ich nicht Olaf sage.
Kannst du auch Olaf-Queries dazu sagen.
Wir verstehen dich, Andi, ist schon okay.
In Duisburg ist es schwierig mit so englischen Begriffen.
Olaf wäre dann Online Analytical Professing oder also Olaf steht für Online Analytical Processing.
Naja.
Aber wie gesagt, da hatte der Wolfgang ja bereits erwähnt, da ist es eigentlich, da geht es darum, dass man Erkenntnisse aus großen Datenmengen ziehen kann.
Also klassische Analyse, BI, Millionen von Datensätzen, lange Reads, große Scans, Aggregationen, komplexe Joints.
Das Datenmodell ist wirklich in der Regel denormalisiert.
Man speichert sogar oft die Daten mehrfach und da genau da kommen die Stärken von Kolumnar Storages nämlich richtig hervor.
Weil alle Werte einer Spalte, über die man zum Beispiel summieren möchte, liegen dann physisch nahe beieinander.
Stell dir vor, du hast eine Artikeltabelle, dann gibt es eine Zeile, die heißt Preis.
Und wenn ich die Summe über alle Preise machen möchte, dann lese ich wirklich nur diese Preise, Zeile.
Und dann habe ich den gleichen Effekt wie beim Row-Based, wo ich sagen möchte, ich nehme nur wie so einer Primary-Key-Look ab, wenn man so möchte.
Du hast dir gedacht, du ziehst jetzt einen Use Case aus der Realität, oder?
Wenn man die Summe über alle Preise bilden.
Sehr realistisches Beispiel.
Nee, schmeiß mein Beispiel mal weg.
Nehmen wir eine Bestellungstabelle.
Ja, nee, das ist auch scheiße.
Du bist den Umsatz generieren.
Den Umsatz meiner Firma, genau.
Jetzt wollte ich, ich wollte gerade sagen, jetzt möchte ich die Summe der ganzen Bestellungen haben, aber das wäre ja auch falsch, da ich ja eine Bestelltabelle habe und dann noch den Filter auf deine Bestellung habe.
Ich möchte den Umsatz meines kompletten Geschäftes von allen Bestellungen berechnen.
Da würde ich sagen, wow.
Genau, wir können auch das Beispiel von gerade eben nehmen mit den Postleitzahlen.
Wenn du nur wissen willst, wie viele Kunden hast du pro Postleitzahl oder pro Stadt zum Beispiel, dann musst du natürlich nur durch diese Spalte Stadt gehen und kannst einfach mitzählen.
Wie oft habe ich jetzt München gesehen, wie oft habe ich Duisburg gesehen und kannst da einfach eine simple Map aufbauen und mitzählen.
Das heißt, du wanderst nur einmal durch diese Spalte mit den Städten und das war's.
Und du musst nicht irgendwie wissen, was für Name das ist, wie viel Umsatz der generiert hat, der Kunde oder sonstige Informationen.
Und da kommt dann eigentlich die Stärke von den Spaltenorientierten Datenbanken heraus.
Zusätzlich, was du auch schon erwähnt hast, ich habe denselben Typ von Daten in so einer Spalte.
Das heißt, ich kann viel besser komprimieren, weil das eben ähnliche Daten sind oder vom Typ zumindest die gleichen.
Das plakativste Beispiel wahrscheinlich ist, wenn man Geschlecht hernimmt, dann hat man männlich-weiblich divers freie Werte und die ändern sich ja nicht so oft, wenn man die einzelnen Zeilen durchgeht.
Also du hast wahrscheinlich auch mal 100 männliche Kunden hintereinander.
Das heißt, du musst dir nicht 100 Mal merken, ich habe da jetzt männlich in meiner Tabelle stehen, sondern du kannst sagen, die nächsten 100 Werte sind immer männlich.
Das nennt sich Lauflängenkodierung und ist eigentlich die einfachste Art von Komprimierung.
Das heißt, du kannst plötzlich diese ganze Gender-Spalte zusammen komprimieren und brauchst dir nur mehr merken, die nächsten 100 Werte sind männlich, nächsten 50 Werte sind weiblich und so weiter.
Das heißt, du speicherst dir nur mal so einzelne Punkte, wenn sich etwas ändert.
Und umso gleichmäßiger die Spalten, umso einfacher natürlich.
Aber du kannst auch ganz andere Komprimierungsalgorithmen draufsetzen, auch wenn das Strings sind, ist es ja auch besser zu komprimieren, weil wahrscheinlich Strings vorkommen, die öfters verwendet werden.
Und dann kannst du natürlich in deinem Komprimierungsalgorithmus den Baum einfach anders aufbauen.
Das heißt, die Komprimierung funktioniert viel, viel besser.
Und wir sprechen ja von ganz großen Datenmengen.
Das heißt, wenn wir da komprimieren können und Anfragen dadurch dann auch schneller bearbeiten können, ist es natürlich ideal genau für den OLAP-Workload mit ganz großen Datenmengen und langen Queries, die eben irgendwas Analytisches machen.
Und darum haben sich die Column-Based in dem Feld zumindest sehr stark dann weiterentwickelt und durchgesetzt.
Und es gibt ja mittlerweile auch so etwas wie HANA, die SRP-Datenbank, die kann zum Beispiel beides.
Da kannst du sagen, will was Row-Based anlegen oder will was Column-Based anlegen.
Das heißt, du kannst dann schon entscheiden, was für Workload ist es eigentlich und wie will ich meine Daten anlegen.
Es gibt auch, glaube ich, für Postgres so ein Plugin, dass du Column Stores dementsprechend verwenden kannst.
Also es hat sich eigentlich schon durchgesetzt und ist, würde ich mal sagen, fast de facto Standard eigentlich heute in der Datenbank.
Wer sind denn so die klassischen Vertreter?
Ich meine, Clickhouse würde ich sagen, ist einer der bekanntesten Vertreter, zumindest im Bereich, was man so selbst hosten kann.
Snowflake als Firma gibt es auch noch, nutzen ebenfalls ein Columnar-Format.
Google BigQuery ist genau das, was wir gerade beschreiben oder Amazon Redshift.
Die frühen waren Monetb, das war, glaube ich, eine der ersten Datenbanken, die so in dem Bereich unterwegs waren, nach eben Vertica.
Vertica war von Stonebreaker aber eben kommerziell.
Und es gibt eben auch für klassische wie MariaDB, Column Store, eine Engine, die jetzt dementsprechend auch Column-basiert ablegt.
Wenn wir jetzt das gleiche Prinzip wie bei der Row-Oriente-Datenbank mal nehmen und sagen, wo ist es denn mal wirklich performant?
Dann kann man generell sagen, bei Column Stores hängt der Aufwand eher davon ab, wie viele Spalten du brauchst und nicht davon, wie viele Spalten die Tabelle insgesamt hat.
Wohingegen bei der Row, wie viele Zeilen du brauchst.
Aber das sagt auch, Aggregationen über viele Zeilen und wenige Spalten, ist dann natürlich genau das Richtige.
Denn dann kannst du nämlich Nutzung von sogenannten Spalten-Pruning machen.
Das bedeutet, massiv komprimierte Spaltenblöcke, weil die Spalten ja eigentlich alle dasselbe Datenformat haben, werden gescannt, aggregiert und vektorisiert zusammengerechnet.
Und diese vektorisierte Zusammenrechnung ist sogar sehr, sehr CPU-freundlich, weil es gibt ein CPU-Konzept, das nennt sich SIMD, Single Instruction Multiple Data.
Dabei lädt die CPU Daten in große Vektorregister und kann die dadurch zusammenhängend berechnen.
Keine Pointer-Sprünge werden dann notwendig und das nutzt so eine Columnar-Storage natürlich sehr gut aus.
Und deswegen ist halt auch so eine Spaltenorientierte Datenbank genau bei sowas recht performant.
Nachdem bei SIMT Operations aber natürlich immer die Daten gleichartig sein müssen, vom gleichen Typ, damit man eben parallel dann mit einer Instruction parallel mehrere Daten verändern kann, lesen, irgendwas addieren, was es auch immer ist, müssen die Daten aber natürlich so dann im Speicher abgelegt werden.
Und da spielt dann Column Store genauso wieder rein.
Man kann natürlich auch SIMT Operations auf Row-Based machen, gar keine Frage.
Aber üblicherweise haben die natürlich in irgendeinem Register nicht so Platz, weil die Rows halt dementsprechend länger sind, damit man die gleichen Datentypen hat und so weiter.
Also wenn es um parallele Verarbeitung geht auf CPU-Ebene, hat man üblicherweise beim Column Store eine einfache Möglichkeit dadurch.
Eine Sache wurde mir sehr früh beigebracht bei relationalen Datenbanken, bei Row-Oriente-Datenbanken ist, dass sehr breite Tabellen, also mit sehr vielen Spalten, nicht so dolle sind.
Macht natürlich Sinn, wenn du, auch wenn du nur eine Spalte in einer Row-oriented Datenbank lesen möchtest, dass du deine ganze Zeile lesen musst und dann deswegen deine 900 oder 1000 Spalten hast.
Hast du ja üblicherweise nicht, weil du ja normalisierst und durch die Normalisierung solltest du eigentlich gar keine Tabellen mehr am Ende haben, die ganz viele Spalten haben.
Ja, ja, Theorie hin oder her.
Bei der Spaltenorientierten Datenbank ist das völlig egal.
Denn du kannst ohne Probleme eine Tabelle mit 1000 Spalten haben, weil der Aufwand wird dadurch bestimmt, wie viele Spalten du liest.
Wenn du jetzt nicht dauerhaft 1000 Spalten gleichzeitig liest, dann kann deine Tabelle wirklich Millionen Spalten haben.
Das ist kein Problem, denn es geht wirklich nur darum, wie viele Spalten liest du.
Natürlich Aggregationen oder ein Top-N-Ranking nach Aggregationen, all diese ganzen Thematiken, die für klassische BI, klassische Analytic-Workloads relevant sind, da kommt so eine Datenbank wie Clickhouse oder BigQuery oder sowas nicht ins Schwitzen, denn genau dafür sind die gebaut.
Was du jetzt noch erwähnt hast, mit dass man unendlich viele Columns haben kann, ganz klassisch denormalisiert, da ist eben auch ganz wichtig, dass es die Komprimierung gibt.
Weil sonst hättest du ja ganz viele Nullwerte.
Sagen wir mal, du hast irgendwie 3000 Spalten, weil du 3000 Felder hast, dann wirst du wahrscheinlich ganz viele Einträge haben, wo ein Feld nicht gesetzt ist.
Keine Ahnung, weil ein JSON dahinter liegt und theoretisch kannst du da halt alles reinschreiben und für jedes neue Feld machst du eine eigene Spalte.
Dann hast du Spalten, wo ganz, ganz viele Null-Values drinnen sind.
Durch die Komprimierung werden die aber eigentlich nicht gespeichert.
Weil wenn du jetzt fünf Werte hast, konkrete, und danach kommt eine Million mal Null, also nicht bekannt, dann speicherst du natürlich nicht eine Million mal Null ab, sondern komprimierst die Nullwerte weg und hast dann nur fünf Werte abgespeichert.
Und so kannst du das erreichen, dass du eigentlich kein Limit auf der Anzahl der Spalten hast.
Jetzt kann man sich fragen, warum schippen wir denn nicht immer nur Kolumna Storages in Produktion für meine Webseite, denn ich baue ja das nächste Unicorn.
Ich habe natürlich Milliarden von Benutzern, deswegen wird meine Datenhaltung auch sehr, sehr groß.
Immer wenn man sich die Frage stellt über OLTP und versus OLAP, dann hat das natürlich alles immer was mit Trade-Offs zu tun.
Wo wir gesagt haben, wenn es um schnelle Transaktionen gehen soll, um kurze Transaktionen, um schnelle Point-Lookups, da sind halt OLTP-Datenbanken deutlich stärker und OLAP-Datenbanken sind häufig leselastiger.
Sie nutzen Snapshot oder Badge-Vorgänge, um Daten zu schreiben.
Wenn es um schnelle Insert geht, sollte man lieber Row-Based-orientierte Datenbanken nutzen.
Ähnlich bei der Latenz.
OLTP zielt auf Millisekunden Latenz ab für einzelne Vorgänge.
OLAP selbst toleriert eher höhere Latenz, weil sie sind optimiert für Durchsatz, für große Scans, für Parallelität.
Das muss man halt schon wissen, bevor man sowas einfach in Produktion schipp und sagt, warum kommt meine Clickhaus-Query über 3 Milliarden Rows nicht schnell zurück.
Ich habe doch beim Wolfio und Andi gelernt, das ist doch Spaltenorientiert, das musst doch jetzt schnell gehen.
Man muss sich das ja auch nur bildlich vorstellen, wenn du jetzt ein Update denkst in so einem Column Store und du änderst jetzt eine Zeile oder du fügst eine neue Zeile hinzu und du hast eine Million Spalten, dann musst du diese eine Million Spalten, die ja einzeln abgespeichert sind, musst du überall einen Wert dranhängen.
Das heißt, du musst, je nachdem, wie viele Spalten du hast, verschiedene Blöcke wieder angreifen und dementsprechend ändern.
Hingegen bei einem Row-Based speicherst du einfach die gesamte Zeile hinten dran, append von deinem Block und that's it.
Wenn du jetzt an den Use Case denkst, wie zum Beispiel irgendeine Webseite und du speicherst jetzt deine Cookies von den Usern, weil die ja logged in sind, in einem Column-Based Store und in dem Cookie hast du immer den Timestamp drin, die letzte besuchte Webseite und vielleicht irgendwelche andere User-Informationen.
Mit jedem Klick auf der Webseite müsstest du dann zwei oder drei Spalten updaten.
Jetzt sind die komprimiert auch noch.
Das heißt, du musst die mal dekomprimieren, musst den Wert finden, irgendwo zwischendrin von deinem User, von diesem Cookie, musst dann in der Spalte den Wert ändern, den Timestamp, dann gehst du zur nächsten Spalte, Millionen von Einträgen, dekomprimierst die, suchst dir wieder den Wert raus, was ist die Last Visit Page von dem User, änderst Doten in String, komprimierst danach wieder alles, legst es wieder kompliziert ab.
Also man merkt schon, wenn man viele Updates hat auf zeilenbasierten Inhalten, dann ist natürlich Column-based einfach ein falsches Format.
Das heißt, man muss schon genau wissen, was ist der Workload, um dann zu entscheiden, vor allem die Row-Based, Column-based und genau darum hat Hana zum Beispiel auch die Wahl zwischen den zwei Herangehensweisen, weil du weißt, ja, was habe ich für einen Workload, habe ich OLAP, habe ich OLTP, dementsprechend kann ich dann Row oder Column-Based auswählen, wenn ich die Tabelle erstellt.
Kennst du den Digmar und den Hasso eigentlich persönlich?
Ich habe den Hasso einmal erlebt, ich glaube, es war ein Workshop oder so einer kleinen Konferenz irgendwo.
Er war dann schon ziemlich alt, war interessant, er hat nämlich in seinem Alter noch damals die Storage Engine von Hana erklärt, die damals noch sehr wissenschaftlich war.
Und zwar wirklich, er hat sich wahnsinnig gut ausgekannt, das war unglaublich.
Was aber auch interessant war, er hat es nicht geschafft, selber die Folien weiter zu klicken, sondern hat einen Assistenten mit dabei, der ihm die Folien weitergeklickt hat.
Aber er hat die Folien auf jeden Fall perfekt erklärt.
Also so viel Werbung, wie du für HANA machst, habe ich das Gefühl, dein nächster Job wird SAP-Konsultant.
Nicht, dass du dann Abo abschreibst.
Ja, ich spreche ja von der Zeit, wo Hana noch überhaupt nicht produktiv im Einsatz war, aber man muss sagen, dass SRB damals mit In-Memory Stores, ist ja ein In-Memory-Store, schon einiges abgeliefert hat.
Und es gab da eigentlich in der Wissenschaft zwei große Systeme in Memory, drei, würde ich mal sagen, eines aus München und eines natürlich vom Stonebreaker.
Und da hast du Plattener war da auch so ein bisschen in dem Game drin und hat da wirklich viel mit seinem Hasso-Platner-Institut weiterentwickelt.
Und was dann eben später daraus geworden ist, ist, was heute HANA ist.
Aber da sind natürlich viele, viele Jahre Wissenschaft auch dahinter, hinter dem ganzen System.
Jetzt hast du dich im Juni 2014 mal hier in den Podcast gestellt und hast gesagt, wieso nutzt du eigentlich alles Datenbanken?
Können wir nicht mehr so gut machen.
Hast du es 2014 gesagt?
Ja, im Juni 2014 kam die Episode 129 raus.
Da wo du dich hier hingestellt hast, hast du gesagt, Datenbank.
Ich glaube nicht, dass das 2014 war.
Oh, 2024.
Entschuldigung.
Ich hat ein bisschen gebraucht.
Wir nehmen an einem Sonntag auf, mein Hirn ist also auch noch im Wochenende.
Das scheint so ein Pattern zu sein.
Kubernetes hast du kürzlich auch in einem Interview so um zehn Jahre irgendwie verschätzt auf 2011 oder so.
Naja, Kubernetes kam 2014 raus.
Also das passt dann schon noch.
Wie dem auch sein, jetzt lass mich mal zu Ende reden hier.
Du unterbrichst mich.
Hast du das in deiner Erziehung nicht genossen, dass man Leute nicht unterbrechen soll?
Also.
Ich sage jetzt nicht, was man in Tirol in der Erziehung mitbekommt, wenn es um deutsche.
Ich tue sie schon wieder.
Es ist unglaublich.
Du hast dich hier hingestellt und hast gesagt, wir brauchen keine Datenbanken, wir brauchen Files.
2014.
2014 plus minus zehn Jahre spielt bei deinem Alter keine Rolle mehr.
Dann lass uns doch mal ganz simpel starten.
Wenn wir über Row-based und Cum-Based sprechen, wo siehst du CSV?
Ja, CSV ist Row-Based, ganz klar.
Und das ist ja das, was ich eigentlich am Anfang auch erwähnt habe.
Man spricht immer von Road-Based-Datenbanken.
Aber wir sprechen eigentlich von dem Datenformat in Files.
Datenbanken speichern ja eigentlich auch im Endeffekt alles in Files ab.
Und so kann man natürlich auch selbstständig Files abspeichern.
CSV zum Beispiel.
Ganz klassisches Road-Based Format.
Dreckiges Format ist nicht standardisiert, du hast kein Schema, es ist einfach nur grausam.
Und eigentlich will man das alles nicht machen.
Naja, nehmen wir mal ein paar Vorteile von CSV.
Es ist unglaublich einfach, weil zum Beispiel so Sachen wie Kompression finden außerhalb statt, ja, durch GZIP und so weiter und so fort.
Und es ist enorm breit unterstützt.
Und ich bin mir nicht sicher, ob es was leichteres zu debuggen gibt als CSV.
Ja, aber du sagst ja schon richtig, debuggen, weil debuggen ist immer damit verbunden.
Weil CSV ist einfach ein dreckiges Format.
Es ist nicht definiert, was ist ein Anführungszeichen, was ist ein Beistrich, äh, Beistrich verstehst du dir nicht, Semikolon, Strichpunkt in Österreich.
Diese ganzen Trennungszeichen und so weiter, es ist einfach nichts definiert und darum ist es ja auch nicht möglich, einfach ein CSV zu öffnen in deinem Excel und die richtigen Daten zu haben.
Du musst dir im Vorhinein definieren, was sind die einzelnen Trennzeichen, was ist ein Komma bei einem Preis, bei einem Integer und die ganzen Dinge.
Und erst dann kannst du damit arbeiten.
Also unstandardisierter und dreckiger geht es eigentlich gar nicht mehr, aber ich gebe dir recht, es ist sehr einfach und es versteht halt jeder mehr oder weniger.
Aber jetzt auf technischer Ebene, würde ich mal sagen, zum automatischen Verarbeiten ist es einfach ein dreckiges Format.
Was ist dann der Grund, warum das eigentlich der de facto Standard für den Austausch, Export, Import für viele, sehr viele Firmen ist?
Ja, ich weiß auch nicht, warum Windows das Standard Operating System geworden ist.
Es gibt Sachen, die muss man nicht verstehen.
Weil immer noch nicht das Jahr des Linux-Desktops gekommen ist.
Relativ einfach.
Ich würde jetzt gerne sagen, vielleicht hat es was mit der Bono-Industrie zu tun, weil VRS hat sich auch durchgesetzt, das schlechteres Format wegen der Bono-Industrie heißt es immer.
Vielleicht spielten die da auch irgendwie mit.
Bei CSV, keine Ahnung.
Da kann jetzt keine Link herstellen.
Mich interessiert jetzt echt der Link von Windows zur Porno-Industrie, aber ist auch egal.
Dann lass uns mal zu einem etwas more sophisticated File-Format kommen.
Und zwar fliegt eine Sache öfter über meinen Bildschirm in letzter Zeit.
Und zwar ist das Apache-Paket oder Paket.
Ich weiß immer noch nicht, wie es richtig ausgesprochen wird.
Aber es ist mir auch egal.
Ich glaube, das eine ist Deutsch und das andere ist dann Französisch?
Eine französische hätte jetzt gesagt, aber ich glaube, die English-Speaking-Leute sagen auch Paket, meines Wissens.
Für die Leute, die es noch nicht gehört haben, nur mal ganz kurz, was ist das eigentlich?
Wir sprechen hier über ein binäres Fileformat, über ein binäres Open Source-File-Format, was standardisiert ist und was ein Calumna-Storage-Format für Analysesysteme ist.
Die ganze Sache wurde 2013 von Twitter und Claudera entwickelt, auf Basis eines wissenschaftlichen Papers von Google, wo es um Dremel geht.
Wer Google Dremel nicht kennt, Google Dremel ist die Abfrage-Engine, die aktuell bei Google BigQuery verwendet wird.
Und Claudera war damals eine Firma, also 2013 war Claudera eine Firma, die haben eine Hadoop-Distribution rausgebracht.
Ähnlich wie bei Linux gab es bei Hadoop auch fertige Installationspakete mit so ein paar Eigenheiten und Claudera war eine Firma, die hat so eine rausgebracht und Twitter war so ein Heavy Hadoop-User.
Und da haben die gesagt, hey, cool, dieses binäre Format Calumnar Storage, das brauchen wir.
Also hat Twitter und Claudera das Fileformat für das Hive-File-System entwickelt, denn genau da wurde es genutzt.
Cladera gibt es übrigens immer noch.
Also die hatten damals so die Distro, sind vor allem im industriellen Umfeld einfach weit verbreitet, immer noch meines Wissens, weil sie halt Sachen vereinfachen.
Und wenn du halt eine Firma bist, die jetzt weniger Tech-Knowledge und Kompetenz hast, dann setzt du halt gerne auf so Out-of-the-Box-Lösungen oder die, die das halt einfach weg abstrahieren.
Da war Cloudera eigentlich immer stark.
So, und jetzt kann man sich die Frage stellen, hä, wenn ich doch eine Datei habe, wie baue ich denn ein Columnar Storage-Format?
Und das ist nämlich ganz interessant.
Und warum das jetzt interessant ist, kommen wir gleich zu, was das nämlich für einen praktischen Anwendungsfall in der aktuellen Industrie mit Kafka und Co., wo das eingesetzt wird.
Denn Apache Paket oder Parkett hat ein paar Designprinzipien.
Auf der einen Seite ist das Spaltenorientiert innerhalb von sogenannten Row Groups.
Was ist eine Row Group?
Eine Row Group besteht aus einem Cum-Chunk für jede Spalte.
Das hört sich total komisch an.
Aber im Endeffekt geht es darum, stellt euch vor, wir haben eine Calumnar-Tabelle und diese Tabelle selbst wird nochmal gesplittet, also nochmal partitioniert.
Innerhalb jeder Partition werden die Daten spaltenweise gespeichert.
Ich nehme mal ein sehr doofes Beispiel.
Stellt euch vor, Deutschland, Deutschland hat 16 Bundesländer.
Wir speichern jetzt alle Postleitzahlen und alle Einwohner und so weiter und so fort in einer Calumna-Tabelle.
Dann könnte man sagen, okay, es gibt 16 Rowgroups.
Es gibt eine Rowgroup Nordrhein-Westfalen, eine No-Group, eine Rowgroup Saarland und so weiter.
Das bedeutet, die Calumar-Tabelle wird nochmal horizontal partitioniert.
Das hat ein paar Vorteile.
Unter anderem kann jede Rowgroup von einem Thread verarbeitet werden, weil jede Rowgroup unabhängig ist.
Für jede Rowgroup selbst werden Metadaten gespeichert, wie zum Beispiel die Min-Max-Werte, Statistiken oder die Anzahl von Null werden.
Das hat natürlich zum Vorteil, wenn jetzt der Wolfgang sagt, gebe mir alle Einwohner, wo die Postleitzahl mit 5 anfängt, da kann man sagen, größer 5000 oder größer 50.000, in Deutschland hat ja in der Regel 5 Stellen, dann wird die halbe Datei einfach gar nicht mehr gelesen, weil man einfach nur in den Metadaten nachgucken kann, welche Rowgroup hat denn welche Min-Max-Werte.
Und so kannst du relativ einfach über die Datei seiten, ohne die ganze Datei zu parsen.
Vielleicht zur Einordnung, wir sprechen da von Rowgroups in der Größenordnung von so mehreren hundert Megabyte.
Oder Default ist, glaube ich, um die 100 Megabyte.
Das heißt, da hat schon einiges Platz, so in 100 Megabyte, vor allem wenn dann noch irgendwas komprimiert wird oder so.
Also es sind schon große, große Gruppen.
Ja, Rowgroup sind das hier gerade nicht vorteilhaft zum Thema Kompression.
Da würde man eher sagen, das ist ein Trade-off oder ein Sweet Spot, weil auf der einen Seite, je größer eine Rowgroup ist, desto besser kannst du die ganze Sache natürlich komprimieren.
Das hatten wir ja gerade schon bei Columnar Storages gesagt.
Umso mehr Datensätze mit den gleichen Datentypen man hat, desto größer kann man die ganze Sache komprimieren.
Aber bei zu großen Rowgroups kann man natürlich weniger parallelisiert die ganze Sache verarbeiten.
Finde ich einen schönen Sweet Spot.
Und eine andere Sache, die Parkett auch sehr gut macht, sind die Metadaten.
Denn jede Parkettdatei hat Metadaten zu den Rowgroups.
Die sind aber nicht im Header, die sind nämlich im Footer.
Die Datei beginnt mit einem Header, der dann direkt auf den Beginn des Footers verweist.
Und im Footer befinden sich die Metadaten mit Beschreibung der Datenblöcke.
Jetzt kann man sich fragen, hä, was ist das denn für ein Vier Elefant?
Ich mache die Datei auf und kriege erstmal ein Pointer auf eine andere Stelle in der Datei, um dann weiterzulesen.
Was ist das für ein Videofund?
Ja, ganz einfach.
Und zwar, wenn die Metadaten im Footer sind, dann werden die Metadaten auch erst geschrieben, wenn die ganze Datei geschrieben wurde.
Das bedeutet, man kann die ganze Datei in einem Stream wegschreiben und ist somit ideal für verteilte Systeme wie Hadoop oder Amazon S3 oder ähnliches.
Und es ist kein Fullscan der Datei notwendig, um zu wissen, was ist denn in der Datei so drin.
Denn im Footer in den Metadaten steht zum Beispiel das Schema, die Anzahl der Rowgroups, die Position jeder Rowgroup, die Min-Max-Werte der Statistiken pro Spalte, Kompressionsinformationen, Encoding-Informationen und so weiter und so.
Also das ganze Dateiformat ist wirklich für Write-Runs-Read-Many optimiert.
Und da sind wir natürlich dann jetzt wieder im ganzen Data-Lake und ich sag mal großen Datenuniversum, wo es dann wirklich um Millionen oder Milliarden von Datensätzen geht.
Also in dem ganzen Olaub-Bereich.
Aber jetzt ist ja Paket keine Datenbank, sondern nur ein Format, wie die Dateien abgespeichert werden.
Ja, genau.
Also ich meine, es ist selbst nur ein Dateiformat, das bedeutet die Partitionierung deiner Paketateien, die müsstest du, wenn du Paket alleine nutzt, durch Verzeichnis- oder Dateikonventionen irgendwie managen.
Ja, Hive oder S3 hat das ganze Zeit lang so gemacht, dass du sagst, okay, du partitionierst deine Daten anhand der Tage oder sowas.
Wenn du jetzt zum Beispiel Logdateien in Paket speicherst, dann hast du einen Ordner von mir aus das Datum von heute und da schreibst 35 Paket-Dateien rein.
Und wenn du auf den nächsten Tag gehst, dann machst du neuen Ordner und so weiter.
Das ist eine Art von Partitionierung.
Aber es gibt von Haus aus in Paket selbst kein Orchestrierungsmechanismus.
Aber was sind jetzt Use Cases, wo ihr Paket wirklich einsetzt, wenn das nur ein Fall ist, was ich eigentlich schreibt?
Naja, Use Case sind halt alles Time-Series-Datenbanken, Logs.
Von mir aus einfach Event-Logs, also sowas wie Event-Sourcing, kannst ja ein Paket super reinschreiben auf hochfrequentierte Systeme.
Alles das, was man, ich sag mal, Archivdaten macht, alles, was du auf Object-Storage fahren würdest, alles Data-Lake-Technischer, würde ich fast sagen.
Also alles, was mich nicht umbringt, wenn ich mal eine Zeile verlieren sollte, ist so in der Richtung, oder?
Also ich mache jetzt keine Bank auf Paket-Files.
Genau, wenn du Milliarden von Daten schreibst, dann verändert ein fehlender Datensatz in der Regel nicht die große Statistik.
Klar, wenn meine Log-Files jetzt Fehler beinhalten und ihr möchtet rausfinden, ist ein Fehler drin oder nicht.
Und ich lösche den Fehler, ist natürlich schlecht.
Aber es zerstört mein Business trotzdem nicht.
Aber in der Regel, wenn du ein hochfrequentiertes System hast, hast du den Fehler nicht nur einmal, sondern hunderttausend Mal und dann ist es irrelevant, ob du es 100.000 Mal oder 100.000 und zwei hast.
Jetzt ist es aber so, jetzt schreibst du ganz viele Daten.
Und jeder, der das schon mal über eine gewisse Zeit gemacht hat, der weiß, uh, immer wenn ich Dateien in Ordner speichern und anhand von Ordnern Namen partitioniere oder Object-Prefixes, wie es dann bei Amazon S3 und so weiter oder Object Storage heißt, irgendwann füge ich eine Spalte hinzu, dann verändert sich das Schema oder es findet eine Evolution des Schemas statt.
Und da fängt irgendwie jeder an, da so eine Art Management-Layer drauf zu bauen.
Und dafür gibt es bei Paket selbst gar nichts.
Und um dieses Problem zu lösen, gibt es ein weiteres Apache-Projekt.
Wer hätte es gedacht?
Wie viele Apache-Projekte gibt es eigentlich?
Das nennt sich Apache Iceberg.
Es ist ja historisch eigentlich auch immer so gewesen.
Man hat ja irgendwie ein Problem.
Alle Leute finden eine Lösung dafür, bauen sich da selber eine Management-Lösung für die Paket-Files.
Oder andere Files gibt ja auch Avro und andere Formate.
Also, Paket ist jetzt nicht das einzige klassische Format, um sowas abzuspeichern.
Je nach Ökosystem gibt es halt andere Hive war dann eher auf Avro zum Beispiel.
Auf jeden Fall kommt dann halt irgendwer um die Ecke und sagt meistens, ich habe eine allgemeinere Lösung für eure ganzen eigenen Selbstentwicklungen und das war halt Iceberg.
Und Iceberg ist ein Managementsystem von diesen Dateien, der nochmal eine Ebene darüber setzt über Parquet und das Management übernimmt.
Das heißt, weiß, wo liegt welche Datei, welche Bereiche liegen, wo, wo kommen neuen Dateien rein.
Wer schreibt diese Dateien?
Also, das ist auch so ein Gateway an sich.
Man schreibt dann Dateien über Iceberg und Iceberg weiß dann, okay, schreiben gerade zwei User vielleicht gleichzeitig, auch wenn es eine Änderung gibt, man kann darüber auch Änderungen abbilden.
Also einfach so ein Managementsystem oben drüber, um diese vielen Paket-Files überhaupt managbar zu machen.
Und gemeinsam ist es dann ein stabiles System, was eben auch gewisse Sicherheitskriterien dann anbietet, dass eben nicht passieren kann, dass irgendwer anderer gerade mein S3-File, mein Paket-File löscht und ein anderer User schreibt, aber gerade drauf was oder solche Sachen.
Also gerade paralleler Zugriff ist ein großes System.
Wenn halt so simple Fragen wie beantwortet, wie zum Beispiel, welche Dateien gehören denn zu welcher Tabelle?
Ja, oder zu welchem Schema?
Ohne die Datei.
Also, das kannst du halt bei Iceberg abfragen.
Und ich bin ja ein Mensch, der auf einfache Analogien steht.
Deswegen habe ich bei der Vorbereitung nochmal kurz die AI meines Vertrauens gefragt.
Gib mir doch mal eine einfache Analogie.
Und ChatGPT hat mir was sehr Tolles rausgepackt.
Oh, wo ich sage, das kann sich jeder merken.
Paket ist wie Ziegelsteine.
Iceberg ist der Bauplan, Bauaufsicht und das Katasteramt.
Die Ziegel speichern Material.
Iceberg sorgt dafür, dass daraus ein stabiles Haus wird.
Puh, also deine Bauanalogien, naja.
Aber gut, man kann es eben im weitesten Sinne so sehen, ja.
Und das Coole an dieser Bauaussicht, wie du sie so schön nennst, ist ja, wie ich schon erwähnt habe, dass User Management auch mit dabei ist, also paralleles Schreiben und so weiter, abgefangen wird, also die Probleme, die dadurch entstehen.
Und ein sehr cooles Feature, was mir persönlich sehr gut gefällt als Datenbankler, ist sogenanntes Time-Traveling.
Das heißt, ich kann in der Histor von meinen Datenänderungen nach hinten gehen und bekomme dann den Stand von einer gewissen Zeit.
Und das hängt auch damit zusammen, wie Iceberg mit Änderungen umgeht, weil an sich Par-K-Files sind eigentlich immutable und werden nicht geändert.
Und wenn jetzt eine Änderung reinkommt, wenn du irgendwie in den User löscht, zum Beispiel irgendwo, dann wird jetzt nicht in das Paket-File hineingegangen und der einzelne User wird gelöscht, sondern es wird das gesamte Paket-File kopiert und der User, der eben rausfliegen soll, der wird gelöscht.
Und sobald das Paket-File neu geschrieben wurde, mit empfehlenden User und alles safe auf Platte ist, dann switcht Iceberg quasi um, setzt den Pointer um auf die neue Datei und genau zu diesem Zeitpunkt ist dann die neue Datei gültig und die andere nicht mehr.
Und nachdem ich aber dadurch die Historie behalte, kann ich eben durch meine Zeit traveln und kann auch alte Datenstände auslesen.
Und das ist auch ein sehr großer Vorteil über diese Snapshot-Technologie bei Änderungen, dass mir das Ganze ermöglicht wird.
Und gerade wenn es um analytische Daten geht, ist es natürlich sehr praktisch, wenn ich sagen kann, ja, wie war denn das Stand vor einem Jahr und was ist dann dazu gekommen zum Beispiel?
Iceberg selbst hat sich eigentlich relativ gut entwickelt.
Also ich meine, Google BigQuery unterstützt Iceberg nativ.
Amazon MSK, das ist der Managed Kafka von Amazon, kann das.
Also eigentlich hat das fast jede Big Data Streaming-Lösung irgendwie integriert.
Also da könnte man fast sagen, ist es schon ein Standard, keine Ahnung.
Es ist zumindest ein Format, was sehr viel verwendet wird.
Eben neben Avro, ein bisschen älteres Format ist, aber auch noch viel verwendet wird.
ORC gibt es auch noch.
Also es gibt schon ein paar andere Formate und wie gesagt, je nach Ecosystem werden andere verwendet, aber gerade weil es jetzt auch mit Kafka zum Beispiel stark verwendet wird, da gibt es einen Iceberg-Connector, hat sich das Ganze schon in die Richtung entwickelt, dass das jetzt durchaus viel verwendet wird, das Ganze.
Und jetzt kann man sich mal die generelle Frage stellen, warum macht meine ganzen Quatsch eigentlich?
Warum lasse ich nicht einfach alles in meiner Clickhouse oder in meinem Kafka, warum, warum muss ich mich jetzt darum kümmern, nochmal irgendwelche Files auf Festplatte darum zu bewegen und zu managen und so weiter?
Berechtigte Frage.
Man kann auch fragen, ist das eine gute Sache, ist das eine schlechte Sache?
Ich bin ja immer da, um den historischen Ansatz zu erklären.
Das würde ich jetzt in dem Fall auch wieder mal wählen, weil man kann eigentlich fast alles historisch herleiten.
Die Datenbanken sind halt irgendwann an einen Punkt gekommen, wo es schwierig war, das Ganze noch handhaben zu können.
Vor allem, wenn man dann in die Richtung In-Memory-Datenbanken geht.
Jetzt muss ich schon wieder Hannah erwähnen, sorry, Andi.
Aber da hast du Plattner hat damals immer schon gesagt, auf das Argument, ja, aber die Speicher sind ja so klein.
Der RAM, wie kann ich denn alles im Main-Memory haben, hat der Hasu-Platten immer gesagt, wir haben keinen Kunden auf der Welt, keinen SAB-Kunden, wo nicht der gesamte Datenbestand, der Hot-Datenbestand in Memory-Platz hat.
Das war mal seine Aussage schon vor vielen Jahren, das stimmt natürlich.
Aber wenn man dann in Richtung Logs geht, dann wird es schon schwieriger, Events, wo man sehr viele hat.
Und ob man die dann in einer Datenbank oder womöglich sogar im Hauptspeicher oder auf einem sehr teuren Speichermedium abspeichert, das ist halt dann einfach kostentechnisch nicht mehr so effizient.
Und darum ist man natürlich in die Richtung gegangen, okay, ich kann billig auf S3, auf irgendeinem einfachen Storage einfach meine Daten ablegen.
In einem Paketformat zum Beispiel.
Und daraus her ist das eigentlich alles entstanden, dass man gesagt hat, okay, ich will diesen billigen Speicherplatz verwenden, ich will dort meine Dateien ablegen können, aber das soll natürlich auch irgendwie sinnvoll vonstatten gehen, damit ich mir nicht selber da irgendwie meine Fallstruktur und so weiter überlegen muss.
Darum setzt man Iceberg darüber und dann hat man ein sicheres System, was meine Daten ablegen, abspeichern kann, die aber trotzdem irgendwelche Garantien bekommen, dass ich mal nicht irgendwas mit parallelen Zugriffen kaputt mache und trotzdem auf die Daten zugreifen kann und dann mit Analysenwerkzeugen im Nachhinein die Daten auch analysieren kann.
Ja, du hast es nicht explizit angeschnitten, aber implizit.
Diese Möglichkeit mit Columnar Storage auf Filesystemen ermöglicht halt ein modulares Setup, dass man wirklich Storage und Compute voneinander trennen kann.
Und besonders im Cloud-Bereich ist das sehr relevant.
Denn wer schon mal eine Compute oder eine EC2-Instanz mit sehr viel schnellem Storage haben möchte, der muss tief in die Tasche greifen.
Und Object Storage wie AWS 3 oder ähnliches ist vergleichsweise günstig zu Hot Storage.
Und wenn man dann auch noch so Themen wie Kompression oder Tiered Storage anwendet, also Tiered Storage bedeutet, dass du zum Beispiel kurzfristige Daten hot vorhältst auf deiner SSD und Daten, die länger in der Vergangenheit liegen, dann auf immer kälteren Storage, wo die Zugriffszeiten höher sind, sei es Object Storage, sei es von mir aus auch Tape irgendwann mal, wo der Zugriff auf eine Minute hochgeht oder ähnliches.
Dann kann man natürlich überzeit deine Storage-Kosten noch weiter drücken.
Was man aber natürlich schon sagen muss, und das haben wir jetzt noch gar nicht explizit erwähnt, wenn wir so eine dateiorientierte Speicherform wählen, wie mit Baket und Iceberg auch darüber geschalten.
Wir haben da noch keine Engine, die unsere Daten analysiert.
Das heißt, man braucht zusätzlich nochmal on top irgendwie ein System, was diese Daten überhaupt verfügbar macht, weil ich kann da jetzt auf Iceberg keine SQL-Query hinsenden oder irgendein Egg-Gate rausholen.
Also das sind nur die Daten an sich.
Und die muss dann darüber irgendein Presto oder Trino heißt es heutzutage, DuckDB, Snowflake hast du auch schon erwähnt, oder BigQuery eben mit dem Storage hinten dran, dann als Engine darüber setzen, damit ich überhaupt was verarbeiten kann, prozessieren kann, meine Analysen, meine Reports dann überhaupt erstellen kann, aus meinen ganz vielen Dateien, die dann irgendwo vielleicht am günstigen Cold Storage irgendwo liegen.
Also man merkt da schon, man braucht dann schon viele Systeme am Ende, um wieder sowas zu erreichen, was man in der Datenbank out of the box bekommt.
Also wenn ich da einen Clickhouse hinstelle, da habe ich meine Query-Engine, da kann ich SQL hinschreiben, da bekomme ich sofort Antworten, da kann ich auch Writes drauf ausführen.
Wenn ich jetzt ein komplexes Baket-System habe, wo Iceberg drüber sitzt, dann sitzt noch Duck-DB drüber.
Dann habe ich schon einmal ganz viele Systeme, die miteinander sprechen müssen.
Ich muss natürlich auch irgendwie die Daten hineinbekommen, habe dann vielleicht noch ein Kafka.
Also da merkt man schon, das ist dann ein großes System, was man halt auch maintainen muss, im Gegensatz zu einer kleinen Clickhouse oder vielleicht sogar einer MySQL, die ja genauso für ganz viele Daten das auch handeln kann.
Gar keine Frage.
Oder ein Postgres.
Man braucht da die Leute dazu und auch den Use Case, damit sich das irgendwann rendiert.
Dafür ist man natürlich modular, kann verschiedene Engines verwenden.
Die Baket-Files können auch von unterschiedlichen Processing-Engines natürlich ausgelesen werden.
Ich kann meine eigenen Pipeline schreiben.
Man ist da natürlich schon flexibel.
Aber es ist halt so der Klassiker: man baut sich auch nicht selber ein Auto, sondern kauft sich vielleicht einfach ein fertiges Auto, aber ein paar Freaks, die irgendwas Spezielles wollen, bauen sich ein Auto auch selber und so.
Ähnlich ist es da halt dann auch, je nachdem, was man braucht, was man für Anforderungen hat, nimmt man halt Standarddatenbank oder eher dann irgendwie so ein komplexeres System, wo man die einzelnen Bausteine auch selber definieren oder vielleicht sogar selber programmieren kann.
Naja, du sagst jetzt auf der einen Seite Paket mit Iceberg und so weiter.
Das ist alles super viel Aufwand.
Ist es auch, gar keine Frage.
Das bedeutet aber im Umkehrschluss könnte man darauf stießen, ja, ein Clickhaus betreibe ich auch wie so eine MySQL.
Also ein Clickhaus-Cluster.
Click-House fährt man in der Regel nicht auf einer Node, sondern auf N-Nodes.
Und dann fängt es halt wirklich an, wo du wirklich jemanden brauchst, der sich konstant um deinen Click-Cluster kümmert.
Also auch ein Clickhaus-Cluster oder von mir aus auch deine Gebäude SAP Hana, die betreibt man mal eben nicht wie eine klassische MySQL auf einem kleinen Digital Ocean-Ding.
Naja, du kannst Clickhause schon auch Single-Node fahren, ist halt die Frage, was du für Ansprüche hast.
Genau, du kannst auch bei der gleichen Argumentation kannst du auch sagen, okay, ich habe nur ein Paket-File, das schreibe ich mit meiner Paket Go-Library, was ohne Probleme geht und nutzt das mit Duck-DB.
Duck-DB ist eine In-Memory-Datenbank, die ähnlich schmal gehalten ist wie SQLite.
Das bedeutet, das ist auch dein Minimum-Setup, was du nur auf deinem Desktop fahren kannst.
Also das ist ja.
Ja, aber auch wenn du es im minimalen Setup fährst, dann hast du trotzdem mehr Moving-Targets.
Dann hast du grundsätzlich mal Paket, dann hast du Iceberg drüber, dann hast du Duck-DB, dann brauchst du irgendwie ein Inchest, es muss ja irgendwas deine Daten schreiben, wie ein Clickhouse, wo All Inclusive einfach, du hast einen Docker, sage ich mal, einen Docker-Container, der läuft und der macht alles.
Hingegen bei der Paket-Variante, hast du mal auf jeden Fall mehrere Docker-Container und musst dir da die Pipelines zusammenbauen und das ist auch schon komplexer, würde ich mal sagen, auch wenn es nur sogar Single-Node angewandt wird.
Aber es ist einfach, ja, du hast halt andere Use Cases, andere Targets, die du damit ansprechen willst.
Und je nachdem, was dein System können muss, wie viele Daten du vor allem hast, was du für Ansprüche hast, dementsprechend kannst du natürlich wählen, was du verwenden willst.
Der große Vorteil ist natürlich bei so einem modularen System, du kannst klein anfangen.
Du kannst mal einfach Paket irgendwo rausschreiben.
Mit einem Data Capturing zum Beispiel irgendwo und schreibst hinten einfach die Files mal raus.
Und wenn du dann irgendwie größer wirst und Probleme damit hast, dann kannst du Iceberg drüber schalten oder wirklich eine Processing Engine.
Aber am Anfang, um irgendwelche Logs zu schreiben, kannst du natürlich mal einfach starten.
Aber du kannst natürlich auch irgendwie einen Open Search verwenden und da alle Logs reinschreiben.
Das ist halt dann eher eine Out-of-the-Box-Lösung.
So, jetzt brabbeln wir hier über Calumnar Storage, Iceberg, Paket und so weiter.
Wo wird der ganze Kram denn überhaupt genutzt?
Dann lass uns mal ganz kurz in die Community schauen, was jetzt gerade hier und da so abgeht.
Erstmal eine tolle Sache, Clickhouse kann nativ Paket-Files lesen.
Das bedeutet, stellt euch mal vor, ihr habt einen Clickhaus-Cluster und stellt euch mal vor, die Nodes sind am Anschlag mit ihrem Festplattenplatz oder mit ihrem RAM.
Dann schreibt die ganze Sache doch einfach in Paket-Files auf Object Storage und Clickhaus, kann die Sache lesen.
Wahnsinn.
Natürlich, Latenzzeiten gehen ein bisschen nach oben, aber wie wir gerade gesagt haben, bei ULAP sollte es eigentlich kein Problem.
Dann hatten wir den Case für Iceberg und Paket gemacht, dass man die Datei in einem Stream schreiben kann, weil die Metadaten ja im Footer liegen.
Und somit, wer also eigentlich ziemlich viel Data-Streaming macht mit Kafka, der kann jetzt mit der Kombination mit Iceberg und Paket sogenanntes Kafka-Tiered Storage nutzen.
Denn Kafka hat ein Problem.
Kafka speichert alle Lot-Dateien auf schnellem, teuren SSD-Laufwerken in der Regel, beziehungsweise das, was du da hast.
Und mit Tier Storage wandern die älteren Kafka-Segmente auf günstigen Object Storage und da kommt dann die Nutzung mit Iceberg und Paket zusammen.
Und mein vorheriger Arbeitgeber Ivan, der ist da ganz stark in dem Business gerade drin, was die gemacht haben, die haben so noch Open Source Kafka-Plugin geschrieben.
Da kannst du mit Kafka Connect eine Iceberg-Sync schreiben und dann aus dem Stream eine native Iceberg-Tabelle lesen.
Also das ganzen Moving-Targets, die der Wolfgang da gerade beschrieben hat, die sind dann da.
Die sind aber für Consumer, für Kafka-Konsumenten, ich sag mal, transparent im Kafka-Cluster dann gehandhabt.
Natürlich auch mal wieder ein Plugin, bla bli-blub, kann alles fehlen.
Aber darum geht die Folge jetzt nicht.
So, aber keine Episode ohne deinem DevOps-Kram und deiner Lieblingsdatenbanken ist es mal ausnahmsweise nicht Redis, aber ich würde fast sagen, das zweitbeliebteste Vot grundsätzlich in den Episoden nach Redis ist Prometheus.
Was hat Prometheus zu bieten?
Naja, wir sprechen die ganze Zeit über Cloud-Kosten.
Und seit einem halben Jahr oder seit einem Jahr spricht man leider nicht mehr über Cloud-Kosten, sondern man spricht auch über Kosten über Observability.
Es gibt sehr viele Leute in der Industrie, die CTOs fragen oder auch sehr viele CTOs werden gefragt von ihrem CFO.
Wieso zahlen wir eigentlich so viel Geld für diese Infrastruktur?
Und dann wird gesagt, ja, das ist, das ist unsere Observability.
Die kostet uns 30% unseres Cloud-Budgets.
Das ist, oder teilweise 40 Prozent, ja.
Also wer mal eine große Data Dog oder New Relic-Instanz hat, der weiß, glaube ich, wie schnell man Geld verbrennen kann.
Hey, jetzt hast du schon so viele Sätze zu DevOps gesagt, zu Kosten und FinOps noch gar nicht erwähnt.
Bist du krank, Andi?
Das ist nochmal dein Lieblingswort, was sofort bei DevOps im Kosten um die Ergebnis gibt.
Ja, du wärst dich ja gegen dieses Thema, dass wir das mal in der Podcast-Episode behandeln.
Deswegen, deswegen habe ich gedacht, irgendwann gebe ich auf, verstehst du?
Irgendwann bin ich zermürbt, Wolfgang.
Aber nein.
Aktuell findet auch eine Entwicklung in den ganzen Time-Series-Thematiken bei Observability statt bei Prometheus und Thanos.
Und zwar wird dort Paket auch als TSDB-Store eingeführt.
Und zwar ist die Diskrepanz folgende.
Du hast Prometheus, was auf SSD-optimierten TSDB, also Timeseries-Datenbank-Blockformaten funktioniert.
Und das hat halt ein Clash mit den aktuellen Realitäten von Object Storage.
Object Storage ist ja in der Regel langsam.
Du musst immer, wenn du den TSDB-Block auf Object-Storage legen würdest, dann würdest du sozusagen das Overfetching betreiben und die ganze Datei lesen, was natürlich völlig unattraktiv ist.
Und Time-Series-Datenbanken möchtest du eigentlich sehr lange speichern.
Du möchtest ja mal wissen, wie hat sich meine Performance von heute zu von vor einem Jahr oder vor zwei Jahren verändert.
Dafür sind ja Time-Series-Datenbanken unter anderem da.
Und deswegen sagt man, okay, man schreibt ältere Blöcke in Paket raus auf Object Storage, dann verhindert man das Overfetching, weil man liest nur den Head, dann den Footer, die Metadaten und weiß ganz genau, welche Rowgroups man lesen kann.
Und da ist der Ansatz jetzt, dass du den Hotpass auf den SSD-optimierten TSDB-basierten Blocks lässt und alles andere, das halt immer kälter wird, immer nach hinten raus, in Parkett speicherst und dann auf Object Storage Packs.
Also wieder ein Tiered Storage eigentlich.
Tiered Storage für aktuelle, ich sag mal, Cloud Native Obsolability-Ansätze.
Die ganze Sache befindet sich gerade in der Entwicklung.
Aus eigener Erfahrung kann ich sagen, es funktioniert wunderbar.
Bei Prometheus gibt es auch eine Prometheus-Paket Working Group.
Kann man dem CNCF-Slack auch nachgucken.
Vielleicht für den einen oder anderen ganz interessant, wenn da mal ein bisschen tiefer einsteigen möchte.
Von welchen Größenordnungen sprechen, wenn wir denn da jetzt eigentlich?
Also so irgendwie Dateigrößen.
Weil es ist ja schon, wenn ihr jetzt mir so überlegt, was ich bisher so mit MySQL gemacht habe und du hast da ein paar hundert Gigabyte an Daten, hat MySQL noch überhaupt keinen Problem.
Da brauchst du noch nicht mal auf Clickhaus gehen.
Jetzt sind wir da quasi noch eine Stufe weiter.
Welche Größenordnungen kennst du denn da, beziehungsweise ab wann macht es Sinn, irgendwie so einen Tiered Storage aufzubauen?
Das ist eine sehr komplexe Frage.
Das kommt natürlich A auf deine Server-Notes drauf an und B, wie viele Metriken du speicherst.
Also jetzt für Zeitdatenbanken und dann C, wie lang hinten raus du speichern möchtest.
Was hast du nun für eine Retention-Time?
Deswegen ist die Frage gar nicht so einfach zu beantworten.
Oder vielleicht anders gefragt, wenn man jetzt mal annimmt, ich habe eine 1TB an Daten.
Ich würde mal sagen, das bekommt man mit einem Node alles noch ganz gut hin, oder?
Also kommt natürlich auf die Daten drauf an, was man genau damit machen will, aber jetzt nur so als Hausnummer heutzutage, würde ich mal sagen, Terabyte braucht man wahrscheinlich noch keine große irgendwie speziellen Systeme, Verteilungen oder sonst irgendwas.
Also ein Terabyte, wenn du das auf optimiert auf SSD hältst, das funktioniert halt schon gut, da kommt es halt drauf an, wie viel RAM hat deine Kiste.
Also wenn du auf dem Terabyte-Disk nur 100 oder 200 Gigramm hast und ziemlich viele Time-Series-Datenbank-Querys hast, dann würde ich sagen, pack mal mehr RAM nach.
Aber das hast du ebenfalls bei Clickhaus und ähnliches.
Also auf der Clickhaus.com gibt es auch Relationen, wie du Storage zu RAM skalieren solltest.
Und diese Datenbanken sind ja berühmt dafür, auf sehr günstigem Storage zu laufen, also auf Spinning-Disks, aber dann brauchst du sehr viel RAM.
Jetzt gerade RAM-Kaufen ein bisschen unvorteilhaft wegen dem ganzen AI-Hype.
Deswegen kannst du dir jetzt gerade überlegen, ob du nicht lieber ein paar Terabyte Disk SSD kaufst, um dann die Geschwindigkeit von dem RAM zu kompensieren durch eine SSD.
Aber in der Regel fährst du ja Click-Haus zum Beispiel.
Clickhaus kannst du ja sehr viel mit sehr vielen Nodes auf sehr vielen Spinning-Disks mit sehr viel RAM fahren.
So fährt sich zum Beispiel auch BigQuery.
Aber wie gesagt, RAM ist gerade ein bisschen frech vom Preis her.
Man muss ja auch dazu sagen, dass gerade jetzt bei Metriken, da bist du ja üblicherweise nicht so interessiert an den Metriken von vor zwei Jahren, sondern vielleicht eher von den aktuelleren.
Das heißt, wenn man da noch ein bisschen Partitionierung draufsetzt, so wie man es früher gemacht hat, MySQL kannst du partitionieren, zum Beispiel.
Das ist halt der Oldschool-Weg.
Da hast du trotzdem den teuren Speicher, den teuren SSD-Speicher, aber du partitionierst halt trotzdem, dass du die Hot-Daten, die halt aktueller sind, dann eigens abgespeichert, weil ein bisschen schneller zugreifbar sind und dann kommst du da eigentlich schon auch relativ weit, würde ich mal sagen, mit dem Ansatz.
Ich sag mal, bei modernen Observability-Daten und je nachdem, wie viele Metriken du hast, nehmen wir mal 30 Microservices, jeder Microservice ist in Go geschrieben oder in Java.
Da gibt es dann Time-Series-Datenbanken über deine über deine Runtime, über deine JVM, das sind schon mal irgendwie 50, 60, 70 Metriken, dann hast du noch Business-Metriken, dann hast du, also da kommt schon was ordentlich zusammen, das potenziert sich dann auf Basis deiner Anzahl von Services.
Das ist der erste Multiplikator, dann hostest du das sehr wahrscheinlich auf irgendeinem Container-Skiller Kubernetes, dann hast du da vielleicht noch weitere Metriken, die dann noch ein Label dran packen, wie zum Beispiel von welchem, von welcher Podinstanz kommt das, ja, weil jedes Label erzeugt eine neue Time-Series, die dann wieder potenziert.
Also, du bist da relativ schnell bei einer sehr, sehr großen Anzahl zeitreihen Daten und da ist das Terabyte relativ schnell voll.
Das hört sich viel an.
Vielleicht trifft das auch nicht zu auf euer Homelab, aber wenn man jetzt mal, ich sag mal, eine Webseite betreibt, wo ein bisschen was los ist mit großen System, 30, 40 Microservice, ein paar Engineering-Teams, vielleicht ein paar Server-Metriken noch, wie geht es die CPU und so.
Also da bist du relativ schnell bei sehr, sehr vielen Zeitreihen-Daten.
Wenn du das einfach in die Zeit laufen lässt, ja, dann bist du mit einem Terabyte relativ schnell dabei.
Was ich dir sagen kann, ist, mein Arbeitgeber hat das schon in Produktion.
Da geht es um Petabyte und das ist ein enormer Geschwindigkeitsboost auf Basis dieser Roblox, auf Basis der Statistiken im Meta-File und so weiter.
Ich finde dieses, deswegen habe ich das Thema auch mitgebracht.
Ich bin gespannt über die nächsten paar Jahre, wo Paket oder Parkett noch so Einsatz findet.
Ich denke, es wird mehr und mehr genutzt, auch in klassischen Systemen, weil einfach Object Storage, ich sag mal, zur Commodity geworden ist und einfach super günstig und es ist einfach super bequem.
Und wenn du dann das Overfetching vermeiden kannst und dann, weil Object Storage hat das Riesenproblem, dass es als langsam gilt.
Und das gilt nur als langsam, weil gesagt wurde, du musst das ganze Pfeil nehmen, lesen, parsen.
Und das ist natürlich jetzt ein möglicher Lösungsantrag.
Und es kommen natürlich immer mehrere Out-of-the-Box-Lösungen.
Iceberg war ja schon eigentlich so ein wichtiger Baustein, der das einfach stabiler macht, die ganze Handhabung und dann kann man auch eben, Duck-DB ist relativ einfach drauf gesetzt.
Also das Deck wird auch einfacher, main-de-nbarer heutzutage mit den ganzen Standard-Tools, die man sich früher vielleicht alles selber gebaut hat.
Aber trotzdem, ihr würd mal einfach anfangen, vor allem bei einem neuen Projekt.
Also man weiß schon, dass man wirklich gleich mal in die Größenordnung geht und dann kann man das immer nochmal umstellen.
Und ich bin sogar noch immer ein Freund, dass man, wenn man ein kleines Side-Project, das ist jetzt eh in der Größe, wo man weiß, ich habe nicht morgen eine Million User, dass man da vielleicht sogar ganz einfache Systeme, Standard Blue-Methuse, Standard MySQL, vielleicht sogar, es kommt mir schwer über die Lippen, aber vielleicht sogar am Anfang die Loks in MySQL speichert, auch wenn man das eigentlich nicht machen sollte.
Aber für einen ganz simplen einfachen Start eignet sich das immer noch sehr gut.
Ja, und ich glaube, das ist die eine Sache, die ich euch noch allen mitgeben möchte.
Nur weil wir hier über Row-Oriented versus Columnar-Oriented und Paket und Terabyte und so reden, heißt das nicht.
Dass ihr in eurer klassischen Row-Oriented-Datenbank keine Summen oder Durchschnitte querieren könnt.
Macht das, macht das so lange, wie das für euch funktioniert.
Ich habe Seitenprojekte, die haben Millionen von Zeilen in MySQL-Datenbanken, die funktionieren ohne Probleme.
Da werde ich bei Weitem keine Click-Offs aufsetzen.
Was ich aber auch sage, wenn ihr euch bei euch im professionellen Umfeld mit ein bisschen mehr Daten rumtoend, dann schaut euch doch mal Calumnar Storages an.
Ein Beispiel, was ich aus einem internen Test nehmen kann.
Wir haben einen sehr, sehr großen Elastic Search Cluster.
Wir haben einen Proof of Concept gemacht mit Clickhaus, Columnar Storage für Logs und es hat eine Kompression von 5,5 Mal.
Das bedeutet, wir können den Cluster echt zusammen dampfen, wenn wir die gleiche Load auf einem Columnar Storage fahren.
Solche Hebel könnt ihr da machen.
Und besonders mit Object Storage und Paket und so weiter.
Probiert da mal ein bisschen rum.
Da könnte in Zukunft einige auch finanzielle Hebel für euch und für euren Arbeitgeber oder für euer Projekt verborgen liegen.
Das heißt jetzt nicht, dass ihr alles da umbauen müsst, aber schaut euch das einfach mal an.
Und DACDB, Fun Fact, mit DACDB kannst du auch CSV und JSON-Dokumente parsen.
Das bedeutet, du lädst ja einfach DACDB runter, statt es auf deinem lokalen Rechner und gibst dem einfach ein Ordner voll JSON-Dokumente.
Du kannst da schön SQL drauf fahren.
Kann ich nur jedem empfehlen.
Schau euch mal DAC-DB an.
Und da haben wir jetzt auch wieder die Brücke zu dem Eingangsstatement von dir.
Das skaliert nicht.
Genau.
Und muss man immer auf was Neues setzen.
Man kann auf was Neues setzen.
Ihr habt gerade auch noch mal schnell kurz gegoogelt, was es an Blockposts gibt in dem Bereich und habt da auch Blockposts gefunden mit Prometheus auf Single Notes, Setups mit 1,5 Millionen Samples pro Sekunde und 50 Millionen Active Series.
Also sind wahrscheinlich Extremwerte natürlich, aber das gibt es grundsätzlich.
Und ich glaube, man sollte sich gut überlegen, ob man wirklich die neueste Hipster-Technologie von HackerNews einsetzen muss, nur weil mal die Datenbank in irgendeinem Use Case irgendwo vielleicht langsam ist und ob man das vielleicht nicht anders lösen kann.
Wir nehmen an meinem Sonntag auf und deswegen sage ich das das Wort zum Sonntag.
Wir verabschieden uns viel Spaß beim Experimentieren.
Bis bald und tschüss.
Und lasst uns mal wissen, was ihr so verwendet an Stacks und Hacker News-Datenbanken oder so, was gerade da draußen so rumschwirrt und cool ist.
Ciao!
