Ir al contenido principal

Profundizando en Delta Lake: Descomprimiendo el registro de transacciones

Diving Into Delta Lake: Unpacking The Transaction Log

Publicado: 21 de agosto de 2019

Producto12 min de lectura

Delta Lake logo.
El registro de transacciones es clave para comprender Delta Lake porque es el hilo conductor que recorre muchas de sus características más importantes, incluidas las transacciones ACID, el manejo escalable de metadatos, el viaje en el tiempo y mucho más. En este artículo, exploraremos qué es el registro de transacciones de Delta Lake, cómo funciona a nivel de archivo y cómo ofrece una solución elegante al problema de las múltiples lecturas y escrituras simultáneas.

¿Qué es el registro de transacciones de Delta Lake?

El registro de transacciones de Delta Lake (también conocido como DeltaLog) es un registro ordenado de cada transacción que se ha realizado en una tabla de Delta Lake desde su inicio.

¿Para qué se utiliza el registro de transacciones?

Única fuente de verdad

Delta Lake se basa en Apache Spark™ para permitir que varios lectores y escritores de una tabla determinada trabajen en la tabla al mismo tiempo. Para mostrar a los usuarios vistas correctas de los datos en todo momento, el registro de transacciones de Delta Lake sirve como una única fuente de verdad: el repositorio central que rastrea todos los cambios que los usuarios realizan en la tabla.

Cuando un usuario lee una tabla de Delta Lake por primera vez o ejecuta una nueva consulta en una tabla abierta que se ha modificado desde la última vez que se leyó, Spark comprueba el registro de transacciones para ver qué nuevas transacciones se han publicado en la tabla y, a continuación, actualiza la tabla del usuario final con esos nuevos cambios. Esto garantiza que la versión de la tabla de un usuario esté siempre sincronizada con el registro maestro a partir de la consulta más reciente, y que los usuarios no puedan realizar cambios divergentes y conflictivos en una tabla.

La implementación de la atomicidad en Delta Lake

Una de las cuatro propiedades de las transacciones ACID, la atomicidad, garantiza que las operaciones (como INSERT o UPDATE) realizadas en su lago de datos se completen totalmente o no se completen en absoluto. Sin esta propiedad, es demasiado fácil que un fallo de hardware o un error de software haga que los datos se escriban solo parcialmente en una tabla, lo que da lugar a datos desordenados o dañados.

El registro de transacciones es el mecanismo a través del cual Delta Lake puede ofrecer la garantía de atomicidad. A todos los efectos, si no está registrado en el registro de transacciones, nunca sucedió. Al registrar solo las transacciones que se ejecutan de forma completa, y al utilizar ese registro como la única fuente de verdad, el registro de transacciones de Delta Lake permite a los usuarios razonar sobre sus datos y tener tranquilidad sobre su fiabilidad fundamental, a escala de petabytes.

¿Cómo funciona el registro de transacciones?

Descomposición de las transacciones en confirmaciones atómicas

Cada vez que un usuario realiza una operación para modificar una tabla (como INSERT, UPDATE o DELETE), Delta Lake divide esa operación en una serie de pasos discretos compuestos por una o más de las siguientes acciones.

  • Añadir archivo: añade un archivo de datos.
  • Eliminar archivo: elimina un archivo de datos.
  • Actualizar metadatos: actualiza los metadatos de la tabla (por ejemplo, cambiar el nombre, el esquema o la creación de particiones de la tabla).
  • Establecer transacción: registra que un trabajo de Structured Streaming ha confirmado un micro lote con el ID dado.
  • Cambiar protocolo: habilita nuevas características cambiando el registro de transacciones de Delta Lake al protocolo de software más reciente.
  • Información de confirmación: contiene información sobre la confirmación, qué operación se realizó, desde dónde y a qué hora.

Esas acciones se registran en el registro de transacciones como unidades atómicas ordenadas conocidas como confirmaciones.

Por ejemplo, supongamos que un usuario crea una transacción para añadir una nueva columna a una tabla y añadir más datos a ella. Delta Lake dividiría esa transacción en sus partes componentes y, una vez que la transacción se completa, las añade al registro de transacciones como las siguientes confirmaciones:

  1. Actualizar metadatos: cambiar el esquema para incluir la nueva columna
  2. Añadir archivo: para cada nuevo archivo añadido

