Stel.. Je speelt met het idee om een autonoom data platform op te zetten, op Europese grond, gebaseerd op open-source componenten. Een platform dat zich kan meten met de grote hyperscaler equivalenten, maar dan zonder afhankelijk te zijn van de Big Tech. Waar begin je dan? Kies je voor een Europese (public) cloud? Of alles zelf hosten op eigen (private) hardware? Ga je voor zo veel mogelijk ‘managed’ open-source componenten? Of houdt het bij IaaS wel een keertje op? Welke data-processing engine gaan we toepassen? Imagine.. You are playing with the idea of setting up an autonomous data platform on European soil, based on open-source components. A platform that can compete with the major hyperscaler equivalents, but without being dependent on Big Tech. Where do you start? Do you choose a European (public) cloud? Or host everything yourself on your own (private) hardware? Do you go for as many 'managed' open-source components as possible? Or does it stop at IaaS at some point? Which data processing engine are we going to apply?
In deze blog neem ik je mee in mijn gedachten en proces om tot een autonoom dataplatform te komen. Terug naar het begin… In this blog, I’ll take you through my thoughts and the process I followed to arrive at an autonomous data platform. Back to the beginning…
Na het nodige wikken en wegen aan de tekentafel, voortschrijdende inzichten tijdens de uitrol van diverse demo probeersels, begint er iets te vormen. De visie wordt scherper en scherper en vast komt te staan dat het platform ongeacht de onderliggende infrastructuur in elke omgeving moet kunnen ‘draaien’. En dus ook eenvoudig moet kunnen worden ‘verhuisd’.. Om die reden ben ik gestart met Docker containers: Meltano voor de ETL – of ELT, zo je wilt – plus een managed PostgreSQL database. Werkt als een trein, zeker met kleine(re) datasets. Maar een dataset met 100 miljoen rijen, dat is andere koek. After considerable deliberation at the drawing board, and evolving insights gained during the rollout of various demo experiments, something begins to take shape. The vision becomes clearer and clearer, and it becomes evident that the platform must be able to run in any environment, regardless of the underlying infrastructure. And therefore, it must also be easy to 'migrate'.. For that reason, I started with Docker containers: Meltano for ETL – or ELT, if you will – plus a managed PostgreSQL database. Works like a charm, especially with small(er) datasets. But a dataset with 100 million rows, that is a different story.
Had ik nu maar de beschikking over een MPP (Massively Parallel Processing) engine, zoals ook beschikbaar is binnen Databricks, of in Fabric, of Snowflake. Maar laat ik nou juist gebruik van Big Tech hebben afgezworen. Toch mis ik die horizontale schaling. En verticaal schalen is nou niet bepaald geschikt wanneer er ‘instantly’ behoefte is aan tijdelijk meer ‘compute resources’. Daarvoor moet de server herstart worden en wat doe je met het overschot aan compute resources nadien? Een ding is zeker, die extra resources kosten in ieder geval geld. If only I had access to an MPP (Massively Parallel Processing) engine, such as those available within Databricks, Fabric, or Snowflake. But of course, I have sworn off the use of Big Tech. Yet I miss that horizontal scaling. And vertical scaling is not exactly suitable when there is an 'instant' need for temporary additional 'compute resources'. That requires restarting the server, and what do you do with the surplus of compute resources afterwards? One thing is certain: those extra resources will cost money.
Zelf een Spark cluster draaien dan maar, is immers open-source beschikbaar! Maar dat maakt het wel meteen complex, zwaar en (misschien wel te) groot. Begrijp me niet verkeerd, een Spark cluster misstaat zeker niet in grote enterprise omgevingen waar honderden miljoenen, zelfs miljarden records data moeten worden ge-processed. Ik heb echter te vaak implementaties gezien waarbij een grote, zware MPP-engine toch echt overkill is. Vergis je niet, er zit best wat ‘overhead’ op dergelijke engines. En daar komt bij dat zeker de gevestigde namen in MPP-land (Spark, Trino, Presto, Flink) in Java zijn geschreven. Een stukje legacy, voortkomend uit het succes van Hadoop rond 2010, eveneens Java. En ja, Java kun je overal op ‘draaien’, maar het staat niet per sé bekend om zijn snelheid en zuinige inzetbaarheid van compute resources. So perhaps running our own Spark cluster then? After all, it’s available as open source! But that immediately adds complexity, weight, and makes it (perhaps too) large. Don’t get me wrong, a Spark cluster certainly has its place in large enterprise environments where hundreds of millions, or even billions, of records need to be processed. However, I’ve seen far too many implementations where such a large, heavy MPP engine is simply overkill. Make no mistake, there is quite some 'overhead' on such engines. Moreover, the established names in the MPP landscape (Spark, Trino, Presto, Flink) are written in Java. A bit of legacy originating from the success of Hadoop around 2010, also Java. And yes, you can 'run' Java anywhere, but it is not exactly known for its speed and efficient use of compute resources.
De zoektocht gaat verder en wat blijkt: nieuwe(re) MPP’s worden veelal in C++ of zelfs in Rust geschreven. Vaak veel sneller en efficiënter dan hun Java concullega’s. Een beweging die ook wordt ingezet bij de grotere Tech bedrijven. Neem Snowflake of Amazon Redshift bijvoorbeeld. Alleen is dat niet open-source. ClickHouse dan? Is dat de ’holy grail’ in mijn dwaling naar de meest geschikte engine voor onze data platform oplossing? Ja en nee. Ja, het is een MPP, geschreven in C++, bovendien open-source. Maar waar ClickHouse echt in uitblinkt is ‘realtime analytics’, bij voorkeur op gedenormaliseerde IoT data, telemetrie, logs, etc. Het is minder geschikt voor zware transformaties, complexe JOIN’s tussen tabellen. Het zou dus een mooie ‘aanvulling op’ kunnen zijn, maar is niet per sé de allrounder waar ik naar op zoek ben. The search continues, and it turns out that newer MPP engines are often written in C++ or even Rust. Those are typically much faster and more efficient than their Java-based counterparts. This is also a trend adopted by the larger tech companies. Take Snowflake or Amazon Redshift, for example. However, those are not open source. What about ClickHouse? Could it be the “holy grail” in my quest for the most suitable engine for our data platform solution? Yes and no. Yes, it is an MPP engine, written in C++, and it is open source. But where ClickHouse truly excels is in real-time analytics, preferably on denormalized IoT data, telemetry, logs, and similar workloads. It is less suited for heavy transformations and complex joins between tables. So it could serve as a strong complement, but it is not necessarily the all-round engine I’m looking for.
Langzaam maar zeker begin ik de moed te verliezen. Moet ik één van de eisen – autonoom, open-source, horizontaal schaalbaar, lichtgewicht – loslaten? Of misschien wel helemaal stoppen met onze Europese data platform droom? Waarschijnlijk ben ik op zoek naar een vreemde eend in de bijt. Een vreemde eend die niet bestaat. Maar wacht eens? Een eend? Ik heb een oud-collega wel eens lyrisch horen ‘prediken’ over een oplossing genaamd DuckDB. Een lichtgewicht, open-source, kolom-georiënteerd relationeel databasebeheersysteem. Uitermate geschikt voor OLAP-doeleinden ook. Misschien wel precies wat ik nodig heb?! Slowly but surely, I begin to lose hope. Do I have to let go of one of the requirements – autonomous, open-source, horizontally scalable, lightweight? Or perhaps even abandon our European data platform dream altogether? I'm probably looking for what I would call in Dutch an "odd duck" (een vreemde eend in de bijt). Which means a wild goose chase. An odd duck that doesn't exist. But wait a minute? A duck? I once heard a former colleague enthusiastically 'preaching' about a solution called DuckDB. A lightweight, open-source, column-oriented relational database management system, also highly suitable for OLAP use cases. Could this be exactly what I’ve been looking for?
Het tikt alle boxjes aan, op eentje na: het is niet out-of-the-box horizontaal schaalbaar. Weer een droom in duigen? Nope, want laat ik nou net ons data platform oplossing ‘in spé’ hebben ge-upgrade in die zin dat native Docker containers zijn geïntegreerd in een Kubernetes cluster! En op één van de containers draait Airflow als ‘orchestrator’, in staat om data pipelines te laten processen op tijdelijke Kubernetes ‘pods’. Deze kunnen prima parallel worden uitgevoerd. Dus afhankelijk van de scope van de data pipelines, wordt horizontaal schalen met DuckDB ineens werkelijkheid. Is de data omvang uit bronsysteem X klein, dan worden meerdere – misschien wel alle – benodigde entiteiten (tabellen) gescoped. Is de data omvang uit bronsysteem Y enorm, dan kan deze scope worden teruggedrongen naar zelfs het niveau van een enkele entiteit. Op die manier kan alle compute (CPU & RAM) toe worden gekend aan die ene grote tabel met honderd(en) miljoenen rijen. It ticks all the boxes except one: it is not horizontally scalable out-of-the-box. Another dream shattered? Nope, because I just upgraded our data platform solution 'to be' by integrating native Docker containers into a Kubernetes cluster! And on one of the containers runs Airflow as an 'orchestrator', capable of processing data pipelines on temporary Kubernetes 'pods'. These can easily be executed in parallel. So, depending on the scope of the data pipelines, horizontal scaling with DuckDB suddenly becomes a reality. If the data volume from source system X is small, multiple – perhaps even all – required entities (tables) are scoped. If the data volume from source system Y is huge, this scope can be reduced to the level of a single entity. In this way, all compute (CPU & RAM) can be allocated to that one large table with hundreds of millions of rows.
De oplettende lezer denkt nu wellicht met betrekking tot het laatst genoemde voorbeeld: ‘is dat wel zuiver horizontaal schalen?’. Fair enough! Een enkele entiteit/tabel kan in deze architectuur inderdaad niet over meerdere ‘nodes’ worden verdeeld. Maar wel over meerdere threads. Dus afhankelijk van het aantal CPU cores en de hoeveelheid RAM die de tijdelijke Kubernetes pod meekrijgt, kan evengoed een enorm aantal parallelle threads worden bereikt. Dus in de bredere zin van het woord, is het wel degelijk horizontaal schalen. Het heeft bovendien het voordeel dat die parallelle threads zich allemaal binnen één machine bevinden en er geen overhead optreedt als gevolg van ‘netwerk latency’ of ‘master/worker’ multi-node architectuur. The attentive reader might now think regarding the last-mentioned example: 'is that really horizontal scaling?'. Fair enough! Indeed, a single entity/table cannot be distributed across multiple 'nodes' in this architecture. But it can be distributed across multiple threads. So, depending on the number of CPU cores and the amount of RAM allocated to the temporary Kubernetes pod, a significant level of parallelism can still be achieved. In that broader sense, it does qualify as horizontal scaling. Moreover, it has the advantage that all those parallel threads operate within a single machine, avoiding overhead caused by network latency or the complexities of a master/worker multi-node architecture.
En zo kwam alles goed! Een supersnelle, lichtgewicht engine voor de data extractie en load. Met de uitrol van PostgreSQL in combinatie met de pg_duckdb en pg_ducklake extensie is de data ook nog eens benaderbaar vanuit zowel object storage (S3 bucket) als relationele database perspectief. Handig voor de exploratie- en integratiefase, al dan niet in combinatie met SQLMesh. En voor de liefhebber kan ClickHouse hier nog aan worden toegevoegd voor directe, realtime data uitvragen. And so, everything fell into place! A super-fast, lightweight engine for data extraction and loading. With the rollout of PostgreSQL in combination with the pg_duckdb and pg_ducklake extensions, the data can also be accessed from both an object storage (S3 bucket) and a relational database perspective. This is particularly useful during the exploration and integration phase, optionally in combination with SQLMesh. And for those interested, ClickHouse can be added for direct, real-time data queries.
Meer weten? Neem contact met ons op of plan een afspraak in. Want to know more? Please contact us or schedule an appointment.
Veelgestelde vragen Frequently asked questions
1. Wat is een autonoom open-source dataplatform? 1. What is an autonomous open-source data platform?
Een data-infrastructuur gebaseerd op open-source componenten zoals Docker, Kubernetes, Meltano en DuckDB, waarmee organisaties volledige soevereiniteit over hun data en rekenkracht behouden zonder vendor lock-in van Big Tech. A data infrastructure based on open-source components such as Docker, Kubernetes, Meltano, and DuckDB, allowing organizations to maintain full sovereignty over their data and compute resources without Big Tech vendor lock-in.
2. Hoe schaalt DuckDB horizontaal? 2. How does DuckDB scale horizontally?
Door de inzet van Kubernetes pods en Airflow orchestrator kunnen pipelines parallel worden verdeeld over verschillende nodes. Grote tabellen kunnen bovendien binnen één pod over tientallen CPU-threads worden geparalleliseerd. By utilizing Kubernetes pods and the Airflow orchestrator, pipelines can be distributed in parallel across multiple nodes. Furthermore, large tables can be parallelized over dozens of CPU threads within a single pod.
3. Wat maakt pg_duckdb zo krachtig in vergelijking met traditionele databasekoppelingen? 3. What makes pg_duckdb so powerful compared to traditional database connections?
pg_duckdb koppelt PostgreSQL direct met de analytische DuckDB engine binnen hetzelfde proces. Hierdoor kun je met minimale overhead zware analytische SQL-vragen uitvoeren direct op data in object storage (zoals S3 Parquet-bestanden), zonder dat de PostgreSQL database zelf belast wordt met de zware I/O en berekeningen. pg_duckdb integrates PostgreSQL directly with the analytical DuckDB engine within the same process. This allows you to execute heavy analytical SQL queries directly on data in object storage (like S3 Parquet files) with minimal overhead, without burdening the PostgreSQL database itself with the heavy I/O and compute.
4. Waarom is de combinatie van pg_duckdb en pg_ducklake/SQLMesh efficiënter dan het overschrijven van de gehele dataset? 4. Why is combining pg_duckdb with pg_ducklake/SQLMesh more efficient than overwriting the entire dataset?
Door gebruik te maken van S3 Hive-partitionering (bijvoorbeeld per jaar) kunnen pg_ducklake en SQLMesh gerichte deltaruns uitvoeren. Alleen de partities die daadwerkelijk nieuwe of gewijzigde records bevatten worden in- en uitgelezen, waardoor de verwerkingstijd van miljoenen rijen daalt van minuten naar enkele seconden. By utilizing S3 Hive-partitioning (e.g., by year), pg_ducklake and SQLMesh can execute targeted delta runs. Only the partitions containing new or updated records are read and written, reducing processing time for millions of rows from minutes to seconds.
5. Is DuckDB geschikt als vervanger van ClickHouse of PostgreSQL? 5. Is DuckDB suitable as a replacement for ClickHouse or PostgreSQL?
Nee, ze vullen elkaar aan. PostgreSQL blijft de ideale transactionele database (OLTP) voor operationeel gebruik. ClickHouse is uitmuntend in realtime analytics op binnenstromende datastromen (zoals IoT en logs). DuckDB is de perfecte, lichtgewicht allrounder voor complexe data-integratie, batchverwerking en interactieve analyse (OLAP) binnen het platform. No, they complement each other. PostgreSQL remains the ideal transactional database (OLTP) for operational use. ClickHouse excels at real-time analytics on streaming data (like IoT and logs). DuckDB is the perfect, lightweight all-rounder for complex data integration, batch processing, and interactive analysis (OLAP) within the platform.