Administración de particiones para la salida de ETL en AWS Glue - AWS Glue

Administración de particiones para la salida de ETL en AWS Glue

La creación de particiones es una importante técnica para organizar conjuntos de datos de manera que se puedan consultar de forma eficaz. Organiza los datos en una estructura de directorios jerárquica en función de los valores diferenciados de una o más columnas.

Por ejemplo, puede decidir particionar los registros de aplicación en Amazon Simple Storage Service (Amazon S3) por fecha, con desglose por año, mes y día. Los archivos que corresponden a los datos de un solo día se colocan con un prefijo como s3://my_bucket/logs/year=2018/month=01/day=23/. Los sistemas como Amazon Athena, Amazon Redshift Spectrum, y ahora AWS Glue, pueden utilizar estas particiones para filtrar datos por valor de partición sin tener que leer todos los datos subyacentes desde Amazon S3.

Los rastreadores no solo infieren los tipos de archivo y esquemas, sino que también identifican automáticamente la estructura de particiones del conjunto de datos cuando rellenan AWS Glue Data Catalog. Las columnas de partición resultantes están disponibles para consultarlas en trabajos de ETL de AWS Glue o motores de consulta como Amazon Athena.

Después de rastrear una tabla, puede ver las particiones que creó el rastreador. En la consola de AWS Glue, seleccione Tables (Tablas) en el panel de navegación de la izquierda. Elija la tabla creada por el rastreador y, a continuación, elija View Partitions (Ver Particiones).

En el caso de las rutas con particiones de tipo Apache Hive en el estilo key=val, los rastreadores rellenan automáticamente el nombre de columna con el nombre de clave. De lo contrario, utiliza nombres predeterminados como partition_0, partition_1 y así sucesivamente. Para cambiar los nombres predeterminados en la consola, vaya a la tabla, elija Edit Schema (Editar esquema) y modifique los nombres de las columnas de partición.

En los scripts de ETL, puede filtrar por las columnas de partición. Dado que la información de partición se almacena en el Data Catalog, utilice llamadas a la API from_catalog para incluir las columnas de partición en el DynamicFrame. Por ejemplo, utilice create_dynamic_frame.from_catalog en lugar de create_dynamic_frame.from_options.

Filtrado previo con predicados de inserción

En muchos casos, puede utilizar un predicado de inserción para filtrar por particiones sin tener que enumerar y leer todos los archivos del conjunto de datos. En lugar de leer todo el conjunto de datos y, a continuación, realizar el filtrado en un objeto DynamicFrame, puede aplicar el filtro directamente en los metadatos de partición en el Data Catalog. A continuación, enumere y lea solo lo que necesita realmente en un objeto DynamicFrame.

Por ejemplo, en Python podría escribir lo siguiente.

glue_context.create_dynamic_frame.from_catalog( database = "my_S3_data_set", table_name = "catalog_data_table", push_down_predicate = my_partition_predicate)

De este modo se crea un objeto DynamicFrame que solo carga las particiones en el Data Catalog que cumplan la expresión de predicado. En función de lo pequeño que sea un subconjunto de los datos que esté cargando, se puede ahorrar mucho tiempo de procesamiento.

La expresión de predicado puede ser cualquier expresión booleana que admita Spark SQL. Funciona todo lo que podría incluir en una cláusula WHERE de una consulta SQL Spark. Por ejemplo, la expresión de predicado pushDownPredicate = "(year=='2017' and month=='04')" solo carga las particiones en el Data Catalog que tienen tanto year igual que 2017 como month igual que 04. Para obtener más información, consulte la documentación de Apache Spark SQL y, en concreto, la referencia de funciones SQL de Scala.

Además de las particiones estilo Hive de las rutas de Amazon S3, los formatos de Apache Parquet y Apache ORC particionan cada archivo en bloques de datos que representan valores de columna. Cada bloque también almacena estadísticas de los registros que contiene, como mín./máx. para valores de columna. AWS Glue admite predicados de inserción para las particiones de estilo Hive y particiones de bloque en estos formatos. De esta forma, puede reducir las particiones de Amazon S3 innecesarias en los formatos Parquet y ORC, así como omitir bloques que considere innecesarios mediante estadísticas de columna.

Filtrado del lado del servidor mediante predicados de partición de catálogo

La opción push_down_predicate se aplica después de crear el listado de todas las particiones del catálogo y antes de crear el listado de los archivos de Amazon S3 para esas particiones. Si tiene muchas particiones para una tabla, el listado de particiones del catálogo puede seguir incurriendo en sobrecarga de tiempo adicional. Para abordar esta sobrecarga, puede usar la poda de particiones del lado del servidor con la opción catalogPartitionPredicate que utiliza índices de partición en AWS Glue Data Catalog. Esto hace que el filtrado de particiones sea mucho más rápido cuando tiene millones de particiones en una tabla. Puede usar ambos push_down_predicate y catalogPartitionPredicate en additional_options en forma conjunta, si su catalogPartitionPredicate requiere sintaxis de predicado que aún no se soporta con los índices de partición del catálogo.

Python:

dynamic_frame = glueContext.create_dynamic_frame.from_catalog( database=dbname, table_name=tablename, transformation_ctx="datasource0", push_down_predicate="day>=10 and customer_id like '10%'", additional_options={"catalogPartitionPredicate":"year='2021' and month='06'"} )

Scala:

val dynamicFrame = glueContext.getCatalogSource( database = dbname, tableName = tablename, transformationContext = "datasource0", pushDownPredicate="day>=10 and customer_id like '10%'", additionalOptions = JsonOptions("""{ "catalogPartitionPredicate": "year='2021' and month='06'"}""") ).getDynamicFrame()
nota

push_down_predicate y catalogPartitionPredicate utilizan sintaxis diferentes. El primero utiliza la sintaxis estándar de Spark SQL y el segundo utiliza el analizador JSQL.

Escritura de particiones

De forma predeterminada, un objeto DynamicFrame no se particiona cuando se escribe. Todos los archivos de salida se escriben en el nivel superior de la ruta de salida especificada. Hasta hace poco tiempo, la única forma de escribir un objeto DynamicFrame en particiones era convertirlo en un objeto DataFrame de Spark SQL antes de la escritura.

Sin embargo, los objetos DynamicFrame ahora admiten la partición nativa mediante una secuencia de claves, utilizando la opción partitionKeys al crear un receptor. Por ejemplo, el siguiente código Python escribe un conjunto de datos en Amazon S3 en formato Parquet, en directorios particionados por el tipo de campo. Desde ahí puede procesar estas particiones con otros sistemas, como Amazon Athena.

glue_context.write_dynamic_frame.from_options( frame = projectedEvents, connection_type = "s3", connection_options = {"path": "$outpath", "partitionKeys": ["type"]}, format = "parquet")