3.5: Data Pipeline and Architecture Patterns
- Page ID
- 48039
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\( \newcommand{\dsum}{\displaystyle\sum\limits} \)
\( \newcommand{\dint}{\displaystyle\int\limits} \)
\( \newcommand{\dlim}{\displaystyle\lim\limits} \)
\( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)
( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\id}{\mathrm{id}}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\kernel}{\mathrm{null}\,}\)
\( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\)
\( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\)
\( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)
\( \newcommand{\vectorA}[1]{\vec{#1}} % arrow\)
\( \newcommand{\vectorAt}[1]{\vec{\text{#1}}} % arrow\)
\( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vectorC}[1]{\textbf{#1}} \)
\( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)
\( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)
\( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\(\newcommand{\longvect}{\overrightarrow}\)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\(\newcommand{\ket}[1]{\left| #1 \right>}\)
\(\newcommand{\bra}[1]{\left< #1 \right|}\)
\(\newcommand{\braket}[2]{\left< #1 \vphantom{#2} \right| \left. #2 \vphantom{#1} \right>}\)
\(\newcommand{\braopket}[3]{\left< #1 \vphantom{#2}\vphantom{#3} \right| #2 \vphantom{#1}\vphantom{#3} \left| #3 \vphantom{#1}\vphantom{#2} \right>}\)
\(\newcommand{\qmvec}[1]{\mathbf{\vec{#1}}}\)
\(\newcommand{\op}[1]{\hat{\mathbf{#1}}}\)
\(\newcommand{\expect}[1]{\langle #1 \rangle}\)
\(\newcommand{\dfn}[1]{\emph{\textbf{#1}}}\)
Data Pipeline and Architecture Patterns
Designing a robust data ingestion pipeline often involves choosing an architecture pattern that suits the organization’s needs. Over time, several data pipeline architecture patterns have emerged as best practices. In this section, we will describe some common pipeline and architecture patterns, using diagrams and examples to illustrate how data flows from sources to targets in each case:
-
Traditional ETL Pipeline (On-Premises Data Warehouse) – A classic pattern where data is periodically extracted from sources, transformed, and loaded into a centralized enterprise data warehouse.
-
Modern ELT Pipeline (Cloud Data Lake/Lakehouse) – A pattern leveraging cloud storage and compute, where raw data is landed in a data lake or “lakehouse” and transformed in-place for different use cases.
-
Lambda Architecture – A hybrid pattern combining batch and real-time processing to provide both historical deep computation and low-latency updates.
-
Kappa Architecture – A streaming-oriented pattern that handles both real-time and batch needs via a single streaming pipeline (treating batch as replays of the stream).
-
Event-Driven Architecture with Message Queues – Using a central event broker (e.g., Kafka) as the backbone, feeding multiple downstream systems and analytics in a publish-subscribe model.
-
Data Integration Hub (Enterprise Service Bus) – A centralized integration layer where data from various systems is ingested into a hub, often transformed to a canonical format, then distributed to where it’s needed.
Each pattern has its pros and cons, and they are not mutually exclusive – some organizations blend elements of each.
Let’s walk through a couple of key patterns with examples:
3.5.1 ETL-Centric Data Warehouse Pipeline
In this traditional pattern (dominant from the 1990s through early 2010s), the pipeline is geared towards feeding a relational data warehouse. The architecture typically looks like:
Sources (Operational DBs & files) → Staging → Transformation Engine → Data Warehouse → BI/Reporting
-
Data is extracted from source systems (which could be relational databases like ERP or CRM, flat files from mainframes, etc.) on a schedule. Often nightly or weekly full extracts or incremental extracts.
-
A staging area (sometimes a schema or database) is used to temporarily hold the raw extracted data.
-
A transformation engine (could be ETL software or stored procedures) applies business logic: joining data from multiple sources, cleaning, deriving new fields, summing up transactions into summary tables, etc. It basically shapes the data to match a target schema (often a star schema with fact and dimension tables).
-
The transformed data is then loaded into the data warehouse (which might be an Oracle, Teradata, or SQL Server data warehouse, etc.).
-
Once in the warehouse, the data is ready for use by BI tools for reporting and analysis. The warehouse typically contains consistent, historical data (often snapshots over time) optimized for read queries.
An example: A retail company has three operational databases (sales, inventory, and finance). Each night, an ETL job runs: extracts yesterday’s sales transactions, daily inventory levels, and new financial records. In staging, it might store them as tables. Then transformation logic: - match sales with inventory to create a fact table of sales with product details, - summarize daily sales per store for a sales fact table, - update dimension tables like product, store, customer with any changes (maybe slowly changing dimensions handling), - calculate some financial metrics or reformat data for finance fact. Finally, it loads these into a data warehouse. Next morning, analysts come and see updated dashboards of prior day sales, etc.
Pros: This pattern ensures high data quality and consistency. The warehouse is a “single source of truth” where data is integrated. Complex transformations can be done deeply (since a long batch window might allow heavy processing). It suits structured, well-defined data needs (e.g., corporate reporting). The separation of staging, transform, and warehouse provides clear modular stages.
Cons: The major con is latency – data is as fresh as the last batch, which might be 1 day old. It also tends to be inflexible: adding a new data source or attribute requires modifying ETL code and possibly the schema. It can be expensive to scale (traditional warehouses on big iron or expensive appliances). Also, because it loads only structured, predefined schema, it may not easily accommodate semi-structured data or exploratory new data sources.
Many enterprises still run such pipelines, but they often supplement them with more real-time feeds for critical data, or are evolving to newer patterns.
3.5.2 Data Lake and Lakehouse ELT Pattern
In newer architectures, the concept of a data lake has emerged – a large storage repository (often on HDFS or cloud object storage like S3) that holds data in its raw form from various sources. A lakehouse extends this idea by adding data warehouse-like management and querying to the lake (e.g., Delta Lake, Apache Iceberg, or tools like Databricks and Snowflake which can treat the lake as a warehouse).
The pipeline pattern here is often ELT:
Sources → Ingestion to Raw Data Lake (as-is) → Transformation within the Lake/Warehouse (creating refined datasets) → Analytics
Key points: - Data from sources is ingested, often continuously or in micro-batches, into a landing zone of the data lake. This could be files dropped via an ingestion service, streaming data appending to log files, etc. The data is stored as close to source format as possible (e.g., JSON logs stored as JSON or converted to Parquet but same schema). - Once data is in the lake, transformations happen using big data processing (Spark, Hive, Flink, etc.) or within a query engine that works on the lake. These transformations produce refined datasets: e.g., cleaning the raw logs into structured tables, combining data from multiple raw sources into one analytics-friendly table, etc. - The refined data might be stored as new files or tables in the lake (with a stricter schema). Because modern query engines can handle both, the difference between raw and refined is logical – raw is a bunch of maybe semi-structured data, refined are the curated tables. - Tools like Databricks’ Delta Lake or Snowflake allow the lake to have ACID transactions and table-like structure, bridging the gap between the free-form lake and traditional warehouse. Hence the term “lakehouse”. - Finally, analytics tools or data science processes can directly query the refined data in the lake (and sometimes even the raw data if needed).
Example: An IoT company collects sensor data from thousands of machines. Using a cloud data lake approach, all raw sensor readings (time, sensor ID, value, status) are dumped into a data lake partitioned by day (perhaps in Parquet files). This is done continuously via a streaming ingest. Then, daily (or continuously via structured streaming), a job reads the raw data to detect anomalies and tag them, generating a refined table of “anomalous events” per machine. It also aggregates each day of readings into hourly averages per sensor, storing that in another table. Analysts then query these refined tables to see trends, and data scientists train models from the raw or refined data as needed. They keep all raw data in case new analysis is needed later.
Pros: Extremely scalable and flexible. All data is stored – you don’t have to decide early exactly how it will be used. New data sources can be landed in the lake easily without impacting existing pipelines. With cloud storage, handling more data is just adding files. The separation of storage and compute means you can scale processing power when doing transformations (ELT). Real-time ingestion can be integrated (e.g., streaming data right into the lake). It suits big data and variety (can handle unstructured too, like images or text, not just structured tables). The lakehouse approach also attempts to give some governance – e.g., data cataloging and schema management on top of the lake.
Cons: Without proper governance, a data lake can turn into a disorganized “data swamp” where it’s hard to find or trust data. Data quality can suffer if not systematically addressed (it might store everything including bad data). Query performance on a lake might be slower compared to a tuned data warehouse (though with partitioning, indexes, etc., it's improving). Also, users might have to sift through more data (multiple versions of truth if not careful – e.g., raw vs cleaned could confuse if not clearly documented). The complexity of maintaining a big data environment can be high (though cloud managed services help).
Lakehouse tries to mitigate these cons by adding governance and performance (e.g., Delta tables with indices, schema enforcement if desired, etc.).
Architecture diagrams often show a multi-zone data lake: Raw zone (landing), Cleansed zone (transformed), Curated zone (perhaps aggregated or business-specific tables), and Analytics zone (extracted data for specific tools). Data flows through these zones via ELT processes.
This pattern is increasingly common for organizations dealing with large-scale and varied data, because it covers needs from data warehousing (structured reporting) to data science (exploring raw data).
3.5.3 Lambda Architecture (Batch + Speed Layer)
The Lambda architecture addresses a scenario where you need both real-time results and comprehensive batch computation. The idea (origin by Nathan Marz for big data) is to split the processing into two parallel layers: - A Batch Layer that computes results on the full data set, typically with high latency (e.g., MapReduce jobs on all data producing daily views). - A Speed Layer (or streaming layer) that computes real-time or near-real-time updates on recent data (and typically does not process huge historical data, just incremental). - A Serving Layer that merges the outputs from both to answer queries. Often the serving layer stores batch results and then applies real-time updates on top for queries.
In ingestion terms, data flows into both layers: 1. All raw data is appended to a master dataset (e.g., stored in a data lake or HDFS). 2. The batch layer periodically recomputes something (like a machine learning model or an aggregate) from scratch or in large batches from this master data and updates the serving DB. 3. The streaming layer takes incoming data (maybe via queue or stream) and does a running computation (like incremental updates) and updates a fast view (like an in-memory DB or caching layer). 4. Queries (or outputs) combine these – for instance, an application might query the batch-computed value and then add the speed layer delta to get the latest.
Example: A social network wants to compute the total number of mentions of a topic. Lambda approach: The batch layer (once a day) crunches all historical posts to count mentions up to the previous day. The speed layer listens to new posts streaming in and maintains a real-time count since the last batch. When someone queries the current count, the system takes the batch count (as of yesterday) plus the speed layer’s count since then. This gives an up-to-date answer without having to reprocess everything for each query.
Another example: In IoT analytics, the batch layer could compute long-term trends or retrain models nightly on all data, while the speed layer detects anomalies within seconds of events.
Pros: You get accuracy from batch (since it can do deep computation on full data) and low latency from streaming. If streaming results are approximate or might have minor errors, the batch layer will eventually override with correct global computation. It’s fault-tolerant in that sense – the batch layer is like a safety net (if you missed something in stream, batch fix it next cycle). It allows use of different tools optimized for each (e.g., Hadoop for batch, Storm/Flink for stream).
Cons: It is complex – maintaining two separate pipelines and logic (one for batch, one for streaming) is double effort. Also merging results and ensuring no double counting can be tricky. It requires more infrastructure (e.g., both Hadoop cluster and streaming cluster). Due to complexity, some have moved towards the Kappa architecture (just stream everything and recompute for batch by replaying streams).
3.5.4 Kappa Architecture (Streaming Unified) [7]
The Kappa architecture, proposed by Jay Kreps, advocates using a single stream processing pipeline for both real-time and batch processing, eliminating the separate batch layer. The idea is that you keep all data in a log (like Kafka), and for recomputation (what batch would do), you simply replay the log through your stream processor. Essentially, treat batch as just re-running the streaming process on historical data.
-
All data is ingested into a central log (immutable sequence of events).
-
A stream processing engine continuously processes events and updates materialized views or outputs (like aggregations, ML model updates, etc.).
-
If you need to recompute from scratch (batch equivalently), you can start a new consumer from the beginning of the log and recompute state.
-
Systems like Kafka + Kafka Streams or Flink support storing state and recomputing by replay.
Pros: Simpler than Lambda because there’s one code path. Only need to maintain one type of pipeline. With modern frameworks that can handle large state and event reprocessing, you can achieve similar outcomes to batch. Great for scenarios where most computations are incremental.
Cons: Replaying entire history through a stream processor can be slow (maybe slower than a purpose-built batch job in some cases), though some frameworks optimize it. If the streaming logic changes (e.g., you fix a bug), you might have to replay history to correct derived data – which is possible but must be managed. Kappa might not be ideal if your batch computation was very complex logic that is hard to do in a streaming context (though one can argue any function can be made streamable with enough work).
It fits well with event-sourced architectures where all data is events. It’s been adopted by some, especially those heavily on Kafka. For example, Netflix, Uber, etc., often lean towards streaming-first architectures (with perhaps some offline batch for heavy ML training, but all metrics and aggregations done via streaming). Kreps argued that hardware improvements and stream engine capabilities make Lambda unnecessary overhead for many use cases.

3.5.5 Event-Driven Ingestion (Pub/Sub Data Integration)
This pattern revolves around using a central event bus (like Kafka or enterprise service bus) as the heart of data ingestion. We touched on it earlier with message queues. The idea is rather than point-to-point data flows, everything publishes events to a bus and everything that needs data subscribes [8].
Architecture: - Data sources (applications, databases via CDC, IoT devices, etc.) produce events (or messages) and publish to the bus. - The bus retains events for some time and allows multiple independent consumers. - Various consumers handle different tasks: one might store the raw events in a data lake for long-term storage, another updates a real-time dashboard, another triggers alerts, another computes aggregates and publishes new events, etc. - This decoupling means the ingestion for any new requirement can tap into the bus rather than disturb sources.
Example: A bank uses an event hub for all transactions. Core banking system publishes “transaction occurred” events to Kafka. Downstream, one consumer is a fraud detection service (to check each transaction live), another updates a data warehouse by accumulating transactions for nightly reporting (or even streaming into a warehouse), another powers a mobile app with real-time feed of user’s transactions. The event-driven approach ensured all these consumers get the data they need without impacting the core system heavily or requiring multiple extraction processes.
Pros: Flexibility and extensibility – new consumers can be added without modifying producers. Real-time capability is inherent. The decoupling can improve reliability (if one consumer is down, others still get data, and the one can catch up later). It encourages a unified data pipeline for different use cases (operational and analytical blur together via events).
Cons: It requires strong governance – you need to manage schemas and ensure events are well-defined, otherwise chaos. There’s a learning curve to event-driven thinking (idempotence, ordering concerns). If not managed, it can proliferate many mini pipelines (each consumer doing their own thing) which might lead to inconsistency. But with a proper design, that’s mitigated.
This pattern is quite popular in microservice architectures and streaming data environments. It’s not mutually exclusive with Lambda or Kappa – in fact it can be the underlying transport in them.
3.5.6 Data Integration Hub and Spoke
A more enterprise-y pattern is having a central integration hub (could be an ESB – enterprise service bus – or a data integration platform). All data from sources is first fed into the integration hub, which transforms it to a canonical model, then distributes to targets (which could be operational systems or analytics stores). This is more common in operational integration but can overlap with analytical ingestion.
For example, an integration platform might take an order event from e-commerce, transform it to a standard “Order” format and send to CRM, ERP, and also to the data warehouse. This way each system doesn’t need to have custom adaptors for each source – just for the hub’s canonical format.
Pros: Less point-to-point spaghetti, more standardization. If done right, ensures consistency (everyone gets the same version of data). It often provides monitoring and control in one place. Good for ensuring data governance (one place to apply rules).
Cons: The hub can become a bottleneck or single point of failure. It also can be high latency if it queues everything through one process. Complexity in building a universal data model (canonical schema) that might not fit all needs. For analytics specifically, it might add overhead – sometimes directly feeding a warehouse is simpler.
This pattern has been around in large enterprises especially for application integration, but with the advent of easier pub/sub and modern data lakes, some aspects have shifted to those methods.
Each of these patterns might be combined. For instance, an organization might have a data lake (ELT pattern) which is fed by an event streaming bus (pub/sub pattern) that itself implements Kappa (single pipeline). Or they might have a traditional warehouse (ETL pattern) plus a real-time dashboard on a speed layer (Lambda style).
The choice depends on requirements like data freshness, types of data, existing technology stack, and skills. Importantly, a good architecture is one that meets the specific needs (no need for Lambda if you don’t require real-time and can manage with daily batch, etc., but if real-time is crucial, a batch-only ETL warehouse is inadequate).
To contextualize, many companies are currently transitioning from legacy ETL architectures to more streaming and lake-based architectures to handle big data and real-time demands.
Industry Example: Netflix’s data pipeline architecture employs a variation of the event-driven and ELT patterns. They have a unified log (event bus) that all services write to (similar to Kappa’s log). That data is landed in S3 (data lake raw zone) and also streamed for immediate processing (speed layer). They use both batch (Spark jobs on S3 data for heavy compute) and streaming (Spark Streaming/Kafka for real-time) – essentially Lambda architecture. The output of both is accessible via a data platform they provide to analysts. This way, Netflix can get quick insights (like trending shows in the last hour) and deep insights (like comprehensive recommendation model training over years of data). Such a multi-pattern approach is complex but supports their large-scale needs.
In summary, understanding these patterns helps in architecting an ingestion solution that aligns with business needs. The patterns are not one-size-fits-all; often a tailored combination is used. But they provide a blueprint for solving common challenges: ETL for reliability and structure, ELT for scale and flexibility, Lambda for mixing batch & real-time, Kappa for simplicity in streaming, and event-driven for decoupled scalability.


