
Strategie di partizionamento su data lake
Progettare partizioni ottimali per query engines su S3: trade-off e pattern consolidati.
Cosa imparerai
- Comprendere il problema analitico e il contesto decisionale
- Applicare esempi, metriche e controlli a casi reali
Collegamenti
import pandas as pd
Strategie di partizionamento su data lake
Partizionare un data lake significa decidere come disporre fisicamente i file su S3 in modo che le query leggano solo i dati che servono. Una tabella di eventi può essere interrogata per giorno, paese, cliente o campagna. Se la partizioni male, ogni query finisce per scansionare troppo, oppure ti ritrovi con migliaia di partizioni minuscole che pesano sui metadati. Il tema è tecnico, quindi qui conta una cosa sola: capire quale decisione di layout cambia il costo e la latenza delle analisi.
Il problema che il partizionamento risolve
Il punto non è conoscere la teoria del partizionamento in astratto, ma decidere come strutturare i dati quando il team ha query ricorrenti, volumi che crescono e un budget di scansione da rispettare. Una partizione utile riduce i dati letti. Una partizione eccessiva aumenta i metadati, moltiplica i file piccoli e complica le operazioni. La lezione insegna a disegnare il layout fisico a partire dalle query reali, non dall’intuizione su quale colonna sembri più “naturale”.
Come ragionare prima di scegliere una colonna
Conviene seguire una sequenza di domande, in cui ogni passaggio rende più chiaro il costo di una scelta sbagliata.
| Passaggio | Domanda da fare | Output atteso |
|---|---|---|
| Decisione | Quale layout fisico stiamo scegliendo? | Scelta esplicita |
| Segnale | Quali query sono più frequenti e più pesanti? | Pattern di filtro osservato |
| Baseline | Quanti dati scansiona oggi una query tipica? | Costo di riferimento |
| Vincolo | Quante partizioni genera questa colonna? | Cardinalità sostenibile |
| Azione | Quale colonna mettiamo nel path? | Layout verificabile |
Questa griglia evita di trasformare il partizionamento in un rituale. Ogni riga deve collegarsi a un costo concreto: GB scansionati, numero di file, latenza della query.
Mettere a fuoco le assunzioni
Conviene rendere esplicite le scelte, così uno stakeholder può discutere il criterio invece di fidarsi del risultato per autorità. L’unità su cui ragioni è la partizione, cioè la cartella che raggruppa un insieme di file Parquet. Il segnale che osservi sono i GB scansionati e il tempo di risposta. La baseline è il comportamento della tabella prima dell’intervento. La soglia decisionale è la dimensione di partizione che consideri accettabile, scritta prima di misurare. Il rischio residuo è scegliere una colonna molto granulare solo perché disponibile, generando partizioni piccole che peggiorano tutto.
| Elemento | Definizione operativa | Controllo minimo |
|---|---|---|
| Unità di analisi | La partizione e i file che contiene | Path, formato, dimensione |
| Variabile osservata | GB scansionati e latenza | Misura ripetibile sulla stessa query |
| Baseline | Costo della query prima del cambio layout | Periodo o tabella di confronto |
| Soglia decisionale | Dimensione di partizione accettabile | Criterio scritto prima della misura |
| Rischio residuo | Troppe partizioni o partizioni troppo grandi | Conteggio file e revisione |
La regola d’oro delle partizioni
Partiziona per la colonna che filtri nel WHERE delle query più frequenti e pesanti. Per un data lake di eventi conviene year/month/day se le query filtrano sempre per data. Per un data lake di clienti segmentato per paese conviene country se le query filtrano sempre per quella dimensione. La colonna giusta non è la più dettagliata, ma quella che compare nei filtri ricorrenti.
La dimensione ideale di una partizione
Una partizione dovrebbe contenere tra 100 e 500 MB di dati in formato Parquet. Sotto i 100 MB ti ritrovi con troppi file piccoli e un overhead elevato sulle operazioni S3 LIST. Sopra 1 GB il partition pruning diventa meno efficace e la query scansiona dati che non servono.
Un calcolo rapido aiuta a scegliere la granularità. Se generi 100 GB al giorno di eventi, la partizione per day è quella giusta: circa 100 MB se Parquet comprime a 10x. Se invece generi 100 MB al giorno, conviene partizionare per month, che porta a circa 3 GB al mese, oppure per week.
Evoluzione delle partizioni nel tempo
I dati crescono e la granularità che andava bene ieri può non bastare domani. Ci sono due pattern principali. Il primo è aggiungere partizioni: si passa da year/month a year/month/day quando il volume aumenta, i nuovi dati finiscono nelle partizioni più granulari e i vecchi restano come sono. Athena e Trino gestiscono partizioni eterogenee senza problemi. Il secondo è compattare le partizioni vecchie: i dati di tre anni fa, ormai a basso volume residuo, si possono passare da day a month con un semplice job Spark o un Athena CTAS.
Un caso che mostra l’errore opposto
Una tabella viene partizionata per user_id perché sembra granulare e quindi efficiente. Il risultato è l’opposto: milioni di partizioni minuscole, metadati ingestibili e query più lente. Il caso mostra che la partizione deve seguire i filtri ricorrenti e una cardinalità sostenibile, non la colonna con più valori distinti.
| Evidenza osservata | Lettura prudente | Azione consigliata |
|---|---|---|
| La query scansiona più del previsto | Forse il filtro non sfrutta la partizione | Verificare path e predicate pushdown |
| Migliaia di file da pochi KB | Granularità troppo alta | Compattare o salire di livello |
| Il costo cresce col volume | Layout non scala | Rivedere la chiave di partizione |
Esercizio
Per il livello base, scrivi in cinque righe quale decisione di layout vuoi migliorare. Indica la query target, la colonna di filtro, la dimensione di partizione attesa e il rischio principale. Se non riesci a nominare la query, il problema è ancora troppo astratto.
Per il livello intermedio, costruisci una tabella con quattro colonne: query osservata, GB scansionati oggi, layout proposto, GB attesi dopo il cambio. Includi almeno un caso in cui il risparmio non giustifica l’aumento di file.
Per il livello research-grade, trasforma l’esercizio in un memo decisionale che includa assunzioni, cardinalità stimata, soglia di dimensione, costo prima e dopo, e un piano di monitoraggio dei file piccoli dopo il rollout. Come dataset usa un export reale, una tabella sintetica o un notebook di studio, purché contenga una dimensione temporale, una dimensione di segmento e una metrica osservabile.
Errore tipico da evitare
L’errore più comune è scegliere la chiave di partizione per intuizione invece che dai pattern di query. Succede quando si parte dalla colonna che sembra più dettagliata o più importante, senza guardare quali filtri compaiono davvero nel WHERE. Il risultato sembra ordinato, ma scansiona troppo o esplode in file piccoli. La domanda di controllo è semplice: quale query reale diventa più economica con questo layout? Se non sai rispondere, il collegamento tra struttura fisica e uso effettivo manca ancora.
Checkpoint
- Quale query ricorrente vuoi rendere più economica?
- Quale colonna compare nel WHERE di quelle query?
- Quanti GB scansiona oggi una query tipica?
- Quante partizioni genera la colonna scelta?
- Quale dimensione media di partizione consideri accettabile?
Riepilogo
Il partizionamento è una scelta di layout fisico guidata dalle query, non dalla colonna più granulare disponibile. Parti dai filtri ricorrenti, punta a partizioni tra 100 e 500 MB di Parquet, evita sia i file piccoli sia le partizioni gigantesche, e fai evolvere la granularità man mano che il volume cambia. Una buona decisione si riconosce perché riduce i GB scansionati su una query reale e mantiene il numero di file sotto controllo.
Riferimenti:
- AWS. (2024). “Top 10 Performance Tuning Tips for Amazon Athena.” AWS Big Data Blog.
- Databricks. (2024). “Delta Lake Best Practices.” databricks.com.
Percorso collegato
Lezioni da leggere insieme
Questi collegamenti portano la lezione dentro il resto del corso: basi da riprendere, passaggi successivi e connessioni tematiche tra moduli.