Ajustar rendimiento: Spark, HDInsight y Azure Data Lake Storage Gen2Tune performance: Spark, HDInsight & Azure Data Lake Storage Gen2

Cuando ajuste el rendimiento de Spark, necesitará tener en cuenta el número de aplicaciones que se ejecutarán en su clúster.When tuning performance on Spark, you need to consider the number of apps that will be running on your cluster. De forma predeterminada, puede ejecutar 4 aplicaciones simultáneamente en su clúster HDI. (Nota: la configuración predeterminada está sujeta a cambios).By default, you can run 4 apps concurrently on your HDI cluster (Note: the default setting is subject to change). Puede decidir usar menos aplicaciones, por lo que puede sustituir la configuración predeterminada y utilizar más del clúster para esas aplicaciones.You may decide to use fewer apps so you can override the default settings and use more of the cluster for those apps.

Requisitos previosPrerequisites

ParámetrosParameters

Estos son los valores más importantes que se pueden optimizar para aumentar el rendimiento en Data Lake Storage Gen2 cuando ejecute trabajos de Spark:When running Spark jobs, here are the most important settings that can be tuned to increase performance on Data Lake Storage Gen2:

  • num-executors: número de tareas simultáneas que se pueden ejecutar.Num-executors - The number of concurrent tasks that can be executed.

  • executor-memory: cantidad de memoria asignada a cada ejecutor.Executor-memory - The amount of memory allocated to each executor.

  • executor-cores: número de núcleos asignados a cada ejecutor.Executor-cores - The number of cores allocated to each executor.

num-executors. En num-executors se define el número máximo de tareas que se pueden ejecutar en paralelo.Num-executors Num-executors will set the maximum number of tasks that can run in parallel. El número real de tareas que se pueden ejecutar en paralelo está limitado por los recursos de CPU y memoria disponibles en el clúster.The actual number of tasks that can run in parallel is bounded by the memory and CPU resources available in your cluster.

executor-memory. Es la cantidad de memoria que se asigna a cada ejecutor.Executor-memory This is the amount of memory that is being allocated to each executor. La memoria necesaria para cada ejecutor depende del trabajo.The memory needed for each executor is dependent on the job. En las operaciones complejas, la memoria debe ser mayor.For complex operations, the memory needs to be higher. En cambio, para las simples como la lectura y escritura, los requisitos de memoria serán menores.For simple operations like read and write, memory requirements will be lower. La cantidad de memoria para cada ejecutor puede verse en Ambari.The amount of memory for each executor can be viewed in Ambari. En Ambari, vaya a Spark y vea la pestaña Configs (Configuraciones).In Ambari, navigate to Spark and view the Configs tab.

Executor-cores Establece el número de núcleos que se usan por ejecutor, lo que determina el número de subprocesos paralelos que se pueden ejecutar por ejecutor.Executor-cores This sets the number of cores used per executor, which determines the number of parallel threads that can be run per executor. Por ejemplo, si executor-cores = 2, entonces cada ejecutor puede ejecutar 2 tareas en paralelo.For example, if executor-cores = 2, then each executor can run 2 parallel tasks in the executor. Los núcleos de ejecutor necesarios dependerán del trabajo.The executor-cores needed will be dependent on the job. Los trabajos con muchas E/S no requieren una gran cantidad de memoria por tarea, por lo que cada ejecutor puede administrar más tareas paralelas.I/O heavy jobs do not require a large amount of memory per task so each executor can handle more parallel tasks.

De forma predeterminada, se definen dos núcleos YARN virtuales para cada núcleo físico cuando se ejecuta Spark en HDInsight.By default, two virtual YARN cores are defined for each physical core when running Spark on HDInsight. Este número proporciona un buen equilibrio entre simultaneidad y la cantidad de cambios de contexto desde varios subprocesos.This number provides a good balance of concurrency and amount of context switching from multiple threads.

GuíaGuidance

