Temas clave de Apache Spark -

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

Temas clave de Apache Spark

En esta sección se explican los conceptos básicos de Apache Spark y los temas clave AWS Glue para ajustar el rendimiento de Apache Spark. Es importante entender estos conceptos y temas antes de analizar las estrategias de ajuste del mundo real.

Arquitectura

El controlador de Spark es el principal responsable de dividir tu aplicación Spark en tareas que puedan realizar trabajadores individuales. El conductor de Spark tiene las siguientes responsabilidades:

  • Se ejecuta main() en tu código

  • Generando planes de ejecución

  • Aprovisionamiento de los ejecutores de Spark junto con el administrador de clústeres, que gestiona los recursos del clúster

  • Programar tareas y solicitar tareas para los ejecutores de Spark

  • Gestionar el progreso y la recuperación de las tareas

Utilizas un SparkContext objeto para interactuar con el controlador de Spark durante tu trabajo.

Un ejecutor de Spark es un elemento que se encarga de almacenar datos y ejecutar tareas que se transfieren desde el controlador de Spark. El número de ejecutores de Spark aumentará y disminuirá con el tamaño del clúster.

Conexiones del controlador Spark, el administrador de clústeres y los nodos de trabajo con los ejecutores de JVM en los nodos de trabajo.
nota

Un ejecutor de Spark tiene múltiples ranuras para procesar múltiples tareas en paralelo. De forma predeterminada, Spark admite una tarea para cada núcleo de CPU virtual (vCPU). Por ejemplo, si un ejecutor tiene cuatro núcleos de CPU, puede ejecutar cuatro tareas simultáneas.

Conjunto de datos distribuido resiliente

Spark realiza la compleja tarea de almacenar y rastrear grandes conjuntos de datos en los ejecutores de Spark. Cuando escribes código para los trabajos de Spark, no necesitas pensar en los detalles del almacenamiento. Spark proporciona la abstracción de conjuntos de datos distribuidos resilientes (RDD), que es una colección de elementos que se pueden operar en paralelo y que se pueden dividir en los ejecutores de Spark del clúster.

La siguiente figura muestra la diferencia en la forma de almacenar datos en la memoria cuando se ejecuta un script de Python en su entorno típico y cuando se ejecuta en el marco Spark (PySpark).

Python val [1,2,3 N], Apache Spark rdd = sc.parallelize [1,2,3 N].
  • Python: la escritura val = [1,2,3...N] en un script de Python mantiene los datos en la memoria de la única máquina en la que se ejecuta el código.

  • PySpark— Spark proporciona la estructura de datos RDD para cargar y procesar los datos distribuidos en la memoria de varios ejecutores de Spark. Puedes generar un RDD con código comordd = sc.parallelize[1,2,3...N], por ejemplo, y Spark puede distribuir y almacenar automáticamente los datos en la memoria entre varios ejecutores de Spark.

    En muchos AWS Glue trabajos, utilizas los RDD a través AWS Glue DynamicFramesde Spark. DataFrames Se trata de abstracciones que permiten definir el esquema de datos de un RDD y realizar tareas de nivel superior con esa información adicional. Como utilizan los RDD internamente, los datos se distribuyen y cargan de forma transparente en varios nodos en el siguiente código:

    • DynamicFrame

      dyf= glueContext.create_dynamic_frame.from_options( 's3', {"paths": [ "s3://<YourBucket>/<Prefix>/"]}, format="parquet", transformation_ctx="dyf" )
    • DataFrame

      df = spark.read.format("parquet") .load("s3://<YourBucket>/<Prefix>")

Un RDD tiene las siguientes características:

  • Los RDD consisten en datos divididos en varias partes denominadas particiones. Cada ejecutor de Spark almacena una o más particiones en la memoria y los datos se distribuyen entre varios ejecutores.

  • Los RDD son inmutables, lo que significa que no se pueden cambiar una vez creados. Para cambiar a DataFrame, puede utilizar las transformaciones, que se definen en la siguiente sección.

  • Los RDD replican los datos en los nodos disponibles para que puedan recuperarse automáticamente de los fallos de los nodos.

