Sumérgete en Delta Lake: cumplimiento de esquemas y evolución

¡Hola, Habr! Presento a su atención la traducción del artículo. "Buceando en el Lago Delta: Aplicación y Evolución de Esquemas" autores Burak Yavuz, Brenner Heintz y Denny Lee, que se preparó antes del inicio del curso Ingeniero de datos de OTUS.

Sumérgete en Delta Lake: cumplimiento de esquemas y evolución

Los datos, como nuestra experiencia, se acumulan y evolucionan constantemente. Para mantenerse al día, nuestros modelos mentales del mundo deben adaptarse a nuevos datos, algunos de los cuales contienen nuevas dimensiones, nuevas formas de observar cosas de las que antes no teníamos idea. Estos modelos mentales no son muy diferentes de los esquemas de tablas que definen cómo categorizamos y procesamos nueva información.

Esto nos lleva al tema de la gestión de esquemas. A medida que los objetivos comerciales y los requisitos cambian con el tiempo, también lo hace la estructura de sus datos. Delta Lake facilita la implementación de nuevas medidas a medida que cambian los datos. Los usuarios tienen acceso a una semántica simple para administrar sus esquemas de tablas. Estas herramientas incluyen Schema Enforcement, que protege a los usuarios de contaminar inadvertidamente sus tablas con errores o datos innecesarios, y Schema Evolution, que permite agregar automáticamente nuevas columnas de datos valiosos en los lugares apropiados. En este artículo profundizaremos en el uso de estas herramientas.

Comprender los esquemas de tablas

Cada DataFrame en Apache Spark contiene un esquema que define la forma de los datos, como tipos de datos, columnas y metadatos. Con Delta Lake, el esquema de la tabla se almacena en formato JSON dentro del registro de transacciones.

¿Qué es la aplicación de esquemas?

Schema Enforcement, también conocido como Schema Validation, es un mecanismo de protección en Delta Lake que garantiza la calidad de los datos al rechazar los registros que no coinciden con el esquema de la tabla. Como una anfitriona en la recepción de un restaurante popular que solo acepta reservas, verifica si cada columna de datos ingresada en la tabla está en la lista correspondiente de columnas esperadas (en otras palabras, si hay una "reserva" para cada uno de ellos), y rechaza cualquier entrada con columnas que no estén en la lista.

¿Cómo funciona la aplicación del esquema?

Delta Lake utiliza la validación del esquema en la escritura, lo que significa que todas las escrituras nuevas en la tabla se verifican para verificar su compatibilidad con el esquema de la tabla de destino en el momento de la escritura. Si el esquema es inconsistente, Delta Lake invierte completamente la transacción (no se escriben datos) y lanza una excepción para informar al usuario de la inconsistencia.
Delta Lake usa las siguientes reglas para determinar si un registro es compatible con una tabla. Marco de datos escrito:

  • no puede contener columnas adicionales que no estén en el esquema de la tabla de destino. Por el contrario, todo está bien si los datos entrantes no contienen absolutamente todas las columnas de la tabla; a estas columnas simplemente se les asignarán valores cero.
  • no puede tener tipos de datos de columna que sean diferentes de los tipos de datos de columna en la tabla de destino. Si una columna en la tabla de destino contiene datos StringType, pero la columna correspondiente en DataFrame contiene datos IntegerType, la aplicación del esquema generará una excepción y evitará que se lleve a cabo la operación de escritura.
  • no puede contener nombres de columna que difieran solo en mayúsculas y minúsculas. Esto significa que no puede tener columnas llamadas 'Foo' y 'foo' definidas en la misma tabla. Si bien Spark se puede usar en modo que distingue entre mayúsculas y minúsculas o no distingue entre mayúsculas y minúsculas (el modo predeterminado), Delta Lake conserva las mayúsculas y minúsculas pero no distingue entre mayúsculas y minúsculas dentro del almacenamiento de esquema. Parquet distingue entre mayúsculas y minúsculas al almacenar y devolver información de columna. Para evitar posibles errores, corrupción de datos o pérdida de datos (que experimentamos personalmente en Databricks), decidimos agregar esta limitación.

Para ilustrar esto, echemos un vistazo a lo que sucede en el siguiente código al intentar agregar algunas columnas recién generadas a una tabla de Delta Lake que aún no está configurada para aceptarlas.

# Сгенерируем DataFrame ссуд, который мы добавим в нашу таблицу Delta Lake
loans = sql("""
            SELECT addr_state, CAST(rand(10)*count as bigint) AS count,
            CAST(rand(10) * 10000 * count AS double) AS amount
            FROM loan_by_state_delta
            """)

