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. Puede cambiar los nombres predeterminados de la consola. Para ello, navegue hasta la tabla. Compruebe si existen índices en la pestaña Indexes (Índices). Si ese es el caso, debe eliminarlos para continuar (puede volver a crearlos con los nuevos nombres de columna más adelante). A continuación, seleccione Editar esquema y modifique allí 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
.
El particionamiento es una técnica de optimización que reduce el escaneo de datos. Para obtener más información sobre el proceso de identificación de cuándo esta técnica es adecuada, consulte Reducir la cantidad de datos escaneados en la guía de Prácticas recomendadas para el ajuste del rendimiento de AWS Glue para trabajos de Apache Spark en las Recomendaciones de AWS.
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
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")