Evaluación perezosa

Los RDD admiten dos tipos de operaciones: las transformaciones, que crean un nuevo conjunto de datos a partir de uno existente, y las acciones, que devuelven un valor al programa controlador tras ejecutar un cálculo en el conjunto de datos.

  • Transformaciones: dado que los RDD son inmutables, solo puede cambiarlos mediante una transformación.

    Por ejemplo, map es una transformación que pasa cada elemento del conjunto de datos a través de una función y devuelve un nuevo RDD que representa los resultados. Observe que el map método no devuelve una salida. Spark almacena la transformación abstracta para el futuro, en lugar de permitirte interactuar con el resultado. Spark no actuará en función de las transformaciones hasta que solicites una acción.

  • Acciones: al usar las transformaciones, construyes tu plan de transformación lógica. Para iniciar el cálculo, ejecute una acción comowrite, countshow, ocollect.

    Todas las transformaciones en Spark son perezosas, ya que no calculan sus resultados de forma inmediata. En su lugar, Spark recuerda una serie de transformaciones aplicadas a algún conjunto de datos base, como los objetos del Amazon Simple Storage Service (Amazon S3). Las transformaciones se calculan solo cuando una acción requiere que se devuelva un resultado al controlador. Este diseño permite a Spark funcionar de forma más eficiente. Por ejemplo, consideremos la situación en la que un conjunto de datos creado mediante la map transformación solo lo consume una transformación que reduce sustancialmente el número de filas, por ejemploreduce. A continuación, puede pasar el conjunto de datos más pequeño que ha sufrido ambas transformaciones al controlador, en lugar de pasar el conjunto de datos mapeado más grande.

Terminología de las aplicaciones de Spark

Esta sección trata sobre la terminología de las aplicaciones de Spark. El controlador Spark crea un plan de ejecución y controla el comportamiento de las aplicaciones en varias abstracciones. Los siguientes términos son importantes para el desarrollo, la depuración y el ajuste del rendimiento con la interfaz de usuario de Spark.

  • Aplicación: basada en una sesión de Spark (contexto de Spark). Se identifica mediante un identificador único, como<application_XXX>.

  • Trabajos: se basan en las acciones creadas para un RDD. Un trabajo consta de una o más etapas.

  • Etapas: se basan en las combinaciones creadas para un RDD. Una etapa consta de una o más tareas. La mezcla es el mecanismo de Spark para redistribuir los datos de forma que se agrupen de forma diferente en las particiones del RDD. Algunas transformaciones, por ejemplojoin(), requieren una mezcla. La mezcla aleatoria se analiza con más detalle en la práctica de ajuste de Optimize shuffles.

  • Tareas: una tarea es la unidad mínima de procesamiento programada por Spark. Las tareas se crean para cada partición RDD y el número de tareas es el número máximo de ejecuciones simultáneas en la etapa.

Plan de ejecución con tareas, etapas, mezcla y tareas.
nota

Las tareas son lo más importante a tener en cuenta a la hora de optimizar el paralelismo. El número de tareas aumenta con el número de RDD

Paralelismo

Spark paraleliza las tareas de carga y transformación de datos.

Considere un ejemplo en el que realiza un procesamiento distribuido de los archivos de registro de acceso (denominadosaccesslog1 ... accesslogN) en Amazon S3. El siguiente diagrama muestra el flujo de procesamiento distribuido.

""
  1. El controlador Spark crea un plan de ejecución para el procesamiento distribuido entre muchos ejecutores de Spark.

  2. El controlador Spark asigna tareas a cada ejecutor en función del plan de ejecución. De forma predeterminada, el controlador Spark crea particiones RDD (cada una de las cuales corresponde a una tarea de Spark) para cada objeto de S3 (). Part1 ... N A continuación, el controlador Spark asigna tareas a cada ejecutor.

  3. Cada tarea de Spark descarga su objeto S3 asignado y lo almacena en la memoria de la partición RDD. De esta forma, varios ejecutores de Spark descargan y procesan la tarea asignada en paralelo.

