apache spark - Evolución del esquema en formato parquet.
apache-spark hadoop (2)
Actualmente estamos utilizando el formato de datos Avro en producción. De varios puntos buenos que utilizan Avro, sabemos que es bueno en la evolución del esquema.
Ahora estamos evaluando el formato de parquet debido a su eficiencia al leer columnas aleatorias. Así que antes de seguir avanzando nuestra preocupación sigue siendo la evolución del esquema .
¿Alguien sabe si la evolución del esquema es posible en el parquet, si es así?
Algunos resources afirman que es posible, pero solo puede agregar columnas al final .
¿Qué significa esto?
Además de la respuesta anterior, otra opción es configurar
"spark.hadoop.parquet.enable.summary-metadata" to "true"
Lo que esto hace es crear archivos de resumen con el esquema cuando escribe archivos. Cuando guarde, verá los archivos de resumen ''_metadata''
y ''_common_metadata''
. _common_metadata
es el esquema comprimido que se lee cada vez que se lee el archivo de parquet. Esto hace que la lectura sea muy rápida ya que ya tiene el esquema. Spark busca estos archivos de esquema, si están presentes, para obtener el esquema.
Tenga en cuenta que esto hace que las escrituras sean muy lentas, ya que Spark tiene que combinar el esquema de todos los archivos y crear estos archivos de esquema.
Tuvimos una situación similar en la que el esquema de parquet cambió. Lo que hicimos fue establecer la configuración anterior en true
durante algún tiempo después del cambio de esquema para que se generen los archivos de esquema y luego volver a establecerlo en false
. Tuvimos que comprometernos con escrituras lentas por un tiempo, pero después de que se generaron los archivos de esquema, configurarlo en false
sirvió para ese propósito. Y con un extra de leer los archivos más rápido.
La evolución del esquema puede ser (muy) costosa.
Para descubrir el esquema, básicamente tiene que leer todos sus archivos de parquet y reconciliar / combinar sus esquemas durante el tiempo de lectura, lo que puede ser costoso dependiendo de cuántos archivos y / o cuántas columnas haya en el conjunto de datos.
Por lo tanto, desde Spark 1.5 , desactivaron la combinación de esquemas por defecto. Siempre puedes volver a encenderlo).
Dado que la combinación de esquemas es una operación relativamente costosa, y no es una necesidad en la mayoría de los casos, lo desactivamos por defecto a partir de 1.5.0.
Sin la evolución del esquema, puede leer el esquema de un archivo de parquet, y mientras lee el resto de archivos, suponga que se mantiene igual.
La evolución del esquema de parquet depende de la implementación.
Hive, por ejemplo, tiene una perilla parquet.column.index.access=false
que podría establecer para mapear el esquema por nombres de columna en lugar de por índice de columna.
Entonces podrías eliminar columnas también, no solo agregar.
Como dije anteriormente, depende de la implementación, por ejemplo, Impala no leería tales tablas de parquet correctamente (corregido en la reciente versión Impala 2.6) [ Reference ].
Apache Spark, a partir de la versión 2.0.2, parece que todavía solo admite la adición de columnas : [ Referencia ]
Los usuarios pueden comenzar con un esquema simple y gradualmente agregar más columnas al esquema según sea necesario. De esta manera, los usuarios pueden terminar con varios archivos de Parquet con esquemas diferentes pero compatibles entre sí. La fuente de datos de Parquet ahora puede detectar automáticamente este caso y combinar esquemas de todos estos archivos.
PD: Lo que he visto hacer a algunas personas para tener más agilidad en los cambios de esquema, es que crean una vista sobre tablas de parquet reales que asignan dos (o más) esquemas diferentes pero compatibles a un esquema común.
Digamos que ha agregado un nuevo campo ( registration_date
) y ha eliminado otra columna ( last_login_date
) en su nueva versión, entonces esto se vería así:
CREATE VIEW datamart.unified_fact_vw
AS
SELECT f1..., NULL as registration_date
FROM datamart.unified_fact_schema1 f1
UNION ALL
SELECT f2..., NULL as last_login_date
FROM datamart.unified_fact_schema2 f2
;
Tienes la idea Lo bueno sería que funcionaría igual en todos los sql en los dialectos de Hadoop (como mencioné anteriormente en Hive, Impala y Spark), y aún tiene todos los beneficios de las tablas de parquet (almacenamiento en columnas, predicado push-down, etc.).