Lambda Architecture vs Kappa Architecture for Big Data Cloud Platforms? Let us discuss which architecture suits best for what use cases.

Big Data – Lambda or Kappa Architecture?

Big Data Analytics stands apart from conventional data processing in its fundamental nature. In the realm of Big Data, there are two prominent architectural concepts that perplex companies embarking on the construction or restructuring of their Big Data platform: Lambda architecture or Kappa architecture. Thus, it is crucial for such companies to contemplate and decide which architectural approach best aligns with their goals.

Lambda – Architecture

Introduced in 2011 during the peak of Big Data’s prominence, the Lambda architecture remains a significant presence in the field. Despite being the older of the two architectures, it offers a more comprehensive approach by incorporating three layers: the batch layer, the speed layer (also known as the stream layer), and the serving layer.

The Batch Layer is responsible for processing the entire dataset, ensuring the generation of the most accurate results. However, this comes at the cost of higher latency due to the batch loading of data. On the flip side, the batch layer can handle complex calculations without time constraints. It stores incoming raw data and filters it for subsequent applications.

Batch runs are suitable for non-time-sensitive data that require regular updates, such as daily or weekly incremental loads. Additionally, batch runs are necessary for complete data migration or overwriting (Full Load) scenarios.

The Speed Layer operates with low latency, producing almost real-time results. It calculates real-time views that complement the batch views. The speed layer receives incoming data and provides incremental updates to the batch layer results. By implementing incremental deduction logic, the speed layer significantly reduces computational costs.

Here is a simplified depiction of the Lambda architecture, showcasing the multi-store concept and the serving layer. In this representation, there is a separate store for events within the speed layer and another store for data loaded during batch processing. The serving layer acts as a mediator, enabling subsequent applications to access the data. It is important to note that in the Lambda architecture, the serving layer can be omitted, allowing batch processing and event streaming to remain separate entities.

Here is a simplified depiction of the Lambda architecture, showcasing the multi-store concept and the serving layer. In this representation, there is a separate store for events within the speed layer and another store for data loaded during batch processing. The serving layer acts as a mediator, enabling subsequent applications to access the data. It is important to note that in the Lambda architecture, the serving layer can be omitted, allowing batch processing and event streaming to remain separate entities.

The batch views within the Lambda architecture allow for the application of more complex or resource-intensive rules, resulting in superior data quality and reduced bias over time. On the other hand, the real-time views provide immediate access to the most current data.

The Serving Layer serves as a conduit for various data queries originating from both the batch and speed layers. It receives batch views from the batch layer and near-real-time views from the speed layer, utilizing this data to facilitate standard reporting and ad hoc analytics.

The Lambda architecture effectively balances speed, reliability, and scalability. However, it is worth mentioning that while the batch layer and real-time stream handle different scenarios, their underlying processing logic often shares similarities. As a result, the development and maintenance efforts for both layers should not be underestimated.

Kappa – Architecture

Jay Kreps introduced the Kappa architecture in 2014 as an alternative to the Lambda architecture. It addresses the redundancy present in the Lambda architecture by completely removing the batch component. By eliminating the parallel operation of two pipelines, the Kappa architecture simplifies the overall architectural complexity.

In the Kappa architecture, only the speed layer, represented by an event-based streaming pipeline, remains. The fundamental concept is to handle real-time data processing and continuous data reprocessing using a single stream processing engine. This approach allows for the avoidance of a multi-layer lambda architecture while ensuring the quality of data processing is maintained.

Illustrated simplified Kappa Architecture. This architectural concept relies on event streaming as the core element of data delivery.

Illustrated simplified Kappa Architecture. This architectural concept relies on event streaming as the core element of data delivery.

In practical implementation, the Kappa architecture is commonly deployed using Apache Kafka or Kafka-based tools. Applications can directly read from and write to Kafka or an alternative message queue tool. For existing event sources, listeners are utilized to stream writes directly from database logs or similar data stores. This approach eliminates the need for inbound batch processing and reduces resource requirements.

By treating every data point as a streaming event, the Kappa architecture enables the ability to near-realtime analytics and observe the state of all data in the organization at any given point. Queries can be performed at a single location, eliminating the need to compare batch and velocity views.

However, there are challenges associated with this architecture. Data processing must be done as a data stream, leading to difficulties such as managing duplicate events, cross-referencing events, and maintaining correct operation order. While batch processing can handle retrospective consolidation of multiple data sets, these challenges persist in the Kappa architecture. As a result, implementing architectures based on the Kappa concept can be more complex compared to those based on the Lambda concept, even though the latter may appear clearer in architectural sketches.