# Вывести исходную схему DataFrame
original_loans.printSchema()

root
  |-- addr_state: string (nullable = true)
  |-- count: integer (nullable = true)
 
# Вывести новую схему DataFrame
loans.printSchema()
 
root
  |-- addr_state: string (nullable = true)
  |-- count: integer (nullable = true)
  |-- amount: double (nullable = true) # new column
 
# Попытка добавить новый DataFrame (с новым столбцом) в существующую таблицу
loans.write.format("delta") 
           .mode("append") 
           .save(DELTALAKE_PATH)

Returns:

A schema mismatch detected when writing to the Delta table.
 
To enable schema migration, please set:
'.option("mergeSchema", "true")'
 
Table schema:
root
-- addr_state: string (nullable = true)
-- count: long (nullable = true)
 
Data schema:
root
-- addr_state: string (nullable = true)
-- count: long (nullable = true)
-- amount: double (nullable = true)
 
If Table ACLs are enabled, these options will be ignored. Please use the ALTER TABLE command for changing the schema.

En lugar de agregar automáticamente nuevas columnas, Delta Lake aplica un esquema y detiene la grabación. Para ayudar a determinar qué columna (o conjunto de ellas) está causando la falta de coincidencia, Spark extrae ambos esquemas de la pila de seguimiento para compararlos.

¿Cuál es el beneficio de la aplicación del esquema?

Dado que la aplicación del esquema es una verificación bastante rigurosa, es una gran herramienta para usar como guardián de un conjunto de datos limpio y completamente transformado que está listo para ser producido o consumido. Normalmente se aplica a tablas que alimentan datos directamente:

  • Algoritmos de aprendizaje automático
  • Paneles de BI
  • Herramientas de visualización y análisis de datos
  • Cualquier sistema de producción que requiera esquemas semánticos altamente estructurados y fuertemente tipados.

Para preparar sus datos para este último obstáculo, muchos usuarios utilizan una arquitectura simple de "saltos múltiples" que gradualmente introduce estructura en sus tablas. Para saber más sobre esto, puedes leer el artículo Aprendizaje automático de grado de producción con Delta Lake.

Por supuesto, la aplicación del esquema se puede usar en cualquier lugar de la canalización, pero tenga en cuenta que la transmisión de escritura en una tabla puede ser frustrante en este caso porque, por ejemplo, olvidó que agregó otra columna a los datos entrantes.

Prevención del adelgazamiento de datos

En este punto, es posible que se pregunte por qué tanta publicidad. Después de todo, a veces un error inesperado de "falta de coincidencia de esquema" puede causarle problemas en su flujo de trabajo, especialmente si es nuevo en Delta Lake. ¿Por qué no dejar que el esquema cambie según sea necesario para que pueda escribir mi DataFrame sin importar qué?

Como dice el viejo refrán, "una onza de prevención vale una libra de cura". En algún momento, si no tiene cuidado de hacer cumplir su esquema, los problemas de compatibilidad de tipos de datos aparecerán: las fuentes de datos sin procesar aparentemente homogéneas pueden contener casos extremos, columnas rotas, asignaciones mal formadas u otras cosas temidas con las que sueña. .en pesadillas. El mejor enfoque es detener a estos enemigos en la puerta, con la aplicación del esquema, y ​​lidiar con ellos a la luz, no más tarde, cuando comiencen a merodear por las oscuras profundidades de su código de producción.

La aplicación del esquema le brinda la confianza de que el esquema de su tabla no cambiará a menos que confirme el cambio usted mismo. Esto evita la dilución de datos que puede ocurrir cuando se agregan nuevas columnas con tanta frecuencia que las tablas comprimidas que antes eran valiosas pierden su valor y utilidad debido a la inundación de datos. Al alentarlo a ser intencional, establecer estándares altos y esperar alta calidad, la aplicación del esquema hace exactamente lo que fue diseñada para hacer: ayudarlo a mantenerse consciente y mantener limpias sus hojas de cálculo.

Si, después de considerarlo más detenidamente, decide que realmente necesario agregue una nueva columna; no hay problema, a continuación se muestra una solución de una línea. ¡La solución es la evolución del circuito!

¿Qué es la evolución del esquema?

La evolución del esquema es una función que permite a los usuarios cambiar fácilmente el esquema actual de una tabla para que coincida con los datos que cambian con el tiempo. Se usa más comúnmente cuando se realiza una operación de agregar o sobrescribir para adaptar automáticamente el esquema para incluir una o más columnas nuevas.

¿Cómo funciona la evolución del esquema?

