Linee guida per l'ottimizzazione delle prestazioni di Spark in HDInsight e di Azure Data Lake StorePerformance tuning guidance for Spark on HDInsight and Azure Data Lake Store

Per l'ottimizzazione delle prestazioni in Spark, è necessario considerare il numero di applicazioni che verranno eseguite nel cluster.When tuning performance on Spark, you need to consider the number of apps that will be running on your cluster. Per impostazione predefinita, nel cluster HDI è possibile eseguire 4 app simultaneamente (nota: l'impostazione predefinita è soggetta a modifiche).By default, you can run 4 apps concurrently on your HDI cluster (Note: the default setting is subject to change). È possibile decidere di usare un numero inferiore di app in modo da sostituire le impostazioni predefinite e usare una parte più ampia del cluster per tali applicazioni.You may decide to use fewer apps so you can override the default settings and use more of the cluster for those apps.

PrerequisitiPrerequisites

parametersParameters

Si riportano di seguito le impostazioni più importanti che possono essere ottimizzate per migliorare le prestazioni in ADLS durante l'esecuzione di processi Spark:When running Spark jobs, here are the most important settings that can be tuned to increase performance on ADLS:

  • Num-executors: numero di attività che è possibile eseguire simultaneamente.Num-executors - The number of concurrent tasks that can be executed.

  • Executor-memory: quantità di memoria allocata per ogni executor.Executor-memory - The amount of memory allocated to each executor.

  • Executor-cores: numero di core allocati per ogni executor.Executor-cores - The number of cores allocated to each executor.

Num-executors. I Num-executors impostano il numero massimo di attività che è possibile eseguire in parallelo.Num-executors Num-executors will set the maximum number of tasks that can run in parallel. Il numero effettivo di attività che possono essere eseguite in parallelo è limitato dalle risorse di memoria e CPU disponibili nel cluster.The actual number of tasks that can run in parallel is bounded by the memory and CPU resources available in your cluster.

Executor-memory. Si tratta della quantità di memoria che viene allocata per ogni executor.Executor-memory This is the amount of memory that is being allocated to each executor. La memoria necessaria per ogni executor dipende dal processo.The memory needed for each executor is dependent on the job. Per operazioni complesse, la quantità di memoria deve essere maggiore.For complex operations, the memory needs to be higher. Per operazioni semplici come la lettura e la scrittura, la quantità di memoria richiesta è inferiore.For simple operations like read and write, memory requirements will be lower. La quantità di memoria necessaria per ogni executor è disponibile in Ambari.The amount of memory for each executor can be viewed in Ambari. In Ambari passare a Spark e visualizzare la scheda Configs (Configurazioni).In Ambari, navigate to Spark and view the Configs tab.

Executor-cores. Definisce la quantità di core usati dall'executor predefinito, che determina il numero di thread paralleli che è possibile eseguire su ogni executor.Executor-cores This sets the amount of cores used per executor, which determines the number of parallel threads that can be run per executor. Ad esempio, se executor-cores = 2, ogni executor può eseguire 2 attività parallele nell'executor.For example, if executor-cores = 2, then each executor can run 2 parallel tasks in the executor. Gli executor-cores necessari dipendono dal processo.The executor-cores needed will be dependent on the job. I processi I/O intensivi non richiedono una grande quantità di memoria per ogni attività. In questo modo, ogni executor può gestire più attività in parallelo.I/O heavy jobs do not require a large amount of memory per task so each executor can handle more parallel tasks.

Per impostazione predefinita, durante l'esecuzione di Spark in HDInsight, vengono definiti due core YARN virtuali per ogni core fisico.By default, two virtual YARN cores are defined for each physical core when running Spark on HDInsight. Questo numero fornisce un buon bilanciamento tra concorrenza e quantità di contesto nel passaggio tra più thread.This number provides a good balance of concurrecy and amount of context switching from multiple threads.

IndicazioniGuidance

Durante l'esecuzione di carichi di lavoro analitici di Spark per l'elaborazione dei dati in Data Lake Store, si consiglia di usare la versione più recente del cluster HDInsight per ottenere prestazioni ottimali con Data Lake Store.While running Spark analytic workloads to work with data in Data Lake Store, we recommend that you use the most recent HDInsight version to get the best performance with Data Lake Store. Quando il processo prevede un I/O più intensivo, è possibile configurare alcuni parametri per migliorare le prestazioni.When your job is more I/O intensive, then certain parameters can be configured to improve performance. Azure Data Lake Store è una piattaforma di archiviazione altamente scalabile in grado di gestire un'elevata velocità effettiva.Azure Data Lake Store is a highly scalable storage platform that can handle high throughput. Se il processo è costituito principalmente da lettura o scrittura, l'aumento della concorrenza di I/O da e verso Azure Data Lake Store potrebbe migliorare le prestazioni.If the job mainly consists of read or writes, then increasing concurrency for I/O to and from Azure Data Lake Store could increase performance.