The Kappa architecture is particularly suitable when event streaming or real-time processing use cases are predominant. It offers the advantage of having a single ETL platform to develop and maintain. It is well-suited for developing data systems that emphasize online learning and do not require a separate batch layer. The sequence of events and queries is not predefined but generated in later steps based on business logic, prioritizing speed.

Use cases – When to use which architecture?

It is important to note that Kappa architecture does not serve as a direct substitute for Lambda architecture, as there are certain use cases supported by Lambda that cannot be seamlessly migrated. The Lambda architecture is better suited for implementing complex data processes and ensuring consistently complete data provisioning compared to the pure event processing approach of Kappa. As a result, many Data Lakehouse systems are built upon the foundations of the Lambda architecture.

Requirements that clearly speak for Lambda

  • If data is to be processed ad-hoc on quasi unchanging, quality-assured databases, or if the focus of the database is on data quality and the avoidance of inconsistencies.
  • When fast responses are required, but the system must be able to handle different update cycles.

Requirements that clearly speak in favor of Kappa:

  • When the algorithms applied to the real-time data and the historical data are identical.
  • If the analytics system is online learning capable and therefore does not require a batch layer.
  • The order of events and queries does not matter, but the stream processing platforms can exchange data with the database instantly at any time.

If your requirements prioritize a highly reliable Data Lakehouse update process and efficient machine learning model training for accurate event predictions, the Lambda architecture is the recommended choice. By leveraging both the batch layer and the speed layer, the Lambda architecture ensures minimal errors and optimized processing speed.

Alternatively, if you seek a streamlined Big Data architecture that excels in handling distinct and continuously emerging events (e.g., fueling data for numerous mobile applications), the Kappa architecture is the ideal solution for data platforms with the main purpose of real-time data processing. Its focus on unique, ongoing events allows for effective and responsive data processing.

Google Cloud run with Infrastructure by Code using Terraform

Google Cloud Run – Tutorial

Es gibt Gelegenheiten, da ist eine oder mehrere serverlose Funktionen nicht ausreichend, um einen Service darzustellen. Für diese Fälle gibt es auf der Google Cloud Plattform Google Cloud Run. Cloud Run bietet zwei Möglichkeiten Container auszuführen. Services und Jobs. In diesem Beispiel wird ein Google Cloud Run Service mittels Terraform definiert, welcher auf Basis eines Scheduler Jobs regelmäßig aufgerufen wird. Cloud Build wird dazu genutzt den aktuellen Code auf den Service zu veröffentlichen.

Der nachfolgende Quellcode ist in GitHub verfügbar: https://github.com/fingineering/GCPCloudRunDemo

tl;dr

Mittels Terraform können alle notwendigen Komponenten erstellt werden, um einen Cloud Run Services aus einem Github Repository kontinuierlich zu aktualisieren. Als Beispiel wird ein stark vereinfachter Flask Webservice verwendet. Durch den Cloud Scheduler wird dieser Service regelmäßig aufgerufen.

Voraussetzungen

Bevor der Service aufgesetzt werden kann, müssen einige Voraussetzungen erfüllt sein. Es wird ein Google Cloud Project benötigt, sowie ein Github Account. Auf dem Computer, welcher zur Entwicklung verwendet werden soll, müssen Terraform, Google Cloud SDK, git, Docker und Python installiert sein. In diesem Beispiel wird Python verwendet, es ist aber mit jeder Sprache möglich, mit der ein WebServer erstellt werden kann.

  • Ein Google Cloud Projekt kann bei Google Cloud Plattform erstellt werden. Es wird nur ein Google Account benötigt, Neukunden erhalten ein kostenloses Guthaben von 300€ für 90 Tage.
  • Wenn noch nicht vorhanden sollte ein kostenloser Github Account auf Github erstellt werden. Das Beispiel kann auch mittels Google Cloud Source Repositories umgesetzt werden. Als Alternative zu Cloud Build kann Github Actions eingesetzt werden.
  • Terraform, Google Cloud SDK, Docker und Python müssen auf dem verwendeten Computer installiert werden, hierzu empfiehlt sich ein Paketmanager wie Homebrew oder Chocolatey. Linux Nutzer verwenden am besten den in ihrer Distribution mitgelieferten.
  • Soll nichts installiert werden, dann kann auch die Google Cloud Shell verwendet werden, diese findet sich im in der Cloud Console