El registro de transacciones de Delta Lake en el nivel de archivo

Cuando un usuario crea una tabla de Delta Lake, el registro de transacciones de esa tabla se crea automáticamente en el subdirectorio _delta_log. A medida que realiza cambios en esa tabla, esos cambios se registran como confirmaciones atómicas ordenadas en el registro de transacciones. Cada confirmación se escribe como un archivo JSON, comenzando con 000000.json. Los cambios adicionales en la tabla generan archivos JSON posteriores en orden numérico ascendente, de modo que la siguiente confirmación se escribe como 000001.json, la siguiente como 000002.json, y así sucesivamente.

Diagrama de la estructura de archivos del registro de transacciones de Delta Lake.

Por lo tanto, como ejemplo, tal vez podríamos añadir registros adicionales a nuestra tabla desde los archivos de datos 1.parquet y 2.parquet. Esa transacción se añadiría automáticamente al registro de transacciones, guardado en el disco como confirmación 000000.json. Entonces, tal vez cambiemos de opinión y decidamos eliminar esos archivos y añadir un nuevo archivo en su lugar (3.parquet). Esas acciones se registrarían como la siguiente confirmación en el registro de transacciones, como 000001.json, como se muestra a continuación.

Diagrama que ilustra dos confirmaciones que realizan operaciones en el mismo archivo.

Aunque 1.parquet y 2.parquet ya no forman parte de nuestra tabla de Delta Lake, su adición y eliminación todavía se registran en el registro de transacciones porque esas operaciones se realizaron en nuestra tabla, a pesar de que finalmente se anularon entre sí. Delta Lake todavía conserva confirmaciones atómicas como estas para garantizar que, en caso de que necesitemos auditar nuestra tabla o utilizar el "viaje en el tiempo" para ver cómo era nuestra tabla en un momento dado, podamos hacerlo con precisión.

Además, Spark no elimina los archivos del disco de forma anticipada, aunque hayamos eliminado los archivos de datos subyacentes de nuestra tabla. Los usuarios pueden eliminar los archivos que ya no son necesarios mediante VACUUM.

Recálculo rápido del estado con archivos de punto de control

Una vez que hemos realizado varias confirmaciones en el registro de transacciones, Delta Lake guarda un archivo de punto de control en formato Parquet en el mismo subdirectorio _delta_log. Delta Lake genera automáticamente el punto de control según sea necesario para mantener un buen rendimiento de lectura.

Diagrama que ilustra la estructura de archivos del registro de transacciones de Delta Lake, incluidos los directorios de partición.

Estos archivos de punto de control guardan todo el estado de la tabla en un momento dado, en formato Parquet nativo que es rápido y fácil de leer para Spark. En otras palabras, ofrecen al lector de Spark una especie de "atajo" para reproducir completamente el estado de una tabla que permite a Spark evitar el reprocesamiento de lo que podrían ser miles de archivos JSON pequeños e ineficientes.

Para ponerse al día, Spark puede ejecutar una operación listFrom para ver todos los archivos en el registro de transacciones, saltar rápidamente al archivo de punto de control más reciente y solo procesar las confirmaciones JSON realizadas desde que se guardó el archivo de punto de control más reciente.

Para demostrar cómo funciona esto, imagine que hemos creado confirmaciones hasta 000007.json como se muestra en el diagrama a continuación. Spark está al día a través de esta confirmación, habiendo almacenado automáticamente en caché la versión más reciente de la tabla en la memoria. Mientras tanto, sin embargo, varios otros escritores (tal vez sus compañeros de equipo demasiado entusiastas) han escrito nuevos datos en la tabla, añadiendo confirmaciones hasta 0000012.json.

Para incorporar estas nuevas transacciones y actualizar el estado de nuestra tabla, Spark ejecutará entonces una operación listFrom version 7 para ver los nuevos cambios en la tabla.

Diagrama que ilustra cómo Spark lee los archivos de punto de control recientes para calcular rápidamente el estado de la tabla.

