Usar distintos tamaños de warehouse para cada workload en Snowflake aporta un enorme valor en rendimiento y optimización de costos. dbt se integra de forma nativa con Snowflake y permite elegir warehouses específicos incluso a nivel de modelo. En este post te explicamos cómo aprovechar esta funcionalidad y compartimos algunas buenas prácticas. ¿Por qué cambiar el tamaño del warehouse?
Si tu proyecto de dbt ya tarda demasiado en ejecutarse, está provocando incumplimientos de SLA o simplemente una mala experiencia para el usuario, lo más probable es que aumentar el tamaño del warehouse mejore su velocidad. Y si ya subiste el tamaño predeterminado del warehouse de dbt, quizá quieras reducir costos aumentando el tamaño solo en los modelos que realmente lo necesitan.
Acelera tus modelos de dbt
Es habitual que los modelos tarden más a medida que crece el volumen de datos con el tiempo. En algunos modelos, esa ralentización es lineal respecto al volumen de datos. En otros no siempre es así, ya que las funciones de agregación y los joins pueden volverse exponencialmente intensivos en cómputo conforme aumenta el volumen de datos. Todos estos efectos pueden impactar el tiempo de ejecución de forma significativa, sobre todo si un modelo empieza a hacer spill a almacenamiento remoto (revisa nuestro post sobre el query profile para conocer más).
La forma más efectiva de acelerar cualquier query es reducir la cantidad de datos que procesa. Si un modelo se vuelve lento y usa una materialización de tipo table, considera usar una materialización incremental para procesar únicamente los datos nuevos o actualizados en cada ejecución.
Si ya estás usando incrementalización, o no es posible aplicarla, lo siguiente más recomendable para acelerar el modelo suele ser aumentar el tamaño del warehouse.
Cómo configurar el warehouse de Snowflake predeterminado de dbt
Por defecto, dbt usa el warehouse de Snowflake configurado en la entrada del profiles.yml del proyecto o, si no se especifica, el warehouse predeterminado del usuario de Snowflake de dbt. Al cambiar ese warehouse por otro más grande, o simplemente redimensionando el existente, dbt pasará a ejecutar todas sus queries en un warehouse mayor. Según dónde se ejecute dbt, el warehouse se cambia en el archivo profiles.yml o en dbt Cloud a nivel de entorno.
profiles.yml
En tu archivo profiles.yml, edita la configuración warehouse y apúntala a un virtual warehouse distinto. El tamaño de cada warehouse se configura en 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
En dbt Cloud, ve a Deploy > Environments en la barra superior. Elige el entorno que quieres editar y entra en Settings. Haz clic en Edit y baja hasta Deployment Connection, donde podrás cambiar el warehouse. El tamaño del warehouse se configura en Snowflake.
Sin embargo, cambiar el tamaño predeterminado del warehouse de dbt no siempre es lo más conveniente, ya que la mayoría de las queries del proyecto no se benefician de un warehouse mayor y eso terminará disparando los costos en Snowflake. Para más detalles sobre el impacto del tamaño del warehouse en la velocidad de las queries, revisa nuestro post sobre cómo dimensionar warehouses. En lugar de aumentar el tamaño predeterminado, recomendamos dejarlo en X-Small y sobrescribir el tamaño a nivel de cada modelo según se necesite.
Cómo configurar el tamaño de warehouse de Snowflake en un modelo de dbt
Configurar el warehouse a nivel de modelo nos permite elegir tamaños específicos según los requisitos de cada modelo, optimizando rendimiento y costos.
Warehouse hardcodeado
dbt ofrece la configuración de modelo snowflake_warehouse, que se ve así cuando se define en un modelo concreto:
{{ config(
snowflake_warehouse="dbt_large"
) }}
select
...
from {{ ref('stg_orders') }}
También se puede aplicar la configuración a todos los modelos de un directorio desde dbt_project.yml, así:
name: my_project
version: 1.0.0
---
models:
+snowflake_warehouse: 'dbt_xsmall'
my_project:
clickstream:
+snowflake_warehouse: 'dbt_large'
Nombre de warehouse dinámico según el entorno
En muchos casos, el warehouse que queremos usar en producción no es el mismo que usamos en desarrollo, ni el que usaríamos en un flujo de CI o de pruebas automatizadas. Lo mismo aplica a los warehouses que ahora estamos configurando a nivel de modelo. Para lograrlo, podemos usar un macro en lugar del valor literal del warehouse que teníamos antes:
{{ config(
snowflake_warehouse=get_warehouse('large')
) }}
select
...
from {{ ref('stg_orders') }}
Este macro puede incorporar la lógica para devolver el tamaño de warehouse adecuado según el entorno.
Supongamos que en producción creamos warehouses llamados dbt_production_<size> (dbt_production_xsmall, dbt_production_small, dbt_production_medium, etc.) y, para CI, warehouses llamados dbt_ci_<size>. En desarrollo local queremos simplemente usar el warehouse predeterminado e ignorar por completo el tamaño configurado. También queremos lanzar un error si el tamaño de warehouse elegido no está dentro de una lista permitida. Esto se logra con la siguiente lógica de 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 %}
Usar un macro para la configuración snowflake_warehouse solo funciona dentro de archivos de modelo; no se puede usar en el dbt_project.yml.
Cómo configurar el warehouse para otros recursos en dbt
Por ahora solo es posible configurar warehouses para modelos y snapshots. Si te interesa estar al tanto del soporte para otros recursos como los tests, échale un ojo a este issue de GitHub.
Cómo monitorear el rendimiento y el costo de los modelos de dbt
Echa un vistazo a nuestro paquete dbt_snowflake_monitoring, que incluye un modelo dbt_queries fácil de usar para analizar el rendimiento de los modelos de dbt a lo largo del tiempo. Atribuye los costos a cada ejecución de modelo, lo que facilita responder preguntas como "¿cuáles son los 10 modelos más costosos del último mes?".
¡Gracias por leernos! En un próximo post compartiremos más recomendaciones para optimizar el rendimiento de dbt en Snowflake. Suscríbete para recibir notificaciones de las próximas publicaciones y escríbenos sin dudar si tienes preguntas.
Niall Woodward·Co-founder & CTO de SELECT
Niall es Co-Founder y CTO de SELECT, una plataforma SaaS de gestión y optimización de costos para Snowflake. Antes de fundar SELECT, fue data engineer en Brooklyn Data Company y en varias startups. Como entusiasta del open source, también es mantenedor de SQLFluff y creador de tres paquetes de dbt: dbt_artifacts, dbt_snowflake_monitoring y dbt_query_tags.