Go to main content
Project: complete data lake on S3 - official lesson image on GinnyTech, created by AD

Project: Complete Data Lake on S3

Practical Lab: Build an enterprise-ready data lake on S3 with Athena, Iceberg, and Glue.

AD
Created byAndrii Dyshkantiuk
Lesson 110 / 236Level: AdvancedDuration: 28 minPrerequisites: 1

What you will learn

  • Understand the analytical problem and the decision-making context
  • Apply examples, metrics, and controls to real cases

import pandas as pd

Project: Complete Data Lake on S3

Il progetto finale porta un lake S3 da un insieme di cartelle sparse a un sistema leggibile e governato: zone raw, curated e analytics, formati colonnari, catalogo, policy di accesso, lifecycle e query engine. Trattalo come una consegna architetturale, dove ogni scelta deve spiegare quale rischio riduce, che si tratti di costi, sicurezza, query lente, dati non tracciabili, schema instabile o recovery mai verificato. Il punto del lab è dimostrare che flessibilità e governance convivono solo se le progetti insieme.

Cosa deve dimostrare il progetto

La domanda guida non è “qual è la definizione corretta di data lake?” ma “quale scelta diventa meno rischiosa se l’architettura è fatta bene?”. Una query lenta, un dato senza owner o uno schema che cambia senza controllo non sono problemi astratti: sono il motivo per cui un report finance arriva sbagliato o in ritardo.

Il caso è completo quando una query Athena legge dati governati senza conoscere i dettagli fisici: dove sono i file, come sono partizionati, quali permessi servono. Tutto il lavoro di seguito serve a costruire quel livello di astrazione.

Come ragionare sulle scelte di architettura

Conviene fissare l’unità su cui ragioni e la metrica che vuoi tenere sotto controllo prima di scrivere la prima CREATE TABLE. La tabella seguente rende esplicite le assunzioni, così un collega può criticare il criterio invece di fidarsi del risultato.

ElementRequested specification
Unit of analysisbucket, partition, file, table, format, or policy
Primary signalscan cost, latency, reliability, freshness, and access risk
Baselineperiodo precedente, gruppo comparabile, benchmark o scenario controfattuale
Decisiondata layout, table format, access control, or lifecycle rule
Riskscambiare un numero disponibile per una prova sufficiente

L’architettura è solida quando un altro ingegnere può riprodurre la logica, criticare le assunzioni e arrivare alle stesse scelte partendo dagli stessi vincoli.

Fase 1: architettura S3 e partizionamento

La struttura del bucket separa i dati transazionali da quelli dimensionali e partiziona i primi per data, così le query temporali leggono solo le partizioni rilevanti.

s3://globalretail-datalake/
  transactional/
    sales/year=YYYY/month=MM/day=DD/
    inventory/year=YYYY/month=MM/
  dimensional/
    products/
    stores/
    customers/

Il formato è Parquet con compressione Snappy. Le partizioni ottimali stanno tra 200 e 500 MB ciascuna: troppo piccole moltiplicano i file e rallentano le scansioni, troppo grandi riducono il parallelismo.

Phase 2: Apache Iceberg

Iceberg trasforma i file in tabelle versionate con time travel, così puoi interrogare lo stato di una tabella a una data passata senza ricostruire nulla a mano.

CREATE TABLE sales_iceberg (
    order_id STRING, store_id INT, product_id INT,
    quantity INT, amount DECIMAL(10,2), margin DECIMAL(10,2)
) PARTITIONED BY (year INT, month INT)
LOCATION 's3://globalretail-datalake/transactional/sales'
TBLPROPERTIES ('format-version'='2');

-- Time travel: stato tabella a gennaio
SELECT * FROM sales_iceberg FOR TIMESTAMP AS OF TIMESTAMP '2024-01-15 00:00:00';

Phase 3: Glue Catalog and governance

Tutte le tabelle Iceberg vanno registrate nel Glue Catalog, che diventa il punto unico da cui i motori scoprono schema e posizione dei dati. Su questo si appoggia Lake Formation per il controllo granulare: marketing vede solo metriche aggregate, finance vede i dati transazionali ma senza PII. Così la stessa tabella espone viste diverse a ruoli diversi senza duplicare i dati.

Fase 4: query ottimizzate Athena

Con le partizioni e il catalogo in piedi, Athena sfrutta il partition pruning per scansionare solo i dati necessari. La query seguente calcola revenue per paese e trimestre leggendo solo i mesi richiesti.

-- Revenue per paese e trimestre (usa partition pruning)
SELECT c.country, year, quarter, SUM(amount) AS revenue
FROM sales_iceberg s JOIN dim_customers c ON s.customer_id = c.id
WHERE year=2024 AND month BETWEEN 1 AND 3
GROUP BY c.country, year, quarter;

Delivery

Il progetto è completo quando puoi spuntare tutti i punti seguenti, dove l’ultimo è il vero test di affidabilità: una query su 100 GB deve restare sotto i cinque secondi grazie a partizionamento e formato colonnare.

  • Data lake on S3 with optimal partitioning
  • Iceberg enabled on at least one table
  • Glue Catalog populated
  • Lake Foundation policy for granular access
  • Athena query <5 seconds on 100 GB

Il progetto come sistema, non come template

In un caso reale questa architettura non vive isolata. Fa parte di un sistema fatto di decisioni, dati disponibili, vincoli tecnici e incentivi organizzativi. Il rischio del principiante è trattare il lavoro come un template da copiare; la pratica professionale è capire quale problema risolve ogni scelta e cosa succede quando le assunzioni saltano.

