Notas de estudio de Hive (5) -Optimización 2

Optimización de Seven JOIN

Optimización de la tabla de tallas

La optimización de la tabla de tamaño se refiere a cuando se unen dos o más tablas, es necesario asegurarse de que el tamaño de la tabla en la consulta continua aumente de izquierda a derecha. De esta manera, Hive guardará las tablas pequeñas en la memoria. Hive puede realizar el proceso de conexión en el lado del mapa y hacer coincidir las tablas pequeñas en la memoria una por una, omitiendo así el proceso de reducción requerido para las operaciones normales.

La primera forma de escribir es escribir de acuerdo con la posición de la tabla de tallas, es decir, la tabla pequeña se escribe en el frente y la tabla grande se escribe en la parte posterior. Las
divisiones son la tabla pequeña; las existencias son las mesa grande.

SELECT s.ymd, s.symbol,s.price_close,d,dividend
FROM divedends d JOIN stocks s ON s.ymd = d.ymd AND s.symblo = d.dymbol
WHERE s.symbol = "AAPL";  

La segunda es que a la colmena no le importa la posición de las tablas grandes y pequeñas, y usa el método de visualización "/ + [nombre de la tabla] /" para marcar las tablas grandes; también hay un MAPJOIN (combinación interna)

SELECT /*+STREAMTABLE(s)*/ s.ymd, s.symbol,s.price_close,d,dividend
FROM stocks s JOIN divedends d ON s.ymd = d.ymd AND s.symblo = d.dymbol
WHERE s.symbol = "AAPL";          --/*+STREAMTABLE(s)*/ 是标记那张表时大表

La tercera es que el usuario puede configurar la colmena de parámetros automáticamente sin marcar.

set hive.auto.convert.join=true

La cuarta configuración del tamaño de la tabla pequeña (el valor predeterminado es bytes)

hive.mapjoin.smalltable.fulesize=250000

La optimización anterior se puede aplicar de manera integral según la situación.

Valores vacíos o sin sentido.
Esta situación es muy común. Por ejemplo, cuando la tabla de hechos son datos de registro, a menudo hay algunos elementos que no se registran. Lo configuraremos como nulo, o una cadena vacía, -1, etc., según sobre la situación. Si faltan muchos elementos, estos valores vacíos estarán muy concentrados al realizar la unión, lo que ralentizará el progreso.
Por lo tanto, si no necesita datos nulos, escriba la instrucción where de antemano para filtrarla. Si necesita conservarlo, divida aleatoriamente la clave nula, por ejemplo, cambie el registro con el ID de usuario nulo a un valor negativo aleatoriamente:

select a.uid,a.event_type,b.nickname,b.age
from (
  select 
  (case when uid is null then cast(rand()*-10240 as int) else uid end) as uid,
  event_type from calendar_record_log
  where pt_date >= 20190201
) a left outer join (
  select uid,nickname,age from user_info where status = 4
) b on a.uid = b.uid;

El manejo de claves sesgadas solo
es en realidad una extensión del método anterior para manejar valores nulos, pero las claves sesgadas se han vuelto significativas. En términos generales, hay muy pocas claves sesgadas. Podemos muestrearlas, almacenar las filas correspondientes en una tabla temporal por separado y luego prefijarlas con un número aleatorio más pequeño (como 0-9) y finalmente agregarlas. La declaración SQL es similar a la anterior, por lo que no la repetiré.

Diferentes tipos de datos
Esta situación no es muy común y ocurre principalmente cuando las columnas del mismo significado comercial han sufrido cambios lógicos.
Por ejemplo, si tenemos dos tablas de registros de calendario, una antigua y otra nueva, el campo de tipo de registro de la tabla anterior es (event_type int) y la nueva tabla es (event_type string). Para ser compatible con la versión anterior del registro, event_type de la nueva tabla también almacenará el valor de la versión anterior como una cadena, como '17'. Cuando estas dos tablas se unen, a menudo lleva mucho tiempo. La razón es que si el tipo no se convierte, el valor hash de la clave se calcula por defecto en tipo int, lo que hace que todas las claves de cadena "reales" se asignen a un reductor. Así que preste atención a la conversión de tipos:

select a.uid,a.event_type,b.record_data
from calendar_record_log a
left outer join (
  select uid,event_type from calendar_record_log_2
  where pt_date = 20190228
) b on a.uid = b.uid and b.event_type = cast(a.event_type as string)
where a.pt_date = 20190228;

La tabla de compilación es demasiado grande
A veces, la tabla de compilación es demasiado grande para usar la combinación de mapas directamente, como una tabla de dimensiones de usuario completa, y el uso de la combinación ordinaria tiene el problema de la distribución de datos desigual. En este momento, es necesario hacer un uso completo de las condiciones de restricción de la tabla de sondeo para reducir el volumen de datos de la tabla de compilación y luego usar la combinación de mapas para resolverlo. El costo es que se requieren dos combinaciones. por ejemplo:

