Skip to main content

Project 01/03MC-SYS-02

All projects

Aether Data

Search engine: scraped pages flow through two Kafka topics and a sanitisation stage into Cassandra.

Stack
  • Python
  • Kafka
  • Cassandra
  • PostgreSQL
  • Grafana
  • Docker
  • Kubernetes
  • GitHub

01Problem

Build a search engine able to process and index large volumes of data. Two paths must coexist: adding data (scraping more pages into the index) and retrieving it (answering a user's query). The volume requirement calls for a distributed architecture.

Source code is public on GitHub.

02Architecture

Data paths, in order

Fig. 2.1 — Aether: ingestion path (top) and query path (middle); users and logs (bottom).

Scraped pages reach the back end, which publishes them to a Kafka topic. A Python sanitisation stage consumes that topic, checks and cleans the data, and publishes the result to a second topic, treated_data, which is written into Cassandra. On the query side, the front end calls the back end, which passes the query through an AI stage that reads from Cassandra and ranks the results. PostgreSQL stores users and their roles; logs are shipped to Grafana.

Redrawn from the project's data-flow, Kafka and user-management diagrams. The log path to Grafana is drawn from the back end only.

Decision 01 / 07

Kafka between every stage

Decision
Each service owns one task and talks to the others only through Kafka, which carries both raw data and inter-service messages.
Rationale
Stated aims: scalability and reliability, and a single channel for service-to-service communication.
Fig. 1.2 — Reference pattern: Kafka Connect in and out of a Kafka cluster.
Fig. 1.3 — Topics, producers and consumers; schema registry.

Decision 02 / 07

Raw and treated data kept on separate topics

Decision
Scraped data lands on one topic; only records that pass sanitisation reach treated_data and, from there, Cassandra.
Rationale
Only records that pass quality control reach the index.
Fig. 1.4 — Source diagram for Fig. 2.1: add data (top), retrieve data (bottom).

Decision 03 / 07

Cassandra for the index

Decision
Indexed pages are stored in Cassandra.
Rationale
As recorded: consistency and integrity of the indexed data.
Fig. 1.5 — Index model: domain and page attributes.

Decision 04 / 07

Users in a separate relational store

Decision
User accounts and permissions live in PostgreSQL, apart from the index, with role-based access control.
Rationale
Keeps accounts and permissions apart from the page index.
Fig. 1.6 — User management path.
Fig. 1.7 — PostgreSQL schema.

Decision 05 / 07

Python for processing and relevance

Decision
Raw-data processing and indexing are written in Python, which also hosts the machine-learning models used to rank results.
Rationale
One language covers data cleaning, indexing and the AI stage.

Decision 06 / 07

Logs to Grafana

Decision
Services emit logs that are collected and visualised in Grafana dashboards.
Rationale
Availability depends on catching errors across many services; a shared dashboard shows performance in real time.
Fig. 1.8 — Reference pattern: log management over Kafka.

Decision 07 / 07

Docker first, then Kubernetes

Decision
The first test phases ran on Docker; Kubernetes was introduced afterwards on dedicated servers.
Rationale
Docker kept environments consistent across development, testing and production; Kubernetes was added for scalability and reliability.