Seleccionar página
19 de junio de 2024

Qué es Delta Live Tables y cómo implementarlo con Databricks Unity Catalog

Vamos a explicar que es Delta Live Tables, y diferenciarlo de otros términos parecido del campo, así como la implementación de Unity Catalog, cómo es desarrollar con Delta Live Tables y las ventajas y desventajas que nos hemos encontrado.

 

¡Comenzamos!

Delta Live Tables busca acelerar la transformación de datos y generación de modelos, permitiendo al Data Engineer centrarse en la parte de código, apoyándose en el resto de las herramientas que tiene Databricks, como la parte de repositorio; para el versionado del código, Unity Catalog; para Data Governance o la facilidad de cambiar entre entornos desde su pipeline.

Delta Live Table es un Framework o acelerador de trabajo, que busca, que tú, como ingeniero, enfoques la mayor parte del tiempo de desarrollo en el código de transformación y modelado y no tanto en la parte de control o permisos, pero antes de meternos más en profundidad, es importante no confundirlo con otros términos del campo, como Delta Lake, Delta Table o incluso Parquet, ya que estos elementos están relacionados con el almacenamiento del dato, no con el código en sí.

Aquí nos centraremos en Delta Live Table, ya que de los otros elementos también se podría escribir un blog entero, pero un breve resumen de los otros elementos podría ser:

  • Delta Lake: Es una capa de almacenamiento optimizada que proporciona las bases para la creación de Delta Tables, es decir, el sitio en el que guardas los datos o archivos.
  • Delta Tables: Es el conjunto de datos/archivos que conforman una tabla, son una extensión de los archivos Parquet, a los cuales les otorga una capa extra de metadata que nos permite realizar transacciones ACID, operaciones DML o Time Travel.
  • Parquet: Es el archivo base que contiene los datos en sí, que están especializados para el Big Data, por ser archivos columnares, es decir, los datos de cada columna se guardan de forma consecutiva, permitiendo una mejor compresión, pues permite tipar cada columna y no guardar la fila como un solo ente, reduciendo así el tamaño del archivo, tener metadata de cada columna, o si no se quieren leer todas las columnas, guardar en memoria solo las columnas seleccionadas.

Ahora ya metiéndonos más con Delta Live Tables, o DLT, vamos a intentar explicar cómo Databricks busca que te centres más en la parte de código apoyándose del resto de sus características.

introducing-delta-live-tables

1. Repos: para el versionado de código y tener el histórico de cambios, y poder volver atrás de ser necesario.

2. Unity Catalog: para Data Discovery y Data Governance, es decir, la parte de permisos y visibilidad del dato.

3. Databricks Workflows: para programar la orquestación.

4. Expectations: Para la parte de Data Quality.

5. Full Refresh: permite recargar y reprocesar todos los datos.

6. Dependency Managment: DLT busca las dependencias entre tablas para poder gestionar mejor la paralelización de las ingestas y que las cargas se hagan en orden.

7. Incremental Computation: DLT se encarga de gestionar los archivos cargados y de la incrementalidad de las tablas.

Documentación oficial: Delta Live Tables

¿Cómo funciona?

En Delta Live Table, los pipelines son el centro de todo, es donde se indican los notebooks a ejecutar y la orquestación de estos. En los notebooks se definan las consultas, ya sea en Python o SQL, que determinan el contenido de las tablas que se van a crear, pero el mantenimiento y la carga de estas se encarga DLT, ya que cómo tal, no puedes ejecutar el código de forma independiente, solo desde el propio pipeline, en el cual podrás ver las tablas que se definieron y el linaje entre ellas.

delta-live-table-pipelines

Es importante saber que la forma en que definas las consultas determina el tipo de tablas que se crean: Streaming Tables o Materialized Views.

  • Streaming tables: están pensadas para orígenes stream o procesamientos incrementales, y principalmente para orígenes de tipo append, aunque también son el tipo de tabla, como target, que permite realizar un apply_changes(), que sería la opción de Upsert, para ingestar nuevos registros, actualizar registros existentes e incluso limpiar duplicados.
  • Materialized Views: se podría resumir como las vistas normales de SQL, que definen el contenido de la tabla, pero son lo suficientemente potentes para manejar los cambios realizados en las tablas de las que depende y recalcular el contenido para mostrar siempre el dato más actualizado.

Descarga el Ebook «Better Together: Databricks Unity Catalog & Microsoft Purview»

