Unterschiedliche Warehouse-Größen für verschiedene workloads in Snowflake sind ein enormer Hebel für Performance und Kostenoptimierung. dbt integriert sich nativ mit Snowflake, sodass sich bestimmte Warehouses bis auf Modellebene auswählen lassen. In diesem Beitrag zeigen wir, wie Sie dieses Feature optimal nutzen, und teilen Best Practices. Warum die Warehouse-Größe ändern?
Wenn Ihr dbt-Projekt immer länger zur Ausführung braucht, dadurch SLAs gerissen werden oder die User Experience leidet, lässt sich die Geschwindigkeit mit einer größeren Warehouse-Größe in der Regel deutlich verbessern. Haben Sie die Standard-Warehouse-Größe von dbt bereits erhöht, möchten Sie womöglich Kosten senken, indem Sie nur jene Modelle hochskalieren, die tatsächlich davon profitieren.
dbt-Modelle beschleunigen
Mit wachsendem Datenvolumen laufen Modelle im Laufe der Zeit oft länger. Bei manchen Modellen verläuft diese Verlangsamung linear zum Datenvolumen, bei anderen nicht – denn Aggregatfunktionen und Joins können mit zunehmender Datenmenge exponentiell rechenintensiv werden. All das kann die Ausführungszeit erheblich verlängern, insbesondere wenn ein Modell anfängt, in den Remote Storage auszulagern (mehr dazu in unserem Beitrag zum Query Profile).
Der mit Abstand wirksamste Hebel zur Beschleunigung einer Query ist, die verarbeitete Datenmenge zu reduzieren. Wenn ein Modell mit Table Materialization langsam wird, prüfen Sie, ob sich eine Incremental Materialization anbietet, um bei jedem Lauf nur neue oder geänderte Daten zu verarbeiten.
Arbeiten Sie bereits inkrementell oder ist das nicht möglich, ist eine größere Warehouse-Größe meist der nächste sinnvolle Schritt, um das Modell zu beschleunigen.
Das Standard-Snowflake-Warehouse von dbt konfigurieren
Standardmäßig nutzt dbt das in der profiles.yml des Projekts hinterlegte Snowflake Warehouse – oder, falls dort nichts gesetzt ist, das Default-Warehouse des dbt-Snowflake-Users. Tauschen Sie dieses Warehouse gegen ein größeres aus oder vergrößern Sie das bestehende, führt dbt fortan alle Queries auf einem größeren Warehouse aus. Je nachdem, wo dbt läuft, lässt sich das Warehouse in der profiles.yml oder in dbt Cloud auf Environment-Ebene ändern.
profiles.yml
Passen Sie in Ihrer profiles.yml den warehouse-Eintrag auf ein anderes Virtual Warehouse an. Die Größe des jeweiligen Warehouses konfigurieren Sie 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
Navigieren Sie in dbt Cloud im oberen Menü zu Deploy > Environments. Wählen Sie das gewünschte Environment aus und klicken Sie auf Settings. Klicken Sie auf Edit und scrollen Sie zu Deployment Connection – dort lässt sich das Warehouse ändern. Die Größe des Warehouses konfigurieren Sie in Snowflake.
Die Standard-Warehouse-Größe von dbt pauschal zu erhöhen, ist allerdings selten klug: Die meisten Queries im Projekt profitieren nicht von einem größeren Warehouse – das treibt lediglich die Snowflake-Kosten. Mehr zum Einfluss der Warehouse-Größe auf die Query-Geschwindigkeit lesen Sie in unserem Beitrag zum Warehouse-Sizing. Statt die Default-Größe hochzudrehen, empfehlen wir, sie auf X-Small zu belassen und die Warehouse-Größe bei Bedarf gezielt auf Modellebene zu überschreiben.
Die Snowflake-Warehouse-Größe eines dbt-Modells konfigurieren
Konfigurieren wir das Warehouse auf Modellebene, lässt sich für jedes Modell die passende Größe wählen – und damit Performance wie Kosten gezielt optimieren.
Fest hinterlegtes Warehouse
dbt stellt dafür die Modellkonfiguration snowflake_warehouse bereit, die in einem konkreten Modell so aussieht:
{{ config(
snowflake_warehouse="dbt_large"
) }}
select
...
from {{ ref('stg_orders') }}
Alternativ lässt sich die Konfiguration über die dbt_project.yml auf alle Modelle in einem Verzeichnis anwenden, zum Beispiel:
name: my_project
version: 1.0.0
---
models:
+snowflake_warehouse: 'dbt_xsmall'
my_project:
clickstream:
+snowflake_warehouse: 'dbt_large'
Dynamischer Warehouse-Name je nach Environment
Oft unterscheidet sich das Warehouse, das wir in Produktion einsetzen, von dem, das wir in der Entwicklung, in CI oder in automatisierten Tests verwenden möchten. Dasselbe gilt für die Warehouses, die wir nun pro Modell konfigurieren. Statt eines fest hinterlegten Werts können wir dafür ein Macro einsetzen:
{{ config(
snowflake_warehouse=get_warehouse('large')
) }}
select
...
from {{ ref('stg_orders') }}
Dieses Macro kann die Logik enthalten, die je nach Environment die gewünschte Warehouse-Größe zurückgibt.
Nehmen wir an, in Produktion gibt es Warehouses nach dem Schema dbt_production_<size> (dbt_production_xsmall, dbt_production_small, dbt_production_medium usw.) und in CI Warehouses nach dem Schema dbt_ci_<size>. Für die lokale Entwicklung wollen wir schlicht das Default-Warehouse nutzen und die konfigurierte Warehouse-Größe komplett ignorieren. Zusätzlich soll ein Fehler geworfen werden, wenn die gewählte Warehouse-Größe nicht in einer verwalteten Liste enthalten ist. Das lässt sich mit folgender Macro-Logik umsetzen:
{% 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 %}
Ein Macro für die snowflake_warehouse-Konfiguration funktioniert ausschließlich in Modelldateien und lässt sich nicht in der dbt_project.yml verwenden.
Warehouses für weitere Ressourcen in dbt konfigurieren
Aktuell lassen sich Warehouses nur für Modelle und Snapshots konfigurieren. Wenn Sie verfolgen möchten, ob künftig auch andere Ressourcen wie Tests unterstützt werden, werfen Sie einen Blick auf dieses GitHub-Issue.
Performance und Kosten von dbt-Modellen überwachen
Werfen Sie einen Blick auf unser dbt_snowflake_monitoring dbt-Package: Es liefert ein einfach nutzbares dbt_queries-Modell, mit dem sich die Performance von dbt-Modellen im Zeitverlauf nachvollziehen lässt. Es ordnet einzelnen Modellläufen Kosten zu – so beantworten Sie Fragen wie "Was waren die 10 teuersten Modelle im letzten Monat?" mühelos.
Vielen Dank fürs Lesen! In einem kommenden Beitrag teilen wir weitere Empfehlungen zur Optimierung der dbt-Performance auf Snowflake. Abonnieren Sie uns, um keinen Beitrag zu verpassen – und melden Sie sich gerne, wenn Sie Fragen haben!
Niall Woodward · Co-Founder & CTO von SELECT
Niall ist Co-Founder & CTO von SELECT, einer SaaS-Plattform für Snowflake-Kostenmanagement und -Optimierung. Vor SELECT war Niall Data Engineer bei Brooklyn Data Company und mehreren Startups. Als Open-Source-Enthusiast ist er zudem Maintainer von SQLFluff und Entwickler dreier dbt-Packages: dbt_artifacts, dbt_snowflake_monitoring und dbt_query_tags.