Directorio de artículos
1. Concepto SparkShuffle
reduceByKey agregará todos los valores correspondientes a cada clave en el RDD anterior en un valor, y luego generará un nuevo RDD. El tipo de elemento tiene la forma de pares <K, V>, de modo que cada clave corresponde a un valor agregado.
Entonces pensaremos en varias preguntas:
- Antes de la agregación, el valor correspondiente a cada clave no está necesariamente en una partición, ni es probable que esté en el mismo nodo, porque RDD es un conjunto de datos elásticos distribuidos y es muy probable que las particiones RDD se distribuyan en cada nodo.
En respuesta a tal problema, ¿cómo agregamos?
- Escritura aleatoria: cada tarea de mapa de la etapa anterior debe garantizar que escribe la misma clave de los datos de la partición actual que está procesando en un archivo de partición y puede escribir en varios archivos de partición diferentes.
- Lectura aleatoria: La tarea de reducción encontrará su propio archivo de partición en la máquina donde se encuentran todas las tareas de la etapa anterior, de modo que pueda garantizar que el valor correspondiente a cada clave se recopile en el mismo nodo para su procesamiento y agregación.
Hay dos tipos de administración de Shuffle en Spark HashShuffleManager
y SortShuffleManager
. Antes de Spark1.2 HashShuffleManager
, se introdujo Spark1.2 SortShuffleManager
. Ha sido HashShuffleManager
descartado en la versión Spark2.0 + .
2. HashShuffleManager
2.1 Mecanismo general
- Diagrama de mecanismo general
-
Proceso de implementación
- Cada tarea de mapa escribe diferentes resultados en diferentes búferes y el tamaño de cada búfer es 32k. búfer juega el papel de almacenamiento en caché.
- Cada archivo de búfer corresponde a un pequeño archivo de disco al final.
- Reduzca la tarea para extraer los archivos de disco pequeños correspondientes.
-
para resumir
-
El resultado del cálculo de la tarea de mapa se basará en el particionador (el predeterminado es
hasPartitioner
) para decidir qué archivo de disco pequeño escribir. La tarea de reducción irá al lado del mapa para extraer los archivos de disco pequeños correspondientes. -
Número de archivos de disco pequeños generados:
M(map task 个数) * R(reduce task 个数)
-
-
El problema
Demasiados archivos pequeños en el disco causarán los siguientes problemas:
- Durante el proceso Shuffle Writer, se generarán muchos objetos que escriben pequeños archivos en el disco.
- Durante el proceso de lectura aleatoria, se generarán muchos objetos que leen archivos pequeños en el disco.
- Demasiados objetos en la memoria del montón de JVM causarán gc frecuente. Si gc no puede resolver la memoria requerida para la operación, será OOM.
- En el proceso de transmisión de datos, habrá comunicación de red frecuente, y la posibilidad de falla de comunicación en la comunicación de red frecuente aumenta enormemente. Una vez que falla la comunicación de red, se producirá el archivo aleatorio no se puede encontrar y la tarea fallará debido a este error. TaskScheduler no es responsable de reintentar, pero DAGSchedule es responsable de reintentar Stage.
2.2 Mecanismo de fusión
- Diagrama esquemático del mecanismo de fusión
-
Proceso de implementación
- Varias tareas de mapas comparten un búfer y luego las escriben en archivos de disco.
- reducir la tarea de extraer archivos de disco pequeños
-
para resumir,
Número de archivos de disco pequeños generados:
C(core 的个数) * R(reduce task 个数)
3. SortShuffleManager
3.1 Mecanismo general
- Diagrama de mecanismo general
-
Proceso de implementación
- El resultado del cálculo de la tarea de mapa se escribirá en una estructura de datos de memoria, que es 5M por defecto.
- En la reproducción aleatoria, cuando habrá un temporizador, de vez en cuando para estimar el tamaño de la estructura de la memoria, cuando la estructura de datos en la memoria sea de más de 5M, como la estructura de datos de la memoria actual es 5.01M, entonces solicitará
5.01*2 - 5 = 5.02M
la estructura de datos en la memoria. - Si la aplicación de memoria tiene éxito, el disco no se sobrescribirá. Si la aplicación no tiene éxito, se enviará un disco de desbordamiento en este momento.
- Antes de sobrescribir el disco, los datos de la estructura de la memoria se ordenarán y dividirán.
- Entonces comienza a sobrescribir el disco. El disco se escribe en forma de lotes. Un lote son 10,000 piezas de datos.
- Una vez ejecutada la tarea de mapa, estos pequeños archivos de disco se fusionarán en un archivo de disco grande y se generará un archivo de índice al mismo tiempo.
- Cuando la tarea de reducción extrae datos del lado del mapa, primero analiza el archivo de índice y luego extrae los datos correspondientes de acuerdo con el archivo de índice.
-
para resumir
La cantidad de archivos pequeños en el disco:
2 * M (map task 的个数)
3.2 Mecanismo de bypass
-
Diagrama esquemático del mecanismo de derivación
-
Proceso de implementación
Básicamente, no hay diferencia entre el proceso de ejecución y el modo normal, excepto que falta un paso de la operación de clasificación.
-
para resumir
-
Las condiciones de activación del mecanismo de operación de bypass son las siguientes:
menor que el número de tareas de reducción aleatoria
spark.shuffle.sort.bypassMergeThreahold
establecidas en el valor. El valor predeterminado es 200. -
Disco pequeño número de documentos producidos:
2 * M (map task 的个数)
.
-
4. Reproducción aleatoria de direcciones de archivos
4.1 MapOutputTracker
MapOutputTracker
Es un módulo en la arquitectura Spark y una arquitectura maestro-esclavo. Administre las direcciones de pequeños archivos en el disco.
MapOutputTrackerMaster
Es el objeto principal y existe en Driver.MapOutputTrackerWorker
Es un objeto esclavo, que existe en el Excutor.
4.2 BlockManager
BlockManager es un módulo en la arquitectura Spark y también una arquitectura maestro-esclavo.
-
BlockManagerMaster
, El objeto principal, existe en Driver.BlockManagerMaster
Se utilizará al difundir variables y datos de caché en el clúster o eliminar los datos almacenados en caché, notificar laBlockManagerSlave
transmisión o eliminar datos. -
BlockManagerSlave
, Del objeto, existe en el Ejecutor.BlockManagerSlave
SeBlockManagerMaster
comunicarán entre sí.
Tanto en el lado del conductor BlockManagerMaster
como en el lado del ejecutor BlockManagerSlave
contiene tres objetos:
- DiskStore: responsable de la gestión del disco.
- MemoryStore: responsable de la gestión de la memoria.
- BlockTransferService: Responsable de la transmisión de datos.
4.3 Direccionamiento de archivos aleatorios
Como se muestra en la figura, el proceso de direccionamiento de archivos aleatorios:
- Cuando se completa la ejecución de la tarea de mapa, la tarea abordará la implementación de archivos pequeños y paquete de disco en
MapStatus
el objeto porMapOutputTrackerWorker
el objeto en elMapOutputTrackerMaster
informe del controlador . - Una vez ejecutadas todas las tareas del mapa, el controlador ha dominado las direcciones de todos los archivos de disco pequeños.
- Antes de reducir la ejecución de la tarea, el ejecutor de la voluntad
MapOutputTrackerWorker
al final del controladorMapOutputTrackerMaster
obtendrá la dirección del archivo de disco pequeño. - Después de obtener un pequeño archivo a la dirección del disco, pasará
BlockManager
, y luego a través del nodo donde se encuentra la conexiónBlockTrasferService
de datos para la transmisión de datos. BlockTransferService
De forma predeterminada, se inician 5 tareas para extraer datos de los nodos. De forma predeterminada, la cantidad de datos extraídos por 5 tareas no puede exceder los 48M.
5. Optimización aleatoria
5.1 Parámetros de ajuste
-
spark.shuffle.file.buffer
Valor predeterminado: 32 k
Descripción del parámetro: establece la tarea de escritura aleatoria del
BufferedOutputStream
nuevo tamaño de búfer. Antes de escribir los datos en el disco, se escribirán en el búfer. Una vez que el búfer esté lleno, se desbordará hacia el disco.Sugerencia de ajuste: si los recursos de memoria disponibles para el trabajo son suficientes, puede aumentar adecuadamente el valor de este parámetro (como 64k) para reducir la cantidad de veces que se sobrescribe el archivo de disco durante el proceso de escritura aleatoria. También puede reducir la cantidad de E / S de disco y mejorar el rendimiento. En la práctica, se encuentra que al ajustar este parámetro de manera razonable, el rendimiento mejorará entre un 1% y un 5%.
-
spark.reducer.maxSizeInFlight
:Valor predeterminado: 48 M
Descripción del parámetro: Este parámetro se utiliza para establecer el tamaño del búfer de la tarea de lectura aleatoria. Este búfer determina cuántos datos se pueden extraer cada vez.
Sugerencia de ajuste: si los recursos de memoria disponibles para el trabajo son suficientes, puede aumentar el valor (por ejemplo, 96M) de manera adecuada para reducir el número de extracciones de datos. Esto reduce el número de transmisiones de red y mejora el rendimiento. En la práctica, se encuentra que al ajustar este parámetro de manera razonable, el rendimiento mejorará entre un 1% y un 5%.
-
spark.shuffle.io.maxRetries
Valor predeterminado: 3
Descripción del parámetro: cuando la tarea de lectura aleatoria extrae sus propios datos del nodo donde se encuentra la tarea de escritura aleatoria, si la extracción falla debido a una anomalía en la red, lo reintentará automáticamente. Este parámetro representa el número máximo de reintentos. Si la extracción sigue sin éxito dentro del número especificado de veces, puede provocar que la ejecución del trabajo falle.
Sugerencias de ajuste: para aquellos trabajos que contienen operaciones de reproducción aleatoria que requieren mucho tiempo, se recomienda aumentar el número máximo de reintentos (por ejemplo, 5 veces) para evitar fallas de extracción de datos causadas por factores como JVM full gc o inestabilidad de la red. En la práctica, se ha descubierto que para el proceso de reproducción aleatoria de cantidades extremadamente grandes de datos (miles de millones a decenas de miles de millones), el ajuste de este parámetro puede mejorar en gran medida la estabilidad.
shuffle file not find taskScheduler no es responsable de reintentar la tarea, pero DAGScheduler es responsable de reintentar la etapa
-
spark.shuffle.io.retryWait
Valor predeterminado: 5 s
Descripción del parámetro: La explicación específica es la misma que la anterior. Este parámetro representa el intervalo de espera para cada reintento para extraer datos. El valor predeterminado es 5 s.
Sugerencia de ajuste: se recomienda aumentar el intervalo de tiempo (por ejemplo, 60 s) para aumentar la estabilidad de la operación aleatoria. -
spark.shuffle.memoryFraction
Valor predeterminado: 0,2
Descripción del parámetro: este parámetro representa la proporción de memoria asignada para mezclar tareas de lectura para operaciones de agregación en la memoria del ejecutor, y el valor predeterminado es 20%.
Sugerencia de ajuste: si la memoria es suficiente y las operaciones persistentes rara vez se utilizan, se recomienda aumentar esta proporción y dar más memoria a la operación de agregación de lectura aleatoria para evitar lecturas y escrituras frecuentes en el disco durante el proceso de agregación debido a memoria insuficiente. En la práctica, se encuentra que un ajuste razonable de este parámetro puede aumentar el rendimiento en aproximadamente un 10%.
-
spark.shuffle.manager
Valor predeterminado: sort | hash
Descripción del parámetro: este parámetro se utiliza para establecer el tipo de ShuffleManager. Después de Spark 1.5, hay tres opciones: hash, sort y tungsten-sort. HashShuffleManager es la opción predeterminada antes de Spark 1.2, pero la predeterminada es SortShuffleManager para Spark 1.2 y versiones posteriores. La ordenación de tungsteno es similar a la ordenación, pero utiliza el mecanismo de administración de memoria fuera de pila del plan Tungsten, que hace que el uso de la memoria sea más eficiente.
Sugerencia de ajuste: dado que SortShuffleManager ordena los datos de forma predeterminada, si necesita este mecanismo de clasificación en su lógica empresarial, puede utilizar el SortShuffleManager predeterminado; y si su lógica empresarial no necesita ordenar los datos, se recomienda consultar En el siguiente ajuste de parámetros, se utiliza el mecanismo de omisión o HashShuffleManager optimizado para evitar operaciones de clasificación y proporcionar un mejor rendimiento de lectura y escritura del disco. Cabe señalar aquí que tungsten-sort debe usarse con precaución, porque se han encontrado algunos errores correspondientes antes.
-
spark.shuffle.sort.bypassMergeThreshold----针对SortShuffle
Valor predeterminado: 200
Descripción del parámetro: cuando ShuffleManager es SortShuffleManager, si el número de tareas de lectura aleatoria es menor que este umbral (el valor predeterminado es 200), la operación de clasificación no se realizará durante el proceso de escritura aleatoria, pero los datos se escribirán directamente de acuerdo con el método HashShuffleManager no optimizado. Pero al final, todos los archivos de disco temporales generados por cada tarea se fusionarán en un solo archivo y se creará un archivo de índice separado.
Sugerencia de ajuste: cuando utiliza SortShuffleManager, si la operación de clasificación no es realmente necesaria, se recomienda aumentar este parámetro para que sea mayor que el número de tareas de lectura aleatoria. Entonces, el mecanismo de omisión se habilitará automáticamente en este momento y el lado del mapa no se ordenará, lo que reduce la sobrecarga de rendimiento de la clasificación. Pero de esta forma, se seguirá generando una gran cantidad de archivos de disco, por lo que es necesario mejorar el rendimiento de la escritura aleatoria.
-
spark.shuffle.consolidateFiles----针对HashShuffle
Valor predeterminado: falso
Descripción del parámetro: si se utiliza HashShuffleManager, este parámetro es válido. Si se establece en verdadero, el mecanismo de consolidación se activará y los archivos de salida de escritura aleatoria se fusionarán en gran medida. En el caso de un número particularmente grande de tareas de lectura aleatoria, este método puede reducir en gran medida la sobrecarga de E / S del disco y mejorar el rendimiento.
Sugerencia de ajuste: si no necesita el mecanismo de clasificación de SortShuffleManager, además de utilizar el mecanismo de omisión, también puede intentar especificar manualmente el parámetro spark.shffle.manager como hash, utilizar HashShuffleManager y activar el mecanismo consolidado. Lo probé en la práctica y descubrí que su rendimiento es entre un 10% y un 30% superior al de SortShuffleManager con el mecanismo de derivación activado.
5.2 Método de sintonización
-
Ajuste de código
sparkConf.set("spark.shuffle.file.buffer","64K")
Este método tiene la prioridad más alta, pero debido a la codificación rígida, el método de ajuste no es flexible y requiere una modificación del código para que surta efecto. No se recomienda.
-
Ajuste del archivo de configuración
Modifique el archivo conf / spark-defaults.conf
spark.shuffle.file.buffer=64k
Este método tiene la tercera prioridad y se utiliza para todos los programas de chispa.
-
Iniciar el ajuste de comandos
./spark-submit --conf spark.shuffle.file.buffer=64 --conf spark.reducer.maxSizeInFlight=96
Este método tiene la segunda prioridad. Puede modificar los parámetros de ajuste con el programa en ejecución, que es más flexible. Se recomienda utilizar este método.