Dado que tanto Unity Catalog de Databricks como Microsoft Purview son presentadas como soluciones para la Gobernanza de los datos, es habitual que surjan preguntas como las siguientes: ¿Son herramientas complementarias o sustitutivas? ¿Puedo utilizar Unity Catalog de Databricks como mi única herramienta de Gobernanza para todo mi patrimonio de datos?

Descarga ahora este documento y descubre en detalle los aspectos que convierten la utilización conjunta Unity Catalog y Microsoft Purview en la herramienta perfecta para el gobierno del dato de tu empresa.

Estructura medallón

Una de las formas más comunes para almacenar el dato, es la estructura medallón, que se compone de tres capas: Bronze, Silver y Gold. Por lo que teniendo en cuenta los tipos de tabla mencionados en el anterior, una forma de definir y guardar los datos podría ser la siguiente.

  • Bronze: Straming Table, va a almacenar todo el histórico de datos, por lo que ir guardando los datos según lleguen es lo ideal.
  • Silver: Streaming Table, va a permitir leer los datos según lleguen a la capa Bronze, y junto al método apply_changes y las expectations (restricciones), va a permitir quitar los duplicados, actualizar los registros y limpiar los datos según las restricciones que se pongan, estilo que la PK no sea NULL o un límite de fecha.
  • Gold: Materialized Views, ya que es la capa en la que se realizan los cálculos de negocios y las agregaciones, y para eso es importante tener todo el conjunto de datos para realizar los cálculos.
estructura-medallon

Creación del Pipeline de Delta Live Table

La parte que se encarga de todo el proceso son los Pipelines, que cuando los creas puedes indicar las configuraciones de este, una de las opciones es donde guardar el dato, Hive Metastore o Unity Catalog, que es la opción que vamos a utilizar nosotros y sobre la que vamos a hablar. Es importante tener en cuenta que, una vez creas el pipeline, el Catálogo, NO puedes modificarlo, pero sí el Schema (Database) en el que se guardan los datos. También puedes seleccionar el modo del Pipeline, ya sea Triggered, para ejecuciones por Lotes o Continuous, ejecuciones en Real Time.

También es la parte donde seleccionas el Source Code, que son los notebooks que crean las tablas, la configuración del Clúster que va a ejecutar dicho pipeline o incluso poner notificaciones al correo.

creacion-pipeline-delta-live-table

Una vez creado, ya verás toda la parte visual, y en la parte central, una vez ejecutados los notebooks, es donde verás las tablas y su linaje.

Nootebooks: código de cada capa

Ahora que tenemos unas nociones básicas de todo, vamos a entrar más en detalle en la parte del código para cada capa.

  • Bronze: en esta capa leeremos los datos que vayan llegando al origen de datos, en nuestro caso, un Volumen de Unity Catalog, que iremos leyendo con el AutoLoader, que se encargará de ir manteniendo los archivo que ya se hayan cargado para no volver a cargarlos e ir cargando solo los nuevos.
nootebooks-codigo-cada-capa-bronze
  • Silver: En esta capa también utilizaremos una Streaming Table, ya que nos permite realizar un apply_changes(), que recordemos, es una versión de Upsert para Delta Live Tables, y además usaremos expectations, que son restricciones que ponemos, para en caso de que no la cumpla, el registros se elimine, falle o simplemente salte un aviso en el pipeline. Para nuestro caso, para simplificar, creamos un diccionario para todas las tablas en el que indicamos la PK (Para actualizar registros, o eliminar duplicados), el Sequence By, que es la columna que usamos como criterio para obtener el último registro para cada PK, y las expectations, en el caso de la captura, hemos indicado dos, pero para el resto de las tablas, sólo la de valid_pk.
notebooks-codigo-cada-capa-silver-uno
notebooks-codigo-cada-capa-silver-dos
  • Gold: en este caso, trabajaremos con Materialized Views, ya que es la capa en la que realizaremos las agrupaciones y los cálculos de agregaciones de negocio.
notebooks-codigo.-cada-capa-gold

En base al código que acabo de mostrar, te preguntarás como sé que tipo de tabla se ha creado o como le indico si es una Materialized Views o una Streaming Table. Lo primero es fácil de ver, en la parte visual de DLT, dentro de Databricks -> Data Engineering -> Delta Live Table -> Nuestro Pipeline, te mostrará todo el linaje de las tablas, y cuando pinchas en un cuadro, que hacen referencia a las tablas que se han creado en el código, en los detalles de cada tabla, a la derecha, se indica de que tipo es.

