Utilizzare warehouse di dimensioni diverse per workloads diversi in Snowflake porta enormi vantaggi in termini di performance e ottimizzazione dei costi. dbt si integra nativamente con Snowflake e consente di selezionare warehouse specifici fino al livello del singolo modello. In questo articolo vediamo nel dettaglio come sfruttare questa funzionalità e quali best practice adottare. Perché cambiare la dimensione del warehouse?
Se il vostro progetto dbt sta diventando lento, con SLA non rispettati o una user experience scadente, aumentare la dimensione del warehouse è quasi sempre la via più rapida per migliorarne la velocità. Se invece avete già aumentato la dimensione predefinita del warehouse di dbt, potreste voler contenere i costi alzando la dimensione solo per i modelli che ne traggono effettivo beneficio.
Velocizzare i modelli dbt
Con il passare del tempo i modelli tendono a rallentare man mano che il volume di dati cresce. Per alcuni modelli il rallentamento è lineare rispetto al volume di dati; per altri non è così, perché funzioni di aggregazione e join possono diventare esponenzialmente onerosi all'aumentare dei dati. Tutti questi fattori incidono in modo significativo sui tempi di esecuzione, soprattutto quando un modello inizia a fare spilling verso il remote storage (per approfondire, leggete il nostro articolo sul query profile).
Il modo più efficace in assoluto per velocizzare una query è ridurre la quantità di dati che elabora. Se un modello sta diventando lento e utilizza una materializzazione di tipo table, valutate il passaggio a una materializzazione incremental, così da elaborare a ogni esecuzione solo i dati nuovi o aggiornati.
Se state già usando l'incrementalizzazione, oppure se non è praticabile, aumentare la dimensione del warehouse è quasi sempre il passo successivo per accelerare il modello.
Configurare il warehouse Snowflake predefinito di dbt
Per impostazione predefinita, dbt utilizza il warehouse Snowflake configurato nella voce profiles.yml del progetto oppure, se non specificato, il warehouse predefinito dell'utente Snowflake di dbt. Sostituendo questo warehouse con uno più grande, o semplicemente ridimensionando quello esistente, dbt eseguirà tutte le query su un warehouse di dimensioni maggiori. A seconda di dove gira dbt, il warehouse può essere modificato nel file profiles.yml oppure in dbt Cloud a livello di environment.
profiles.yml
Nel file profiles.yml, modificate la configurazione warehouse indicando un virtual warehouse diverso. La dimensione di ciascun warehouse si imposta in Snowflake.
select_internal:
outputs:
dev:
type: snowflake
account: org.account
user: niall
password: XXXXX
warehouse: dev
database: dev
schema: niall
threads: 8
target: dev
dbt Cloud
In dbt Cloud, andate su Deploy > Environments nella barra dei menu in alto. Scegliete l'environment da modificare, poi Settings. Cliccate su Edit e scorrete fino a Deployment Connection, dove potete cambiare il warehouse. La dimensione del warehouse si imposta in Snowflake.
Cambiare la dimensione predefinita del warehouse di dbt, però, non è sempre una scelta saggia: la maggior parte delle query del progetto non trarrà vantaggio da un warehouse più grande, con il rischio di far lievitare i costi Snowflake. Per approfondire l'impatto della dimensione del warehouse sulla velocità delle query, consultate il nostro articolo sul dimensionamento dei warehouse. Invece di aumentare la dimensione predefinita, consigliamo di impostarla a X-Small e di sovrascriverla a livello di singolo modello, dove serve.
Configurare la dimensione del warehouse Snowflake a livello di modello dbt
Configurare il warehouse a livello di modello permette di scegliere dimensioni specifiche in base alle esigenze di ciascun modello, ottimizzando performance e costi.
Warehouse hardcoded
dbt mette a disposizione la configurazione di modello snowflake_warehouse, che impostata su un modello specifico si presenta così:
{{ config(
snowflake_warehouse="dbt_large"
) }}
select
...
from {{ ref('stg_orders') }}
In alternativa, la configurazione può essere applicata a tutti i modelli di una directory tramite dbt_project.yml, ad esempio:
name: my_project
version: 1.0.0
---
models:
+snowflake_warehouse: 'dbt_xsmall'
my_project:
clickstream:
+snowflake_warehouse: 'dbt_large'
Nome del warehouse dinamico in base all'environment
Nella maggior parte dei casi, il warehouse che vogliamo utilizzare in produzione è diverso da quello usato in sviluppo, in CI o in un workflow di test automatizzato. Lo stesso vale per i warehouse che stiamo ora configurando per i singoli modelli. Per gestire questo scenario possiamo usare una macro al posto del valore letterale del warehouse visto sopra:
{{ config(
snowflake_warehouse=get_warehouse('large')
) }}
select
...
from {{ ref('stg_orders') }}
La macro può implementare la logica necessaria per restituire la dimensione del warehouse adatta all'environment.
Supponiamo che in produzione siano stati creati warehouse denominati dbt_production_<size> (dbt_production_xsmall, dbt_production_small, dbt_production_medium ecc.) e che, per la CI, esistano warehouse denominati dbt_ci_<size>. In sviluppo locale vogliamo invece utilizzare il warehouse predefinito, ignorando del tutto la dimensione configurata. Vogliamo inoltre che venga sollevato un errore se la dimensione del warehouse scelta non rientra in un elenco gestito. Ecco la logica della macro:
{% macro get_warehouse(size) %}
{% set available_sizes = ['xsmall', 'small', 'medium', 'large', 'xlarge', '2xlarge'] %}
{% if size not in available_sizes %}
{{ exceptions.raise_compiler_error("Warehouse size not one of " ~ valid_warehouse_sizes) }}
{% endif %}
{% if target.name in ('production', 'prod') %}
{% do return('dbt_production_' ~ size) %}
{% elif target.name in ('ci') %}
{% do return('dbt_ci_' ~ size) %}
{% else %}
{% do return(None) %}
{% endif %}
{% endmacro %}
L'uso di una macro per la configurazione snowflake_warehouse è supportato solo nei file dei modelli e non può essere utilizzato nel dbt_project.yml.
Configurare il warehouse per altre risorse in dbt
Al momento è possibile configurare i warehouse solo per modelli e snapshot. Se volete restare aggiornati sul supporto per altre risorse, come i test, seguite questa issue su GitHub.
Monitorare performance e costi dei modelli dbt
Vi consigliamo di provare il nostro pacchetto dbt dbt_snowflake_monitoring, che mette a disposizione un modello dbt_queries immediato per analizzare le performance dei modelli dbt nel tempo. Attribuisce i costi alle singole esecuzioni dei modelli, rendendo semplice rispondere a domande come "quali sono i 10 modelli più costosi dell'ultimo mese?".
Grazie per aver letto fin qui! In un prossimo articolo condivideremo altri consigli per ottimizzare le performance di dbt su Snowflake. Iscrivetevi per ricevere le notifiche sui nuovi articoli e non esitate a contattarci per qualsiasi domanda!
Niall Woodward·Co-founder & CTO di SELECT
Niall è Co-Founder e CTO di SELECT, una piattaforma SaaS per la gestione e l'ottimizzazione dei costi Snowflake. Prima di fondare SELECT, è stato data engineer in Brooklyn Data Company e in diverse startup. Appassionato di open source, è anche maintainer di SQLFluff e autore di tre pacchetti dbt: dbt_artifacts, dbt_snowflake_monitoring e dbt_query_tags.