Siguiendo el ejemplo de la sección anterior, los desarrolladores pueden usar fácilmente la evolución del esquema para agregar nuevas columnas que se rechazaron previamente debido a la inconsistencia del esquema. La evolución del circuito se activa agregando .option('mergeSchema', 'true') a tu equipo Spark .write или .writeStream.

# Добавьте параметр mergeSchema
loans.write.format("delta") 
           .option("mergeSchema", "true") 
           .mode("append") 
           .save(DELTALAKE_SILVER_PATH)

Para ver el gráfico, ejecute la siguiente consulta Spark SQL

# Создайте график с новым столбцом, чтобы подтвердить, что запись прошла успешно
%sql
SELECT addr_state, sum(`amount`) AS amount
FROM loan_by_state_delta
GROUP BY addr_state
ORDER BY sum(`amount`)
DESC LIMIT 10

Sumérgete en Delta Lake: cumplimiento de esquemas y evolución
Alternativamente, puede configurar esta opción para toda la sesión de Spark agregando spark.databricks.delta.schema.autoMerge = True a la configuración de Spark. Pero use esto con precaución, ya que la aplicación del esquema ya no le advertirá sobre las inconsistencias del esquema no intencionales.

Al incluir un parámetro en la solicitud mergeSchema, todas las columnas que están presentes en el DataFrame pero que no están presentes en la tabla de destino se agregan automáticamente al final del esquema como parte de la transacción de escritura. También se pueden agregar campos anidados, y estos también se agregarán al final de las columnas de estructura correspondientes.

Los ingenieros de fechas y los científicos de datos pueden usar esta opción para agregar nuevas columnas (tal vez una métrica rastreada recientemente o la columna de cifras de ventas de este mes) a sus tablas de producción de aprendizaje automático existentes sin romper los modelos existentes basados ​​en las columnas antiguas.

Los siguientes tipos de cambios de esquema están permitidos como parte de la evolución de un esquema al agregar o sobrescribir una tabla:

  • Agregar nuevas columnas (este es el escenario más común)
  • Cambio de tipos de datos de NullType -> cualquier otro tipo o promoción de ByteType -> ShortType -> IntegerType

Otros cambios que no están permitidos como parte de la evolución del esquema requieren que el esquema y los datos se sobrescriban agregando .option("overwriteSchema", "true"). Por ejemplo, en el caso de que la columna "Foo" fuera originalmente un número entero y el nuevo esquema fuera un tipo de datos de cadena, todos los archivos de Parquet (datos) deberían sobrescribirse. Estos cambios incluyen:

  • borrando una columna
  • cambiar el tipo de datos de una columna existente (en su lugar)
  • cambiar el nombre de las columnas que difieren solo en mayúsculas y minúsculas (por ejemplo, "Foo" y "foo")

Finalmente, con la próxima versión de Spark 3.0, DDL explícito (usando ALTER TABLE) será totalmente compatible, lo que permitirá a los usuarios realizar las siguientes acciones en esquemas de tablas:

  • agregando columnas
  • cambiar comentarios de columna
  • establecer las propiedades de la tabla que determinan cómo se comporta la tabla, como establecer cuánto tiempo se conserva el registro de transacciones.

¿Cuál es el beneficio de la evolución del esquema?

La evolución esquemática se puede utilizar siempre que pretender cambie el esquema de su tabla (a diferencia de cuando accidentalmente agregó columnas a su DataFrame que no deberían estar allí). Esta es la forma más fácil de migrar su esquema porque agrega automáticamente los nombres de columna y los tipos de datos correctos sin tener que declararlos explícitamente.

Conclusión

La aplicación del esquema rechaza cualquier columna nueva u otros cambios de esquema que no sean compatibles con su tabla. Al establecer y mantener estos altos estándares, los analistas e ingenieros pueden confiar en que sus datos tendrán el más alto nivel de integridad, razonando sobre ellos de manera clara y concisa, lo que les permitirá tomar mejores decisiones comerciales.

Por otro lado, la evolución del esquema complementa la aplicación al simplificar supuesta Cambios automáticos de esquema. Después de todo, no debería ser difícil agregar una columna.

La aplicación del esquema es yang, donde las evoluciones del esquema son yin. Cuando se usan juntas, estas funciones hacen que la reducción de ruido y el ajuste de la señal sean más fáciles que nunca.

También nos gustaría agradecer a Mukul Murthy y Pranav Anand por sus contribuciones a este artículo.

Otros artículos de esta serie:

Sumérgete en Delta Lake: desempaquetando el registro de transacciones

Artículos relacionados

Aprendizaje automático de grado de producción con Delta Lake

¿Qué es un lago de datos?

Más información sobre el curso

Fuente: habr.com

Añadir un comentario