Bronze:

notebooks-codigo.-cada-capa-bronze-tres

Silver:

notebooks-codigo.-cada-capa-bronze-tres

Gold:

table-gold

Ahora que hemos visto dónde se puede ver el tipo de tabla, a excepción de la capa Silver, que se indica claramente con dlt.create_streaming_table(), en las capas de Bronze y Gold, no se indica que tipo de tabla es, y aun así, las ha creado de distinto tipo, y eso es porque el decorator @dlt.table(), según se defina la consulta y como se lean los datos de origen, deduce el formato de la tabla final:

  1. Bronze: en esta capa estamos leyendo datos con AutoLoader, por lo que está leyendo datos en forma Stream, y entonces se crea una Streaming Table.

2. Silver: en este caso, se indica claramente que es una Streaming Table a la hora de crear la tabla con el método dlt.create_streaming_table().

3. Gold: en esta capa se está utilizando el método read(), que lee todo el origen, por lo que crea una Materialized View, si utilizase el método dlt.read_stream(), crearía una Sreaming Table.

¿Como se puede saber esto? Si, por ejemplo, dentro del Notebook, clicas en el método y pulsas F12, te enseñará el Source Code y la descripción del mismo y para cada tipo de lectura:

  • dlt.read()
table-gold
  • dlt.read_stream()
tipo-lectura-uno

Es importante saber que una vez creas una tabla en un formato, si después cambias la consulta para que se utilice el otro, saltará un error, por lo que tendrás realizar un reproceso FULL para sobrescribir la tabla y que la vuelva a crear.

Ejecución del Pipeline

Una vez quieras ejecutar el código, es muy sencillo, desde el pipeline, arriba a la derecha hay diferentes botones, y uno de ellos es para ejecutarlo.

ejecucion-pipeline
  • Start: Permite ejecutar el pipeline de forma incremental
    • Full refresh all: permite recargar y crear de 0 todas las tablas.
  • Development/Production: es un botón toggle que permite seleccionar el modo de trabajo, la principal diferencia está en el tiempo de apagado y que el esquema interno de trabajo del pipeline, son distintos.
  • Settings: Permite modificar algunas propiedades del pipeline, por si las quieres cambiar después de su creación, y añadir nuevos notebooks según vas desarrollando y probando.
  • Schedule: permite programar la ejecución del Pipeline.
  • Select tables for refresh: justo encima del gráfico de linaje, está este botón, que abre una nueva ventana, que permite seleccionar las tablas que quieres ejecutar o recargar desde 0, en los botones que aparecen abajo a la derecha.
ejecucion-pipeline-dos

Ventajas

Integración Databricks

Se integra perfectamente con el resto de las características de Databricks:

  • Unity Catalog
  • Repositorio de Código
  • Workflows (orquestación)

Integración Databricks

Se integra perfectamente con el resto de las características de Databricks:

  • Unity Catalog
  • Repositorio de Código
  • Workflows (orquestación)

Consulta por lotes o continua

Desde la propia configuración del Pipelines, puedes cambiar rápidamente entre ejecución por Trigger o de forma Continua.

Integración Databricks

Se integra perfectamente con el resto de las características de Databricks:

  • Unity Catalog
  • Repositorio de Código
  • Workflows (orquestación)

Linaje

Se puede ver el linaje y las relaciones entre las tablas de las distintas capas de forma visual.

Integración Databricks

Se integra perfectamente con el resto de las características de Databricks:

  • Unity Catalog
  • Repositorio de Código
  • Workflows (orquestación)

Optimización del clúster

Gracias a que primero analiza las consultas y sus relaciones, puede maximizar el uso del clúster, paralelizando las consultas, ya que sabe el linaje y las necesidades de cada tabla de las distintas capas.

Integración Databricks

Se integra perfectamente con el resto de las características de Databricks:

  • Unity Catalog
  • Repositorio de Código
  • Workflows (orquestación)

Facilidad de reproceso

En caso de que necesites reprocesar unas tablas, es muy sencillo, pues desde la propia parte visual puedes seleccionar las tablas que quieres refrescar.

Integración Databricks

Se integra perfectamente con el resto de las características de Databricks:

  • Unity Catalog
  • Repositorio de Código
  • Workflows (orquestación)

Facilidad de trabajo

Ya que te puedes centrar principalmente en la parte del código de carga, limpieza de datos y modelado, gracias a la integración de Databricks con sus otras características.

