Progettare e implementare uno schema di partizionamento dei dati
Il partizionamento dei dati influisce direttamente sull'esecuzione delle query in modo efficiente e sulla quantità di risorse di calcolo utilizzate. Quando si partiziona una tabella, i dati vengono divisi in segmenti discreti in base ai valori di colonna, consentendo al motore di query di leggere solo parti pertinenti del set di dati. Questo approccio, denominato eliminazione delle partizioni, può ridurre notevolmente le analisi dei dati quando i filtri sono allineati ai limiti della partizione.
Prendere in considerazione un'azienda di vendita al dettaglio che elabora milioni di transazioni di vendita giornaliere. Gli analisti eseguono spesso query sui dati in base agli intervalli di date per generare report settimanali, confrontare le tendenze mensili e analizzare i modelli stagionali. Senza partizionamento, ogni query analizza l'intera cronologia delle transazioni. Con il partizionamento corretto per data, le query per una settimana specifica toccano solo una frazione dei file archiviati.
Determinare quando si applica il partizionamento
Databricks consiglia di non partizionare tabelle contenenti meno di 1 TB di dati. Per le tabelle più piccole, il sovraccarico di gestione dei metadati della partizione e il potenziale per la creazione di molti file di piccole dimensioni supera i vantaggi delle prestazioni delle query. Le tabelle Delta non partizionate nelle versioni recenti di Databricks Runtime traggono automaticamente vantaggio dal clustering basato sull'ora di ingestione, offrendo vantaggi simili nelle query senza necessità di configurazione esplicita.
Quando le tabelle superano 1 TB, il partizionamento diventa una tecnica di ottimizzazione preziosa. A questo livello, i vantaggi della lettura solo dei segmenti di dati rilevanti compensino significativamente i costi di gestione delle partizioni. Il partizionamento consente anche l'elaborazione parallela, in quanto Spark può distribuire partizioni diverse tra i nodi del cluster per l'esecuzione simultanea.
Importante
Ogni partizione deve contenere almeno 1 GB di dati. Questa linea guida consente di evitare il partizionamento eccessivo, creando file troppo piccoli e degradando le prestazioni delle query.
Per tabelle molto grandi nell'intervallo di centinaia di terabyte, il partizionamento offre vantaggi ancora più elevati. A questo livello, l'eliminazione delle partizioni riduce notevolmente la quantità di dati che il motore di query deve elaborare, migliorando sia le prestazioni che l'efficienza dei costi.
Scegliere chiavi di partizione valide
La selezione della chiave di partizione richiede di comprendere le caratteristiche dei dati e i modelli di query. Le chiavi di partizione efficaci condividono tratti comuni che ottimizzano i vantaggi delle prestazioni evitando problemi comuni.
Le colonne a cardinalità bassa funzionano meglio
Scegliere le colonne con un numero limitato di valori distinti. Le colonne di data, le aree geografiche, le categorie di prodotti e i campi di stato creano chiavi di partizione eccellenti perché creano un numero gestibile di partizioni. Una colonna con migliaia o milioni di valori univoci, ad esempio l'ID cliente o l'ID transazione, comporta un over-partitioning e prestazioni scarse.
Ad esempio, il partizionamento di una tabella delle vendite da sale_date a livello giornaliero potrebbe creare 365 partizioni all'anno. Se ogni giorno contiene un volume di dati sufficiente, questa granularità funziona correttamente. Tuttavia, il partizionamento in sale_timestamp base al secondo livello creerebbe milioni di partizioni, ognuna contenente dati minimi.
Allinea ai modelli di query
La chiave di partizione deve corrispondere alle colonne filtrate più di frequente dagli utenti. Se gli analisti eseguono costantemente query sui dati di vendita per intervalli di date, il partizionamento per data consente un'efficiente ottimizzazione. Se le query vengono filtrate principalmente per regione, considerare la regione come chiave di partizione.
Quando esistono più modelli di filtro, assegnare la priorità alle query più comuni o più critiche per le prestazioni. È possibile definire uno schema di partizionamento per ogni tabella, quindi scegliere le colonne che traggono vantaggio dalla maggior parte del carico di lavoro. Per modelli di query notevolmente diversi, è consigliabile creare viste materializzate ottimizzate separate o tabelle di riepilogo per casi d'uso specifici.
Prendere in considerazione la crescita dei dati nel tempo
Selezionare uno schema di partizione che viene ridimensionato in modo appropriato man mano che i dati aumentano. Il partizionamento per anno funziona correttamente inizialmente, ma potrebbe creare partizioni troppo grandi nel tempo. Al contrario, il partizionamento per ora potrebbe funzionare per i dati con volumi elevati, ma crea troppe partizioni di piccole dimensioni per volumi moderati.
Valutare il tasso di crescita dei dati previsto quando si sceglie la granularità della partizione. Un equilibrio tra le dimensioni della partizione e il numero di partizioni consente di mantenere prestazioni coerenti delle query man mano che il set di dati si espande.
Prendere in considerazione anche la distribuzione dei dati tra le partizioni. Le dimensioni delle partizioni molto irregolari possono creare colli di bottiglia di elaborazione, poiché i nodi che gestiscono partizioni di dimensioni maggiori richiedono più tempo per il completamento, mentre altri rimangono inattivi.
Implementare partizioni in Azure Databricks
Le partizioni vengono definite durante la creazione di una tabella usando la PARTITIONED BY clausola in SQL o il partitionBy metodo in PySpark. Dopo aver stabilito le partizioni, Azure Databricks instrada automaticamente i dati in ingresso alle directory di partizione appropriate in base ai valori di colonna.
Creare una tabella partizionata con SQL
Nell'esempio seguente viene creata una tabella delle transazioni di vendita partizionata in base alla data della transazione:
CREATE TABLE sales.transactions (
transaction_id STRING,
customer_id STRING,
product_id STRING,
quantity INT,
unit_price DECIMAL(10,2),
total_amount DECIMAL(12,2),
transaction_date DATE
)
PARTITIONED BY (transaction_date);
Quando si esegue una query su questa tabella con un filtro di data, il motore di query legge solo le partizioni che corrispondono ai criteri di filtro:
SELECT product_id, SUM(total_amount) AS revenue
FROM sales.transactions
WHERE transaction_date BETWEEN '2024-01-01' AND '2024-01-31'
GROUP BY product_id;
Creare una tabella partizionata con PySpark
Quando si usa PySpark, specificare il partizionamento durante l'operazione di scrittura:
df.write.format("delta") \
.partitionBy("transaction_date") \
.saveAsTable("sales.transactions")
Per le scritture successive, mantenere la coerenza includendo la stessa specifica di partizione:
new_transactions_df.write.format("delta") \
.mode("append") \
.partitionBy("transaction_date") \
.saveAsTable("sales.transactions")
Usare le colonne generate per la flessibilità delle partizioni
Le colonne generate consentono di derivare valori di partizione da colonne esistenti senza archiviare dati ridondanti. Questo approccio è utile quando i dati di origine contengono timestamp, ma si vuole partizionare per data:
CREATE TABLE sales.transactions (
transaction_id STRING,
customer_id STRING,
product_id STRING,
quantity INT,
unit_price DECIMAL(10,2),
total_amount DECIMAL(12,2),
transaction_timestamp TIMESTAMP,
transaction_date DATE GENERATED ALWAYS AS (CAST(transaction_timestamp AS DATE))
)
PARTITIONED BY (transaction_date);
Suggerimento
Con questa configurazione, Delta Lake genera automaticamente filtri di partizione quando si esegue una query usando la colonna timestamp di base. Una query che filtra su transaction_timestamp trae vantaggio dall'eliminazione della partizione senza richiedere filtri di data espliciti.
Evitare errori comuni di partizionamento
Comprendere cosa evitare è importante quanto sapere cosa fare. Diversi errori comuni possono ridurre significativamente le prestazioni e complicare la gestione dei dati.
Il partizionamento eccessivo crea piccoli problemi di file
La creazione di troppe partizioni, ognuna contenente dati insufficienti, causa problemi di file di piccole dimensioni. Quando le partizioni contengono file inferiori alle dimensioni del file di destinazione, le prestazioni delle query risentono di operazioni di metadati eccessive e riducono l'efficienza di lettura. Mirare a partizioni con almeno 1 GB di dati.
I segni di over-partitioning includono prestazioni lente delle query nonostante l'eliminazione delle partizioni, un numero elevato di file di piccole dimensioni nelle directory di partizione e tempi di ottimizzazione delle tabelle lunghi. Se si osservano questi sintomi, è consigliabile scegliere una granularità della partizione più grossolana.
Il partizionamento delle colonne a cardinalità elevata fallisce
Le colonne con molti valori univoci rendono le chiavi di partizione scarse. Il partizionamento in base all'ID cliente, all'ID transazione o ad altre colonne a cardinalità elevata crea milioni di partizioni che riducono le prestazioni anziché migliorare le prestazioni. Riservare l'ottimizzazione delle colonne a cardinalità elevata per altre tecniche progettate per questo scopo.
La modifica delle partizioni richiede la riscrittura dei dati
Le colonne di partizione fanno parte della struttura della tabella. La modifica della strategia di partizionamento richiede la riscrittura dell'intera tabella in una nuova posizione con limiti di partizione diversi. Questa operazione utilizza risorse di calcolo e tempo significative per le tabelle di grandi dimensioni.
Pianificare attentamente la strategia di partizionamento prima di caricare i dati su larga scala. Prendere in considerazione i modelli di query futuri e una crescita dei dati per evitare costose ristrutturazioni in un secondo momento.
Decisioni relative al partizionamento dei documenti
Registra le scelte della chiave di partizione e la motivazione dietro di esse. Questa documentazione aiuta i membri del team a comprendere le opportunità di ottimizzazione delle query e impedisce modifiche accidentali che potrebbero influire sulle prestazioni. Includere informazioni sulle dimensioni delle partizioni previste, i modelli di query che traggono vantaggio dallo schema e tutti i vincoli che hanno influenzato le decisioni.
Prendere in considerazione il clustering liquido come alternativa
Quando si verificano problemi di partizionamento, in particolare con colonne a cardinalità elevata come timestamp o quando i modelli di query sono incerti, il clustering liquido offre un'alternativa moderna. A differenza del partizionamento tradizionale, il clustering liquido offre:
- Flessibilità per modificare le strategie di ottimizzazione senza riscrivere i dati
- Manutenzione automatica man mano che le tabelle aumentano
- Riduzione del sovraccarico di gestione delle partizioni
Il clustering liquido è l'approccio consigliato per le nuove tabelle in cui i vincoli di partizionamento limitano le prestazioni o creano un carico di manutenzione eccessivo. È particolarmente efficace per le tabelle che superano 1 TB e richiedono un filtro per colonne che creerebbero troppe partizioni usando approcci tradizionali.
Annotazioni
Il clustering liquido non è compatibile con le tabelle partizionate. Scegliere un approccio basato sui requisiti per la progettazione di nuove tabelle.
Per informazioni dettagliate sull'implementazione, la sintassi e le strategie di ottimizzazione, vedere l'unità Progettazione e implementare una strategia di clustering più avanti in questo modulo.