Si va a ejecute cargas de trabajo de análisis de Spark para trabajar con datos de Data Lake Storage Gen2, se recomienda usar la versión más reciente de HDInsight para conseguir el máximo rendimiento con Data Lake Storage Gen2.While running Spark analytic workloads to work with data in Data Lake Storage Gen2, we recommend that you use the most recent HDInsight version to get the best performance with Data Lake Storage Gen2. Si el trabajo tiene un uso intensivo de E/S, hay determinados parámetros que puede configurar para mejorar el rendimiento.When your job is more I/O intensive, then certain parameters can be configured to improve performance. Data Lake Storage Gen2 es una plataforma de almacenamiento altamente escalable que puede controlar un alto rendimiento.Data Lake Storage Gen2 is a highly scalable storage platform that can handle high throughput. Si el trabajo está compuesto principalmente por lecturas o escrituras, aumentar la simultaneidad de E/S hacia y desde Data Lake Storage Gen2 podría aumentar el rendimiento.If the job mainly consists of read or writes, then increasing concurrency for I/O to and from Data Lake Storage Gen2 could increase performance.

Para aumentar la simultaneidad de trabajos de uso intensivo de E/S, existen algunos métodos generales:There are a few general ways to increase concurrency for I/O intensive jobs.

Paso 1: Determine cuántas aplicaciones se ejecutan en el clúster. Debe conocer cuántas aplicaciones se están ejecutando en el clúster, incluida la actual.Step 1: Determine how many apps are running on your cluster – You should know how many apps are running on the cluster including the current one. Los valores predeterminados para cada ajuste de Spark asume que hay 4 aplicaciones ejecutándose simultáneamente.The default values for each Spark setting assumes that there are 4 apps running concurrently. Por lo tanto, solo habrá un 25 % del clúster disponible para cada aplicación.Therefore, you will only have 25% of the cluster available for each app. Para obtener un mejor rendimiento, puede sustituir los valores predeterminados cambiando el número de ejecutores.To get better performance, you can override the defaults by changing the number of executors.

Paso 2: Establezca executor-memory. Lo primero que se debe establecer es executor-memory.Step 2: Set executor-memory – The first thing to set is the executor-memory. La memoria dependerá el trabajo que va a ejecutar.The memory will be dependent on the job that you are going to run. Puede aumentar la simultaneidad asignando menos memoria a cada ejecutor.You can increase concurrency by allocating less memory per executor. Si ve excepciones por memoria insuficiente cuando ejecuta el trabajo, aumente el valor para este parámetro.If you see out of memory exceptions when you run your job, then you should increase the value for this parameter. Otra alternativa consiste en obtener más memoria mediante un clúster que tenga mayor cantidad de la misma o aumentar el número de nodos en el clúster.One alternative is to get more memory by using a cluster that has higher amounts of memory or increasing the size of your cluster. Mientras más memoria tenga, más ejecutores podrá utilizar, lo que se traduce en una mayor simultaneidad.More memory will enable more executors to be used, which means more concurrency.

Paso 3: Establezca executor-cores. En cargas de trabajo con uso intensivo de E/S que no tengan operaciones complejas, es recomendable empezar con un gran número de núcleos de ejecutor para aumentar el número de tareas paralelas por cada ejecutor.Step 3: Set executor-cores – For I/O intensive workloads that do not have complex operations, it’s good to start with a high number of executor-cores to increase the number of parallel tasks per executor. Un buen punto de partida sería establecer executor-cores en 4.Setting executor-cores to 4 is a good start.

--executor-cores = 4executor-cores = 4

Si aumenta el número de núcleos de ejecutor podrá tener mayor paralelismo, con lo que puede experimentar con diferentes valores para executor-cores.Increasing the number of executor-cores will give you more parallelism so you can experiment with different executor-cores. Para los trabajos que tengan operaciones más complejas, reduzca el número de núcleos por ejecutor.For jobs that have more complex operations, you should reduce the number of cores per executor. Si executor-cores se ha establecido en un número mayor que 4, puede que la recolección de elementos no utilizados sea ineficaz y el rendimiento se vea degradado.If executor-cores is set higher than 4, then garbage collection may become inefficient and degrade performance.