APIs die in Google Cloud aktiviert werden müssen

Neben den Voraussetzungen zur Software müssen auf der Google Cloud Plattform einige APIs aktiviert werden:

  • Cloud Run API
  • Cloud Build API
  • Artifact Registry API
  • Cloud Scheduler API
  • Cloud Logging API
  • Identity and Access Management API

Die Cloud Run API wird benötigt um einen Cloud Run Service zu erstellen, die Artifact Registry wird benötigt, um die Container Abbilder zu speichern. Die Cloud Build API und die Identity and Access Management API werden benötigt, um eine CI/CD Pipeline zu implementieren. Cloud Scheduler wird in diesem Beispiel verwendet, um den Service regelmäßig aufzurufen. Da alle Services via Terraform erstellt und verwaltet werden, werden die APIs benötigt.

Infrastruktur

Das Erstellen der Infrastruktur läuft in mehreren Schritten ab, nur wenn App Code und Container bereits vorhanden sind, kann der gesamte Prozess automatisiert werden. Für die Definition der Infrastruktur wird ein Ordner “Infrastructure” erstellt und darin die Dateien main.tfvariables.tfund  terraform.tfvars.

Insgesamt werden vier Komponenten erstellt, das Artifact Registry Repository, ein Cloud Run Service, ein Cloud Build Trigger und ein Cloud Scheduler Job. Bevor die eigentliche Infrastruktur erzeugt werden kann, müssen einige Service Accounts definiert werden. Ziel ist es, das jedes Asset eine eigene Identität zugewiesen werden kann. Daher werden drei Service Accounts erstellt, für den Run Service, den Build Trigger und den Scheduler Job.

Da der erste Schritt die Einrichtung der Artifact Registry für den Cloud Run Service ist, wird dieser wie folgt hinzugefügt:

Nun kann der erste Schritt zum Aufsetzen der Infrastruktur mittels des Terraform Dreiklangs durchgeführt werden:

Die Beispiel Flask Anwendung

Als Beispielanwendung wird hier eine sehr simple Flask Webapp verwendet. Die Webapp beinhaltet eine einzige Route, es wird Hello World bei einem GET Request zurück gegeben und mittels POST kann die Nachricht personalisiert werden. Die Anwendung dient nur der Demonstration, es können fast beliebige Funktionalitäten umgesetzt werden.

Es ist auch nur zwingend notwendig flask oder Python zu verwenden, es kann jede Sprache und jedes Framework eingesetzt werden, welches einen Webserver implementieren kann und auf HTTP Anfragen reagieren kann. Flask selbst ist ein sogenanntes Micro Framework und kann flexibel eingesetzt werden, für mehr Informationen empfiehlt sich z.b. das Flask Mega Tutorial

Im Projektverzeichnis muss ein neuer Ordner App erzeugt werden, in diesem Ordner wird die Python Datei main.py, sowie die requirements.txt Datei erzeugt.

Dieser minimale Webservice kann local ausgeführt werden indem ein virtual environment erzeugt und die in requirements.txt spezifizierten Pakete installiert werden.

Die App kann nun local ausgeführt werden mittels:

Zum Testen kann im Browser die Adresse localhost:8080 aufgerufen werden oder mittels curl ein POST Request an den Service gesendet werden.

Der mit flask mitgelieferte Web Server sollte nur zu Entwicklungszwecken verwendet werden, in produktiven Umgebungen kann z.b. gunicorn eingesetzt werden. Gunicorn wird in diesem Beispiel später auch im Container verwendet werden.

Docker Container erstellen, ausführen und deployen

Um einen Service in Cloud Run auszuführen, muss dieser in einem Docker Container vorliegen. Dazu wird zunächst ein Dockerfile im App Ordner erstellt. Diese ist einfach gehalten, es basiert auf einem Python Container, kopiert die Dateien aus dem App Ordner und definiert das Start Kommando für Gunicorn.

In vielen Fällen sind im lokalen Entwicklungsordner Dateien vorhanden die nicht in den Container veröffentlicht werden sollten, damit Dateien explizit aus der Containererzeugung ausgeschlossen werden können kann eine .dockerignore Datei hinzugefügt werden. Diese funktioniert analog der .gitignore Dateien.