En lugar de procesar todos los archivos JSON intermedios, Spark puede saltar al archivo de punto de control más reciente, ya que contiene todo el estado de la tabla en la confirmación #10. Ahora, Spark solo tiene que realizar el procesamiento incremental de 0000011.json y 0000012.json para tener el estado actual de la tabla. A continuación, Spark almacena en caché la versión 12 de la tabla en la memoria. Siguiendo este flujo de trabajo, Delta Lake puede utilizar Spark para mantener el estado de una tabla actualizado en todo momento de forma eficiente.

Cómo lidiar con múltiples lecturas y escrituras simultáneas

Ahora que entendemos cómo funciona el registro de transacciones de Delta Lake a un alto nivel, hablemos de la simultaneidad. Hasta ahora, nuestros ejemplos han cubierto principalmente escenarios en los que los usuarios confirman las transacciones linealmente, o al menos sin conflicto. Pero, ¿qué sucede cuando Delta Lake está lidiando con múltiples lecturas y escrituras simultáneas?

La respuesta es simple. Dado que Delta Lake está impulsado por Apache Spark, no solo es posible que varios usuarios modifiquen una tabla a la vez, sino que se espera. Para manejar estas situaciones, Delta Lake emplea el control de concurrencia optimista.

¿Qué es el control de concurrencia optimista?

El control de concurrencia optimista es un método para lidiar con transacciones simultáneas que asume que las transacciones (cambios) realizadas en una tabla por diferentes usuarios pueden completarse sin entrar en conflicto entre sí. Es increíblemente rápido porque, cuando se trata de petabytes de datos, existe una alta probabilidad de que los usuarios estén trabajando en diferentes partes de los datos por completo, lo que les permite completar transacciones no conflictivas simultáneamente.

Por ejemplo, imagine que usted y yo estamos trabajando juntos en un rompecabezas. Siempre y cuando ambos estemos trabajando en diferentes partes del mismo (usted en las esquinas y yo en los bordes, por ejemplo), no hay ninguna razón por la que no podamos trabajar cada uno en nuestra parte del rompecabezas más grande al mismo tiempo y terminar el rompecabezas el doble de rápido. Solo cuando necesitamos las mismas piezas, al mismo tiempo, hay un conflicto. Eso es el control de concurrencia optimista.

Por supuesto, incluso con el control de concurrencia optimista, a veces los usuarios intentan modificar las mismas partes de los datos al mismo tiempo. Afortunadamente, Delta Lake tiene un protocolo para eso.

Resolución de conflictos de forma optimista

Para ofrecer transacciones ACID, Delta Lake tiene un protocolo para averiguar cómo se deben ordenar las confirmaciones (conocido como el concepto de serialización en las bases de datos) y determinar qué hacer en caso de que se realicen dos o más confirmaciones al mismo tiempo. Delta Lake maneja estos casos implementando una regla de exclusión mutua, luego intenta resolver cualquier conflicto de forma optimista. Este protocolo permite a Delta Lake cumplir con el principio ACID de aislamiento, que garantiza que el estado resultante de la tabla después de múltiples escrituras simultáneas sea el mismo que si esas escrituras se hubieran producido en serie, aisladas entre sí.

En general, el proceso se desarrolla de la siguiente manera:

  1. Registre la versión inicial de la tabla.
  2. Registre las lecturas/escrituras.
  3. Intente una confirmación.
  4. Si alguien más gana, compruebe si algo de lo que ha leído ha cambiado.
  5. Repita.

Para ver cómo se desarrolla todo esto en tiempo real, echemos un vistazo al diagrama a continuación para ver cómo Delta Lake gestiona los conflictos cuando surgen. Imagine que dos usuarios leen de la misma tabla y luego cada uno intenta añadir algunos datos a ella.

Ilustración del control de concurrencia optimista mostrando dos usuarios con confirmaciones conflictivas.

  • Delta Lake registra la versión inicial de la tabla (versión 0) que se lee antes de realizar cualquier cambio.
  • Los usuarios 1 y 2 intentan añadir algunos datos a la tabla al mismo tiempo. Aquí, nos hemos encontrado con un conflicto porque solo una confirmación puede venir a continuación y registrarse como 000001.json.
  • Delta Lake maneja este conflicto con el concepto de "exclusión mutua", lo que significa que solo un usuario puede realizar con éxito la confirmación 000001.json. La confirmación del usuario 1 se acepta, mientras que la del usuario 2 se rechaza.
  • En lugar de lanzar un error para el usuario 2, Delta Lake prefiere manejar este conflicto de forma optimista. Comprueba si se han realizado nuevas confirmaciones en la tabla y actualiza la tabla silenciosamente para reflejar esos cambios, luego simplemente vuelve a intentar la confirmación del usuario 2 en la tabla recién actualizada (sin ningún procesamiento de datos), confirmando con éxito 000002.json.