Paso 4: Determine la cantidad de memoria YARN en el clúster. Esta información está disponible en Ambari.Step 4: Determine amount of YARN memory in cluster – This information is available in Ambari. Vaya a YARN y vea la pestaña Configs (Configuraciones). En esta ventana se muestra el tamaño de la memoria de YARN.Navigate to YARN and view the Configs tab. The YARN memory is displayed in this window.
Tenga en cuenta que mientras está en la ventana puede ver también el tamaño predeterminado del contenedor YARN.Note while you are in the window, you can also see the default YARN container size. El tamaño del contenedor YARN es igual que la memoria por cada parámetro de ejecutor.The YARN container size is the same as memory per executor parameter.

Memoria total de YARN = nodos * memoria de YARN por nodoTotal YARN memory = nodes * YARN memory per node

Paso 5: Calcule num-executorsStep 5: Calculate num-executors

Calcule la restricción de memoria: el parámetro num-executors está restringido por la memoria o por la CPU.Calculate memory constraint - The num-executors parameter is constrained either by memory or by CPU. La restricción de memoria se determina por la cantidad de memoria YARN disponible para la aplicación.The memory constraint is determined by the amount of available YARN memory for your application. Tome la memoria total de YARN y divídala por la memoria del ejecutor.You should take total YARN memory and divide that by executor-memory. La restricción debe adaptarse al número de aplicaciones, por lo que dividiremos entre dicho número.The constraint needs to be de-scaled for the number of apps so we divide by the number of apps.

Restricción de memoria = (memoria de YARN total / memoria del ejecutor) / número de aplicacionesMemory constraint = (total YARN memory / executor memory) / # of apps