Esistono alcuni modi generali per aumentare la concorrenza per i processi con I/O intensivo.There are a few general ways to increase concurrency for I/O intensive jobs.

Passaggio 1: Determinare il numero di app in esecuzione nel cluster. È necessario conoscere il numero di applicazioni in esecuzione nel cluster, inclusa quella corrente.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. I valori predefiniti per ogni impostazione Spark presumono che siano presenti 4 applicazioni in esecuzione contemporanea.The default values for each Spark setting assumes that there are 4 apps running concurrently. Pertanto, si disporrà solo del 25% del cluster per ogni applicazione.Therefore, you will only have 25% of the cluster available for each app. Per ottenere prestazioni migliori, è possibile sostituire le impostazioni predefinite modificando il numero di executor.To get better performance, you can override the defaults by changing the number of executors.

Passaggio 2: Impostare executor-memory. La prima cosa da impostare è la memoria dell'executor.Step 2: Set executor-memory – the first thing to set is the executor-memory. La memoria dipende dal processo da eseguire.The memory will be dependent on the job that you are going to run. È possibile aumentare la concorrenza allocando una quantità inferiore di memoria per ogni executor.You can increase concurrency by allocating less memory per executor. Se vengono visualizzate eccezioni di memoria insufficiente quando si esegue il processo, è necessario aumentare il valore di questo parametro.If you see out of memory exceptions when you run your job, then you should increase the value for this parameter. In alternativa è possibile ottenere una maggiore quantità di memoria usando un cluster con maggiore memoria oppure aumentando le dimensioni del cluster.One alternative is to get more memory by using a cluster that has higher amounts of memory or increasing the size of your cluster. Una maggiore quantità di memoria consentirà di usare più executor, ottenendo così più concorrenza.More memory will enable more executors to be used, which means more concurrency.

Passaggio 3: Impostare executor-cores. Per carichi di lavoro I/O intensivi che non prevedono operazioni complesse, è consigliabile iniziare con un numero elevato di core per ogni executor al fine di aumentare il numero di attività parallele per ognuno di essi.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. Per iniziare, è consigliabile impostare executor-cores su 4.Setting executor-cores to 4 is a good start.

executor-cores = 4

L'aumento del numero di core dell'executor offrirà maggior parallelismo in modo che sia possibile sperimentare diversi core dell'executor.Increasing the number of executor-cores will give you more parallelism so you can experiment with different executor-cores. Per i processi che includono operazioni più complesse, è necessario ridurre il numero di core per ogni executor.For jobs that have more complex operations, you should reduce the number of cores per executor. Se executor-cores viene impostato su un valore superiore a 4, la Garbage Collection può diventare inefficiente e incidere negativamente sulle prestazioni.If executor-cores is set higher than 4, then garbage collection may become inefficient and degrade performance.

Passaggio 4: Determinare la quantità di memoria YARN nel cluster. Queste informazioni sono disponibili in Ambari.Step 4: Determine amount of YARN memory in cluster – This information is available in Ambari. Passare a YARN e visualizzare la scheda Configs (Configurazioni). La memoria YARN è visualizzata in questa finestra.Navigate to YARN and view the Configs tab. The YARN memory is displayed in this window.
Nota: nella finestra è possibile anche visualizzare anche le dimensioni predefinite del contenitore YARN.Note: while you are in the window, you can also see the default YARN container size. Le dimensioni del contenitore YARN sono uguali alle dimensioni della memoria per ogni parametro executor.The YARN container size is the same as memory per executor paramter.

Total YARN memory = nodes * YARN memory per node

Passaggio 5: Calcolare num-executorsStep 5: Calculate num-executors

Calcolare il vincolo della memoria. Il parametro num-executors è vincolato dalla memoria o dalla CPU.Calculate memory constraint - The num-executors parameter is constrained either by memory or by CPU. Il vincolo di memoria è determinato dalla quantità di memoria YARN disponibile per l'applicazione.The memory constraint is determined by the amount of available YARN memory for your application. Prendere il valore della memoria totale di YARN e dividerlo per il valore executor-memory.You should take total YARN memory and divide that by executor-memory. Il vincolo deve essere diviso per il numero di applicazioni.The constraint needs to be de-scaled for the number of apps so we divide by the number of apps.