select /*+mapjoin(b)*/ a.uid,a.event_type,b.status,b.extra_info
from calendar_record_log a
left outer join (
  select /*+mapjoin(s)*/ t.uid,t.status,t.extra_info
  from (select distinct uid from calendar_record_log where pt_date = 20190228) s
  inner join user_info t on s.uid = t.uid
) b on a.uid = b.uid
where a.pt_date = 20190228;

Ocho optimización de MapReduce

Primero recuerda una ola del proceso de reproducción aleatoria de MR
Inserte la descripción de la imagen aquí

Nueve ajustan el número de mapeadores

El número de mapeadores está estrechamente relacionado con el número de divisiones del archivo de entrada org.apache.hadoop.mapreduce.lib.input.FileInputFormat. La lógica específica de la división dividida se puede ver en la clase de código fuente de Hadoop . No se publica ningún código aquí, pero describe directamente cómo se determina el número de asignador.

  • El valor esperado del número de asignador se puede establecer directamente a través del parámetro mapred.map.tasks (valor predeterminado 2), pero es posible que no tenga efecto, como se menciona a continuación.

  • Sea el tamaño total del archivo de entrada total_input_size. En HDFS, el tamaño de un bloque se especifica mediante el parámetro dfs.block.size, y el valor predeterminado es 64 MB o 128 MB. Por defecto, el número de mapeadores es `` '' shell default_mapper_num = total_input_size / dfs.block.size.

  • Los parámetros mapred.min.split.size (valor predeterminado 1B) y mapred.max.split.size (valor predeterminado 64 MB) se utilizan para especificar el tamaño de división mínimo y máximo, respectivamente. Las reglas para calcular el tamaño de la división y el número de divisiones son:

    MIN(mapred.max.split.size, dfs.block.size)); split_num =
    total_input_size / split_size。 ```
    
    得出mapper数:
    
    ```shell mapper_num = MIN(split_num, MAX(default_num,
    mapred.map.tasks))```
    
    
    

Se puede ver que si desea reducir el número de mapeadores, debe aumentar mapred.min.split.size apropiadamente, y el número de divisiones se reducirá. Si desea aumentar el número de mapeadores, además de reducir mapred.min.split.size, también puede aumentar mapred.map.tasks.
En términos generales, si el archivo de entrada es una pequeña cantidad de archivos grandes, reduzca la cantidad de mapeadores; si el archivo de entrada es una gran cantidad de archivos no pequeños, aumente la cantidad de mapeadores; como para una gran cantidad de archivos pequeños, consulte la sección "Fusionar archivos pequeños" a continuación Procesamiento de métodos.

Diez ajustan el número de reductores

El método para determinar el número de reductores es mucho más simple que el del mapeador. Utilice el parámetro mapred.reduce.tasks para establecer directamente el número de reductores, que no es el valor esperado como mapeador. Pero si este parámetro no está configurado, Hive lo adivinará por sí mismo, la lógica es la siguiente:

  • El parámetro hive.exec.reducers.bytes.per.reducer se utiliza para establecer la cantidad máxima de datos que puede manejar cada reductor. El valor predeterminado es 1G (antes de la versión 1.2) o 256M (después de la versión 1.2).

  • El parámetro hive.exec.reducers.max se utiliza para establecer el número máximo de reductores para cada trabajo. El valor predeterminado es 999 (antes de la versión 1.2) o 1009 (después de la versión 1.2).

  • Obtenga el número de reductores:
    shell reducer_num = MIN(total_input_size / reducers.bytes.per.reducer, reducers.max)。

El número de reductores está relacionado con el número de archivos de salida. Si hay demasiados reductores, se generará una gran cantidad de archivos pequeños, lo que ejercerá presión sobre HDFS. Si el número de reductores es demasiado pequeño, cada reductor tiene que procesar una gran cantidad de datos, lo que puede ralentizar el tiempo de ejecución o causar OOM.

Once fusionan archivos pequeños

En la fase de entrada
, es necesario cambiar el formato del archivo de entrada de Hive, es decir, el parámetrohive.input.format. El valor predeterminado esorg.apache.hadoop.hive.ql.io.HiveInputFormat, lo cambiamosorg.apache.hadoop.hive.ql.io.CombineHiveInputFormat.
En comparación con el ajuste anterior del número de mapeadores, habrá dos parámetros más, a saber, mapred.min.split.size.per.node y mapred.min.split.size.per.rack, es decir, nodo único y bastidor único. tamaño mínimo de división en la parte superior. Si se encuentra que un tamaño de división es menor que estos dos valores (el valor predeterminado es 100 MB), se combinará. Para conocer la lógica específica, consulte la clase correspondiente en el código fuente de Hive.
Fusionar la etapa de salida
establece directamente hive.merge.mapfiles y hive.merge.mapredfiles en true. La primera significa fusionar la salida de la tarea de solo mapa y la última significa fusionar la salida de la tarea de reducción de mapa.
Además, hive.merge.size.per.task puede especificar el valor esperado del tamaño de archivo combinado después de la salida de cada tarea, y hive.merge.size.smallfiles.avgsize puede especificar el umbral promedio de todos los tamaños de archivo de salida. el valor predeterminado es 1 GB. Si el tamaño medio es insuficiente, se inicia otra tarea para fusionar.

Doce habilitan la compresión

La compresión de los datos de resultados intermedios y los datos de salida del trabajo puede ahorrar mucho espacio con una pequeña cantidad de tiempo de CPU. El método de compresión generalmente elige Snappy, que tiene la mayor eficiencia.
Para habilitar la compresión intermedia, debe establecer hive.exec.compress.intermediate为truey especificar el método de compresión hive.intermediate.compression.codeccomo org.apache.hadoop.io.compress.SnappyCodec. Además, el parámetro hive.intermediate.compression.typepuede seleccionar compresión de bloque (BLOCK) o grabación (RECORD), y la tasa de compresión de BLOCK es relativamente alta.
La configuración de la compresión de salida es básicamente la misma, solo enciéndala hive.exec.compress.output.

Reutilización de dieciséis JVM

En el trabajo de MR, el valor predeterminado es iniciar una JVM cada vez que se ejecuta una tarea. Si la tarea es muy pequeña y está fragmentada, la JVM tardará mucho en iniciarse y cerrarse. Puede reutilizarse ajustando el parámetro mapred.job.reuse.jvm.num.tasks. Por ejemplo, si este parámetro se establece en 5, significa que 5 tareas ejecutadas secuencialmente en el mismo trabajo de MR pueden reutilizar una JVM, lo que reduce la sobrecarga de inicio y apagado. Pero no es válido para tareas en diferentes trabajos de RM.
Ejecución paralela y modo local

Diecisiete ejecuciones paralelas

Los trabajos que no dependen unos de otros en Hive se pueden ejecutar en paralelo, y el más típico es la unión de múltiples subconsultas. Cuando los recursos del clúster son relativamente suficientes, se puede habilitar la ejecución en paralelo, es decir, el parámetro hive.exec.parallel se establece en verdadero. Además, hive.exec.parallel.thread.number puede establecer el número de subprocesos de ejecución paralela, el valor predeterminado es 8, que generalmente es suficiente.
En modo local,
Hive también puede procesar tareas directamente en un nodo en lugar de enviar tareas al clúster para su cálculo. Debido a que se elimina la sobrecarga enviada al clúster, es más adecuado para tareas con pequeñas cantidades de datos y lógica sencilla.
Establezca hive.exec.mode.local.auto en verdadero para habilitar el modo local. Sin embargo, la cantidad total de datos de entrada para la tarea debe ser menor que hive.exec.mode.local.auto.inputbytes.max(valor predeterminado 128 MB), el número de mapeadores debe ser menor que hive.exec.mode.local.auto.tasks.max(valor predeterminado 4) y el número de reductores debe ser 0 o 1, para ejecutarse en modo local.

Decimoctavo modo estricto

所谓严格模式,就是强制不允许用户执行3种有风险的HiveQL语句,一旦执行会直接失败。这3种语句是:

Al consultar una tabla particionada, no limita el enunciado de la columna de partición; el enunciado del
producto cartesiano se genera mediante la unión de las dos tablas; el enunciado que
usa order by para ordenar pero no especifica el límite.

要开启严格模式,需要将参数hive.mapred.mode设为strict。

Diecinueve Adopte un formato de almacenamiento adecuado

	在HiveQL的create table语句中,可以使用stored as ...指定表的存储格式。Hive表支持的存储格式有TextFile、SequenceFile、RCFile、Avro、ORC、Parquet等。

El formato de almacenamiento generalmente debe seleccionarse de acuerdo con el negocio En nuestra práctica, la mayoría de las mesas utilizan uno de los dos formatos de almacenamiento, TextFile y Parquet.
TextFile es el formato de almacenamiento más simple, es un registro de texto sin formato y también es el formato predeterminado de Hive. Aunque su sobrecarga de disco es relativamente grande y la eficiencia de las consultas es baja, se utiliza más como trampolín. Las tablas en RCFile, ORC, Parquet y otros formatos no se pueden importar directamente desde archivos y deben ser transferidas por TextFile.
Parquet y ORC son formatos de almacenamiento en columnas de código abierto bajo Apache. El almacenamiento en columnas es más adecuado para consultas OLAP por lotes que el almacenamiento en filas tradicional, y también admite una mejor compresión y codificación. Elegimos Parquet principalmente porque es compatible con el motor de consultas Impala y tenemos una baja demanda de operaciones de actualización, eliminación y transacciones.
No ampliaré sus detalles aquí, puede consultar sus respectivos sitios web oficiales:
https://parquet.apache.org/
https://orc.apache.org/

referencia:


  1. Enlace "Guía de programación de Hive" : https://pan.baidu.com/s/15SXPvo9DIed_OuDmdwTjow
    Código de extracción: wauz
  2. "Documento de desarrollo de Meituan"
  3. https://www.jianshu.com/p/deb4a6f91d3b

Supongo que te gusta

Origin blog.csdn.net/u013963379/article/details/90724333
Recomendado
Clasificación