Calcule la restricción de CPU: la restricción de la CPU se calcula como el total de núcleos virtuales divididos por el número de núcleos por ejecutor.Calculate CPU constraint - The CPU constraint is calculated as the total virtual cores divided by the number of cores per executor. Hay 2 núcleos virtuales para cada núcleo físico.There are 2 virtual cores for each physical core. Al igual que en la restricción de memoria, se divide por el número de aplicaciones.Similar to the memory constraint, we have to divide by the number of apps.

  • núcleos virtuales = (nodos del clúster * n.º de núcleos físicos en el nodo * 2)virtual cores = (nodes in cluster * # of physical cores in node * 2)
  • Restricción de CPU = (número total de núcleos virtuales / número de núcleos por ejecutor) / número de aplicacionesCPU constraint = (total virtual cores / # of cores per executor) / # of apps

Establezca num-executors: el parámetro num-executors se determina con la restricción de memoria y la restricción de CPU mínimas.Set num-executors – The num-executors parameter is determined by taking the minimum of the memory constraint and the CPU constraint.

num-executors = Min (número total de núcleos virtuales / número de núcleos por ejecutor, memoria de YARN disponible / executor-memory)num-executors = Min (total virtual Cores / # of cores per executor, available YARN memory / executor-memory)

El hecho de establecer un número mayor de ejecutores no tiene por qué aumentar el rendimiento.Setting a higher number of num-executors does not necessarily increase performance. Debe tener en cuenta que al agregar más ejecutores pondrá una sobrecarga adicional a cada ejecutor que agregue, lo que podría reducir el rendimiento.You should consider that adding more executors will add extra overhead for each additional executor, which can potentially degrade performance. El valor de num-executors está limitado por los recursos del clúster.Num-executors is bounded by the cluster resources.

Cálculo de ejemploExample calculation

Supongamos que tiene actualmente un clúster compuesto de 8 nodos D4v2 que están ejecutando 2 aplicaciones, incluida la que se va a ejecutar.Let’s say you currently have a cluster composed of 8 D4v2 nodes that is running 2 apps including the one you are going to run.

Paso 1: Determine cuántas aplicaciones se ejecutan en el clúster. Sabe que tiene 2 aplicaciones en el clúster, incluida la que se va a ejecutar.Step 1: Determine how many apps are running on your cluster – you know that you have 2 apps on your cluster, including the one you are going to run.

Paso 2: Establezca executor-memory. En este ejemplo, determinamos que 6 GB de memoria de ejecutor serán suficientes para trabajos con uso intensivo de E/S.Step 2: Set executor-memory – for this example, we determine that 6GB of executor-memory will be sufficient for I/O intensive job.

executor-memory = 6 GBexecutor-memory = 6GB

Paso 3: Establezca executor-cores. Puesto que se trata de un trabajo con uso intensivo de E/S, podemos establecer el número de núcleos para cada ejecutor a 4.Step 3: Set executor-cores – Since this is an I/O intensive job, we can set the number of cores for each executor to 4. Si establece los núcleos por ejecutor en un número mayor que 4 puede causar problemas de colección de elementos no utilizados.Setting cores per executor to larger than 4 may cause garbage collection problems.

--executor-cores = 4executor-cores = 4

Paso 4: Determine la cantidad de memoria YARN en clúster. Navegamos a Ambari para averiguar que cada D4v2 tiene 25 GB de memoria YARN.Step 4: Determine amount of YARN memory in cluster – We navigate to Ambari to find out that each D4v2 has 25GB of YARN memory. Dado que hay 8 nodos, la memoria YARN disponible se multiplica por 8.Since there are 8 nodes, the available YARN memory is multiplied by 8.

  • Memoria de YARN total = nodos * memoria de YARN * por nodoTotal YARN memory = nodes * YARN memory* per node
  • Memoria de YARN total = 8 nodos * 25 GB = 200 GBTotal YARN memory = 8 nodes * 25GB = 200GB

Paso 5: Calcule num-executors. El parámetro num-executors se determina a partir de la restricción mínima de memoria y de CPU, dividida por el número de aplicaciones que están ejecutando en Spark.Step 5: Calculate num-executors – The num-executors parameter is determined by taking the minimum of the memory constraint and the CPU constraint divided by the # of apps running on Spark.

Calcule la restricción de memoria. La restricción de memoria se calcula dividiendo la memoria YARN total entre la memoria por ejecutor.Calculate memory constraint – The memory constraint is calculated as the total YARN memory divided by the memory per executor.

  • Restricción de memoria = (memoria de YARN total / memoria del ejecutor) / número de aplicacionesMemory constraint = (total YARN memory / executor memory) / # of apps
  • Restricción de memoria = (200 GB / 6 GB)/ 2Memory constraint = (200GB / 6GB) / 2
  • Restricción de memoria = 16 (redondeado)Memory constraint = 16 (rounded)

Calcule la restricción de CPU. La restricción de la CPU se calcula dividiendo el total de núcleos YARN entre el número de núcleos por ejecutor.Calculate CPU constraint - The CPU constraint is calculated as the total yarn cores divided by the number of cores per executor.

  • Núcleos de YARN = nodos del clúster * número de núcleos por nodo * 2YARN cores = nodes in cluster * # of cores per node * 2
  • Núcleos de YARN = 8 nodos * 8 núcleos por D14 * 2 = 128YARN cores = 8 nodes * 8 cores per D14 * 2 = 128
  • Restricción de CPU = (Total de núcleos de YARN / número de núcleos por ejecutor) / número de aplicacionesCPU constraint = (total YARN cores / # of cores per executor) / # of apps
  • Restricción de CPU = (128 / 4) / 2CPU constraint = (128 / 4) / 2
  • Restricción de CPU = 16CPU constraint = 16

Establezca num-executorsSet num-executors

  • num-executors = min (restricción de memoria, restricción de CPU)num-executors = Min (memory constraint, CPU constraint)
  • num-executors = Min (16, 16)num-executors = Min (16, 16)
  • num-executors = 16num-executors = 16