Um das Veröffentlichen auf die Artifact Registry zu vereinfachen, kann es eine gute Idee sein dem Namensschema der Registry zu folgen: location—docker.pkg.dev/your-project-id/registryname/containername:latest. Mittels docker build kann das Container Image erstellt werden:

Um das erstellt Image local zu testen, kann dieses mittels docker run auch lokal ausgeführt werden. Wichtig ist dabei zu beachten die notwendigen Umgebungsvariablen mit zugeben und den Port zu exponieren.

Werden im Webservice Google Identitäten verwendet, dann müssen Informationen über den zu verwendenden Google Account mitgegeben werden. Wie dies im Detail funktioniert findet sich unter Cloud Run lokal testen.

Den ersten Container manuell deployen

Bevor es möglich ist den Cloud Run Service zu erstellen muss das Container Abbild einmal manuell in die Artifact Registry veröffentlicht werden.

Erstellen und veröffentlichen des Container Abbilds kann auch in einem Kommando erfolgen:

Cloud Run Service aufsetzen

Da der initiale Container nun in der Aritfact Registry vorhanden ist, kann der Cloud Run Service daraus erstellt werden. Für den Cloud Run Service wird eine neue Resource im main.tf erstellt.

Dieser Service ist zunächst privat, alle Identitäten die diesen Service aufrufen wollen benötigen die Rolle roles/run.invoker. Da der Cloud Scheduler den Service regelmäßig aufrufen soll, muss die Identität des Schedulers Mitglied der Rolle sein.

Nun kann der Terraform Dreiklang verwendet werden den Service und den Scheduler Job zu erstellen.

Cloud Build Trigger erstellen

Der finale Schritt um ein kontinuierliches deployment des Services zu erreichen ist einen Cloud Build Trigger einzurichten. Der Cloud Build Trigger beobachtet Veränderungen am GitHub Repository und erstellt bei jedem neuen Commit auf dem main branch eine neue Version des Cloud Run Services. Die hier vorgestellte Pipeline beinhaltet nur das Erstellen und Veröffentlichen des Containers. Für eine produktive Implementation ist unbedingt zu empfehlen auch noch ein Testschritt mit einzufügen. Mit dem folgenden Code wird der Trigger mittels Terraform erstellt:

Der Cloud Build Trigger nutzt zur Definition des Deployment Processes die Datei cloudbuild.yaml, diese enthält die drei Schritte zum Erstellen des Container Abbilds, Veröffentlichen des Abbilds und Erzeugen einer neuen Version des Cloud Run Services.

  1. Erstellen des Container Abbilds mittels des Docker build Tools. Das erste Argument ist die Aktion build, das zweite und dritte beziehen sich auf den Tag des Images und das vierte gibt den Ort vor an dem nach dem Dockerfile gesucht wird
  2. Veröffentlichen des Container Images in die Artifact Registry mittels des Cloud Build Docker Tools. Als Argumente werden die Aktion push und das Ziel mitgegeben.
  3. Veröffentlichen der neuen Version des Images im Cloud Run Service mittels des Google Cloud SDK Tools gcloud

Alle drei Schritte nutzen Variablen, um Projektziel, Image Tag und Ort flexibel durch den Build Trigger zu steuern. Diese Variable werden bei der Erstellung des Triggers mit definiert, d.h. dieser finden sich in der Definition des Cloud Build Triggers in der Terraform Datei. Die Variablen werden substitutions genannt, es ist zu beachten, das nutzerdefinierte Variablen mit einem Unterstrich beginnen müssen, nur Systemvariablen, wie die PROJECT_ID.

Das Erstellen des Cloud Build Triggers kann versagen, in diesem Falle sollten die Einstellungen von Cloud Build in der Cloud Console geprüft werden. Die Service Account Berechtigungen für Cloud Run und Service Accounts müssen aktiviert sein, wie im Bild unten.

Service Account Berechtigungen für Cloud Run und Service Accounts

Service Account Berechtigungen für Cloud Run und Service Accounts

Zusammenfassung

Mit Hilfe von Terraform ist es möglich ein vollständig in Code definierten, kontinuierlich veröffentlichten Google Cloud Run Service zu erstellen. Dazu werden GCP Services verwendet, eine Flask Webapp in einem Container zu verpacken und diesen auf Cloud Run zu veröffentlichen.

Für Fragen erstellt gerne ein Issue oder ihr findet mich auf LinkedIn.

Der Quellcode ist in GitHub verfügbar: https://github.com/fingineering/GCPCloudRunDemo