Para obtener más información sobre el número inicial de particiones y la optimización, consulta la sección Paralelizar tareas.

Optimizador Catalyst

Internamente, Spark usa un motor llamado Catalyst optimizer para optimizar los planes de ejecución. Catalyst cuenta con un optimizador de consultas que puede utilizar al ejecutar API de Spark de alto nivel, como Spark SQL, y conjuntos de datosDataFrame, tal y como se describe en el siguiente diagrama.

El plan lógico utiliza el optimizador Catalyst, que genera un plan optimizado que se envía a los RDD.

Como el optimizador de Catalyst no funciona directamente con la API RDD, las API de alto nivel suelen ser más rápidas que las API RDD de bajo nivel. En el caso de uniones complejas, el optimizador Catalyst puede mejorar considerablemente el rendimiento al optimizar el plan de ejecución del trabajo. Puedes ver el plan optimizado de tu trabajo de Spark en la pestaña SQL de la interfaz de usuario de Spark.

Ejecución de consultas adaptativa

El optimizador Catalyst optimiza el tiempo de ejecución mediante un proceso denominado Adaptive Query Execution. Adaptive Query Execution utiliza estadísticas de tiempo de ejecución para volver a optimizar el plan de ejecución de las consultas mientras el trabajo está en ejecución. Adaptive Query Execution ofrece varias soluciones a los desafíos de rendimiento, como la fusión de particiones posteriores a la reorganización, la conversión de uniones por orden y fusión en uniones por transmisión y la optimización de las uniones sesgadas, tal y como se describe en las siguientes secciones.

La ejecución adaptativa de consultas está disponible en la AWS Glue versión 3.0 y versiones posteriores, y está habilitada de forma predeterminada en AWS Glue la versión 4.0 (Spark 3.3.0) y versiones posteriores. La ejecución adaptativa de consultas se puede activar y desactivar utilizando spark.conf.set("spark.sql.adaptive.enabled", "true") tu código.

Combinación de particiones posteriores a la reproducción aleatoria

Esta función reduce las particiones RDD (se fusionan) después de cada mezcla en función de las estadísticas de salida. map Simplifica el ajuste del número de particiones de reproducción aleatoria al ejecutar consultas. No necesita establecer un número de partición aleatoria que se ajuste a su conjunto de datos. Spark puede elegir el número de partición aleatoria adecuado en tiempo de ejecución una vez que el número inicial de particiones aleatorio sea lo suficientemente grande.

La fusión de particiones posteriores a la reproducción aleatoria está habilitada cuando ambas están configuradas como verdaderas. spark.sql.adaptive.enabled spark.sql.adaptive.coalescePartitions.enabled Para obtener más información, consulte la documentación de Apache Spark.

Convertir sort-merge join en broadcast join

Esta función reconoce cuando se unen dos conjuntos de datos de un tamaño sustancialmente diferente y adopta un algoritmo de unión más eficiente basado en esa información. Para obtener más información, consulte la documentación de Apache Spark. Las estrategias de unión se describen en la sección Optimizar las combinaciones.

Optimización de uniones sesgadas

La asimetría de los datos es uno de los obstáculos más comunes en los trabajos de Spark. Describe una situación en la que los datos se desvían hacia particiones RDD específicas (y, en consecuencia, hacia tareas específicas), lo que retrasa el tiempo total de procesamiento de la aplicación. A menudo, esto puede reducir el rendimiento de las operaciones de unión. La función de optimización de uniones asimétricas gestiona de forma dinámica la asimetría en las uniones de clasificación y fusión dividiendo (y replicando si es necesario) las tareas asimétricas en tareas de tamaño aproximadamente uniforme.

Esta función está habilitada cuando se establece en true. spark.sql.adaptive.skewJoin.enabled Para obtener más información, consulte la documentación de Apache Spark. El sesgo de los datos se analiza con más detalle en la sección Optimizar las mezclas.