Memory constraint = (total YARN memory / executor memory) / # of apps   

Calcolare il vincolo della CPU. Il vincolo della CPU viene calcolato come il numero totale dei core virtuali diviso per il numero di core per ogni executor.Calculate CPU constraint - The CPU constraint is calculated as the total virtual cores divided by the number of cores per executor. Per ogni core fisico sono presenti 2 core virtuali.There are 2 virtual cores for each physical core. Come per il vincolo di memoria, questo valore viene diviso per il numero di applicazioni.Similar to the memory constraint, we have divide by the number of apps.

virtual cores = (nodes in cluster * # of physical cores in node * 2)
CPU constraint = (total virtual cores / # of cores per executor) / # of apps

Impostare num-executors. Il parametro num-executors viene determinato dal valore minimo del vincolo della memoria e del vincolo della CPU.Set num-executors – The num-executors parameter is determined by taking the minimum of the memory constraint and the CPU constraint.

num-executors = Min (total virtual Cores / # of cores per executor, available YARN memory / executor-memory)   

Impostare un numero maggiore di num-executors non si traduce necessariamente in un miglioramento delle prestazioni.Setting a higher number of num-executors does not necessarily increase performance. Si noti che l'aggiunta di esecutori può comportare un carico extra per ciascuno di questi ultimi, con una potenziale diminuzione delle prestazioni.You should consider that adding more executors will add extra overhead for each additional executor, which can potentially degrade performance. I num-executors sono limitati dalle risorse del cluster.Num-executors is bounded by the cluster resources.

Calcolo di esempioExample Calculation

Si supponga di disporre di un cluster costituito da 8 nodi D4v2 che eseguono 2 applicazioni, inclusa quella che si è in procinto di eseguire.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.

Passaggio 1: Determinare il numero di app in esecuzione nel cluster. L'utente sa di avere 2 app nel cluster, inclusa quella corrente.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.

Passaggio 2: Impostare executor-memory. Per questo esempio, si stabilisce che 6 GB di memoria per executor saranno sufficienti per il processo I/O intensivo.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 = 6GB

Passaggio 3: Impostare executor-cores. Poiché si tratta di un processo I/O intensivo, è possibile impostare su 4 il numero di core per ogni executor.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. L'impostazione di un numero di core per executor superiore a 4 può causare problemi alla Garbage Collection.Setting cores per executor to larger than 4 may cause garbage collection problems.

executor-cores = 4

Passaggio 4: Determinare la quantità di memoria YARN nel cluster. Aprendo Ambari, si scopre che ogni D4v2 dispone di 25 GB di 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. Poiché sono presenti 8 nodi, la memoria di YARN disponibile viene moltiplicata per 8.Since there are 8 nodes, the available YARN memory is multiplied by 8.

Total YARN memory = nodes * YARN memory* per node
Total YARN memory = 8 nodes * 25GB = 200GB

Passaggio 5: Impostare num-executors. Il parametro num-executors viene determinato dal valore minimo del vincolo della memoria e del vincolo della CPU, divisi per il numero di app in esecuzione su 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.

Calcolare il vincolo della memoria. Il vincolo della memoria viene calcolato come la memoria totale di YARN divisa per la memoria di ogni executor.Calculate memory constraint – The memory constraint is calculated as the total YARN memory divided by the memory per executor.

Memory constraint = (total YARN memory / executor memory) / # of apps   
Memory constraint = (200GB / 6GB) / 2   
Memory constraint = 16 (rounded)

Calcolare il vincolo della CPU. Il vincolo della CPU viene calcolato come il numero totale dei core di YARN diviso per il numero di core per ogni executor.Calculate CPU constraint - The CPU constraint is calculated as the total yarn cores divided by the number of cores per executor.

YARN cores = nodes in cluster * # of cores per node * 2   
YARN cores = 8 nodes * 8 cores per D14 * 2 = 128
CPU constraint = (total YARN cores / # of cores per executor) / # of apps
CPU constraint = (128 / 4) / 2
CPU constraint = 16

Impostare num-executorsSet num-executors

num-executors = Min (memory constraint, CPU constraint)
num-executors = Min (16, 16)
num-executors = 16