En la gran mayoría de los casos, esta conciliación se produce de forma silenciosa, fluida y exitosa. Sin embargo, en el caso de que haya un problema irreconciliable que Delta Lake no pueda resolver de forma optimista (por ejemplo, si el usuario 1 eliminó un archivo que el usuario 2 también eliminó), la única opción es lanzar un error.

Como nota final, dado que todas las transacciones realizadas en las tablas de Delta Lake se almacenan directamente en el disco, este proceso satisface la propiedad ACID de durabilidad, lo que significa que persistirá incluso en caso de fallo del sistema.

LÍDER 5X

Gartner®: Databricks, líder en bases de datos en la nube

Otros casos de uso

Viaje en el tiempo

Cada tabla es el resultado de la suma total de todas las confirmaciones registradas en el registro de transacciones de Delta Lake, ni más ni menos. El registro de transacciones proporciona una guía de instrucciones paso a paso, que detalla exactamente cómo pasar del estado original de la tabla a su estado actual.

Por lo tanto, podemos recrear el estado de una tabla en cualquier momento comenzando con una tabla original y procesando solo las confirmaciones realizadas antes de ese punto. Esta poderosa capacidad se conoce como "viaje en el tiempo" o control de versiones de datos, y puede ser un salvavidas en cualquier número de situaciones. Para obtener más información, lea la entrada de blog Presentación del viaje en el tiempo de Delta para lagos de datos a gran escala, o consulte la documentación del viaje en el tiempo de Delta Lake.

Linaje de datos y depuración

Como registro definitivo de cada cambio realizado en una tabla, el registro de transacciones de Delta Lake ofrece a los usuarios un linaje de datos verificable que es útil para fines de gobernanza, auditoría y cumplimiento. También se puede utilizar para rastrear el origen de un cambio inadvertido o un error en una canalización hasta la acción exacta que lo causó. Los usuarios pueden ejecutar DESCRIBE HISTORY para ver los metadatos sobre los cambios que se realizaron.

Resumen del registro de transacciones de Delta Lake

En este blog, profundizamos en los detalles de cómo funciona el registro de transacciones de Delta Lake, incluyendo:

  • Qué es el registro de transacciones, cómo está estructurado y cómo se almacenan las confirmaciones como archivos en el disco.
  • Cómo el registro de transacciones sirve como una única fuente de verdad, lo que permite a Delta Lake implementar el principio de atomicidad.
  • Cómo Delta Lake calcula el estado de cada tabla, incluyendo cómo utiliza el registro de transacciones para ponerse al día desde el punto de control más reciente.
  • Uso del control de concurrencia optimista para permitir múltiples lecturas y escrituras simultáneas, incluso cuando las tablas cambian.
  • Cómo Delta Lake utiliza la exclusión mutua para garantizar que las confirmaciones se serialicen correctamente y cómo se vuelven a intentar silenciosamente en caso de conflicto.
¿Está interesado en el código abierto de Delta Lake?
Visite el centro en línea de Delta Lake para obtener más información, descargar el código más reciente y unirse a la comunidad de Delta Lake.

Relacionado

Artículos de esta serie:
Inmersión en Delta Lake #1: Desembalaje del registro de transacciones
Inmersión en Delta Lake #2: Aplicación y evolución del esquema
Inmersión en Delta Lake #3: Internos de DML (Actualización, Eliminación, Fusión)

Artículos relacionados:
¿Qué es un lago de datos?
Producción de Machine Learning con Delta Lake

(Esta entrada del blog ha sido traducida utilizando herramientas basadas en inteligencia artificial) Publicación original

No te pierdas ninguna publicación de Databricks.

Suscríbete a nuestro blog y recibe las últimas publicaciones en tu bandeja de entrada.