La prima domanda non è “quale metrica calcolo?” ma quale decisione dovrà nascere da questi dati. Una dashboard, una query o un modello hanno valore solo se riducono incertezza decisionale. Un modo concreto di impostare il lavoro:

  1. define the problem in business language;
  2. identify the correct unit of analysis: user, account, event, session, order, campaign;
  3. check if the data truly measures the phenomenon or just its shadow;
  4. build an interpretable metric;
  5. segment to avoid the average hiding opposite patterns;
  6. turn the result into a verifiable recommendation.

Real case: Netflix and the discipline of metrics

Netflix è un esempio utile perché ha costruito molte decisioni di prodotto intorno a segnali comportamentali osservabili: completamento degli episodi, tempo di ricerca prima della riproduzione, abbandono dopo pochi minuti, ritorno nella settimana successiva, efficacia delle raccomandazioni. Non è un invito a copiare Netflix, ma a trattare il dato come infrastruttura decisionale e non come ornamento.

Quando l’azienda valuta una modifica, per esempio una nuova riga di raccomandazioni o un diverso algoritmo di ranking, non misura solo il click immediato ma anche se l’utente segue il contenuto, se torna nei giorni successivi, se riduce il tempo speso a cercare. Lo stesso vale per il data lake del progetto: ha senso solo se i dati che governa alimentano scelte concrete invece di restare documentazione.

SQL example: building a control view

Il pattern seguente è volutamente generico ma eseguibile nella maggior parte dei warehouse moderni. Crea una base analitica con metrica, segmento e finestra temporale, così da confrontare periodi e gruppi senza riscrivere la logica ogni volta.

WITH base_events AS (
  SELECT
    user_id,
    account_id,
    event_type,
    event_time,
    DATE_TRUNC('week', event_time) AS week,
    source,
    device_type
  FROM events
  WHERE event_time >= CURRENT_DATE - INTERVAL '180 days'
    AND user_id IS NOT NULL
),
weekly_user_metrics AS (
  SELECT
    week,
    user_id,
    COALESCE(source, 'unknown') AS source,
    COALESCE(device_type, 'unknown') AS device_type,
    COUNT(*) AS total_events,
    COUNT(DISTINCT DATE(event_time)) AS active_days,
    COUNT(DISTINCT event_type) AS event_diversity,
    MAX(CASE WHEN event_type IN ('purchase', 'subscribe', 'activation') THEN 1 ELSE 0 END) AS reached_key_outcome
  FROM base_events
  GROUP BY week, user_id, source, device_type
)
SELECT
  week,
  source,
  device_type,
  COUNT(DISTINCT user_id) AS users,
  ROUND(AVG(active_days), 2) AS avg_active_days,
  ROUND(AVG(event_diversity), 2) AS avg_event_diversity,
  ROUND(AVG(reached_key_outcome) * 100, 2) AS key_outcome_rate
FROM weekly_user_metrics
GROUP BY week, source, device_type
ORDER BY week, source, device_type;

La query crea una superficie di osservazione (trend, segmenti, differenze tra canali) da cui formulare ipotesi più precise.

Python example: checking stability and anomalies

Una metrica utile deve essere stabile abbastanza da orientare decisioni e sensibile abbastanza da segnalare cambiamenti reali. In Python si possono individuare variazioni anomale settimana su settimana.


# df contiene: week, segment, users, key_outcome_rate
# key_outcome_rate espresso in percentuale, es. 12.4

df = df.sort_values(['segment', 'week']).copy()
df['previous_rate'] = df.groupby('segment')['key_outcome_rate'].shift(1)
df['wow_change_pp'] = df['key_outcome_rate'] - df['previous_rate']
df['rolling_mean'] = df.groupby('segment')['key_outcome_rate'].transform(
    lambda s: s.rolling(4, min_periods=2).mean()
)
df['rolling_std'] = df.groupby('segment')['key_outcome_rate'].transform(
    lambda s: s.rolling(4, min_periods=2).std()
)
df['z_score'] = (df['key_outcome_rate'] - df['rolling_mean']) / df['rolling_std']

anomalies = df[df['z_score'].abs() >= 2].sort_values('z_score')
print(anomalies[['week', 'segment', 'key_outcome_rate', 'wow_change_pp', 'z_score']])

Il valore del controllo è pratico: evita di reagire a ogni oscillazione casuale e segnala quando una variazione merita un’indagine. In azienda alimenta alert, review settimanali e retrospettive.

Common mistakes to avoid

Il primo errore è lavorare su dati aggregati troppo presto: una media globale può nascondere due segmenti che si muovono in direzioni opposte. Il secondo è non controllare la qualità del dato, perché eventi duplicati, tracking incompleto, timezone incoerenti e definizioni che cambiano producono conclusioni false. Il terzo è confondere correlazione e causalità: se gli utenti che usano una feature convertono di più, non è detto che la feature causi la conversione, perché potrebbero usarla proprio perché già più motivati.

Per ridurre questi rischi ogni analisi dovrebbe includere almeno tre controlli: definizione esplicita della metrica, confronto per segmento e verifica contro un periodo precedente o un gruppo di controllo.

Il progetto vale quando produce decisioni più chiare, non quando accumula terminologia. Le quattro fasi costruiscono un percorso coerente: il partizionamento S3 rende le scansioni economiche, Iceberg aggiunge versioning e time travel, Glue e Lake Formation governano accessi e schema, Athena chiude il cerchio leggendo dati governati senza conoscere i dettagli fisici. Il test finale resta concreto: una query su 100 GB sotto i cinque secondi e una governance che mostra a ogni ruolo solo ciò che gli compete.