Integración Databricks

Se integra perfectamente con el resto de las características de Databricks:

  • Unity Catalog
  • Repositorio de Código
  • Workflows (orquestación)

Muy visual e intuitivo

Desde la parte del pipeline, se pueden ver todas las tablas que se están cargando, su relación con las otras capas, y dentro de los detalles de cada tabla, puedes ver la cantidad de registros que se han ingestado y las expectations, así como la cantidad de registros que no la cumplen.

Desventajas

Limitaciones de Unity Catalog

A la hora de desarrollar, nos hemos encontrado con algunas limitaciones:

  1. Las consultas DML no pueden modificar el esquema de una Streaming Table
  2. No se puede indicar el LOCATION de las tablas
  3. Actualmente, las UDF de Python sólo están en preview
  4. No se pueden realizar RLS ni Data Masking
  5. Más…

Limitaciones de Unity Catalog

A la hora de desarrollar, nos hemos encontrado con algunas limitaciones:

  1. Las consultas DML no pueden modificar el esquema de una Streaming Table
  2. No se puede indicar el LOCATION de las tablas
  3. Actualmente, las UDF de Python sólo están en preview
  4. No se pueden realizar RLS ni Data Masking
  5. Más…

Guardado en diferentes esquemas físicos

El catálogo y el esquema en el que se van a guardar las tablas se indican en las propiedades del pipeline y no se pueden modificar dentro de cada Notebook, por lo que todas las tablas de las distintas capas estarán todas mezcladas dentro del mismo esquema.

La solución que hemos encontrado para esto es crear tres DLT distintos, uno para cada capa, pero esto implica llamar desde un Workflow cada DLT, por lo que implicaría levantar 3 clúster, pues no se pueden reaprovechar.

Limitaciones de Unity Catalog

A la hora de desarrollar, nos hemos encontrado con algunas limitaciones:

  1. Las consultas DML no pueden modificar el esquema de una Streaming Table
  2. No se puede indicar el LOCATION de las tablas
  3. Actualmente, las UDF de Python sólo están en preview
  4. No se pueden realizar RLS ni Data Masking
  5. Más…

Tablas manejadas

Todas las tablas que se crean son tablas manejadas.

Limitaciones de Unity Catalog

A la hora de desarrollar, nos hemos encontrado con algunas limitaciones:

  1. Las consultas DML no pueden modificar el esquema de una Streaming Table
  2. No se puede indicar el LOCATION de las tablas
  3. Actualmente, las UDF de Python sólo están en preview
  4. No se pueden realizar RLS ni Data Masking
  5. Más…

Limitación de tablas

Sólo se pueden guardar datos como Streaming Tables o Materialized Views, lo cual tienen algunos limitantes, por ejemplo, el tema de RLS o Data Masking.

Limitaciones de Unity Catalog

A la hora de desarrollar, nos hemos encontrado con algunas limitaciones:

  1. Las consultas DML no pueden modificar el esquema de una Streaming Table
  2. No se puede indicar el LOCATION de las tablas
  3. Actualmente, las UDF de Python sólo están en preview
  4. No se pueden realizar RLS ni Data Masking
  5. Más…

Realización de pruebas

Al no poder ejecutar funciones de DLT fuera del entorno de los pipelines, al principio puede ser un poco lioso hacer pruebas, ya que, si quieres realizar pruebas de los dataframes, o vas haciendo pruebas desde el pipeline siempre o escribes en PySpark convencional y después pasas ese código al propio de Delta Live Table.

Conclusión

Es una herramienta potente que puede ayudar a los desarrolladores a centrarse en el código y acelerar el desarrollo de las consultas, es muy visual y es sencillo de cambiar entre entornos de desarrollo de DEV y PRO, es solo un botón. Pero también nos hemos encontrado con algunas limitaciones, sobre todo a la hora de guardar los datos, ya que cuando utilizas Unity Catalog, todo el tema del almacenamiento lo gestiona el propio sistema, sólo hay dos tipos de tablas y el hecho de separar, física y visualmente, los datos y archivos de las diferentes capas, que puede llegar a hacer demasiado lioso el trabajar con los esquemas si la cantidad de tablas escala demasiado.

Por lo que, por ahora, para proyectos pequeños o medianos, diría que es una herramienta idónea y que se ha de tener en cuenta para los desarrollos de ETL, ya que busca la máxima optimización del clúster.

santiago brandariz-fuentes

Santiago Brandariz Fuentes

DPE