¿Debo elegir ORC o Parquet para la creación de tablas de almacenamiento de datos de Hive y LZO o Snappy para la compresión?

Porque mencioné en el artículo anterior que estaba en la capa ods del almacén de datos porque usé
STORED AS INPUTFORMAT'com.hadoop.mapred.DeprecatedLzoTextInputFormat 'OUTPUTFORMAT'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat' almacenamiento modo, Pero me encontré con una situación en la que el resultado estadístico del recuento (*) es diferente del seleccionado *, por lo que tengo que comenzar a comprender el formato de almacenamiento de archivos en detalle (aunque el problema no se puede resolver, pero al menos en el camino hacia el La verdad del problema, quiero ver esto Para este artículo, vaya a la Enciclopedia de ajuste del entorno de Hive, pero todavía hay un error que no se ha resuelto, ¡que es un dolor de cabeza!).

En el almacén de datos, se recomienda que, a excepción de la tabla de interfaz (importada de otras bases de datos o finalmente exportada a otras bases de datos), el formato de almacenamiento de las tablas restantes sea consistente con el formato de compresión.

Primero hablemos sobre el formato de almacenamiento principal actual y el método de compresión de las tablas de Hive.

Formato de almacenamiento de archivos

Según el sitio web oficial de Hive, Apache Hive admite varios formatos de archivo familiares utilizados en Apache Hadoop, como TextFile (formato de texto), RCFile (archivo determinante), SequenceFile (archivo serializado binario), AVRO, ORC (rangos optimizados) Archivo de formato) y El formato parquet, entre los que actualmente utilizamos la mayoría de ellos son TextFile, SequenceFile, ORC y Parquet.

Echemos un vistazo más de cerca a estos dos tipos de almacenamiento determinante.

1 、 ORC

1.1 Estructura de almacenamiento de ORC

Primero obtenemos el diagrama del modelo de almacenamiento ORC del sitio web oficial

Parece un poco complicado, así que simplifiquémoslo un poco, dibujé un diagrama simple para ilustrar

Inserte la descripción de la imagen aquí

La figura de la izquierda muestra el método tradicional de almacenamiento de base de datos basado en filas, que se almacena por fila. Si no hay un índice de almacenamiento, si necesita consultar un campo, debe averiguar la fila completa de datos y luego filtrarla. Este tipo consume más recursos de IO, por lo que el método de índice se utilizó para resolver este problema al comienzo de Hive.

Sin embargo, debido al alto costo de los índices, en el actual Hive 3.X, los índices se han abolido y, por supuesto, el almacenamiento en columnas se ha introducido durante mucho tiempo.

El método de almacenamiento de la columna es en realidad el mismo que su nombre. Se almacena columna por columna, como se muestra en la figura de la derecha. De esta manera, si consulta los datos de un campo, es equivalente a una consulta de índice. , que es muy eficiente. Pero si necesita buscar toda la tabla, ocupa más recursos porque necesita tomar todas las columnas y resumirlas por separado. Entonces apareció el almacenamiento determinante de ORC.

     1. Cuando se requiere un escaneo completo de la tabla, se puede leer de acuerdo con el grupo de filas
     . 2. Si necesita obtener datos de la columna, lea la columna especificada sobre la base del grupo de filas, en lugar de todas las filas en todos los grupos de filas y dentro de una fila Datos para todos los campos.
Después de comprender la lógica básica del almacenamiento ORC, echemos un vistazo a su diagrama de modelo de almacenamiento.

Inserte la descripción de la imagen aquí

Al mismo tiempo, también he adjuntado el texto detallado a continuación, para que pueda consultarlo:

  • Franja: el lugar donde los archivos ORC almacenan datos. Cada franja es generalmente el tamaño de bloque de HDFS. (Contiene las siguientes 3 partes)
1. index data:保存了所在条带的一些统计信息,以及数据在 stripe中的位置索引信息。
2. rows data:数据存储的地方,由多个行组构成,每10000行构成一个行组,数据以流( stream)的形式进行存储。
3. stripe footer:保存数据所在的文件目录
  • Pie de página del archivo: contiene la lista de laminillas del archivo, el número de filas en cada franja y el tipo de datos de cada columna. También contiene información agregada, como el mínimo, el máximo, el recuento de filas y la suma de cada columna.
  • postscript: contiene información sobre los parámetros de compresión y el tamaño de la compresión

Entonces, de hecho, se encontró que ORC proporciona índices de tres niveles, nivel de archivo, nivel de tira y nivel de grupo de fila. Por lo tanto, al realizar consultas, el uso de estos índices puede evitar la mayoría de los archivos y bloques de datos que no cumplen las condiciones de la consulta.

Pero tenga en cuenta que la información de descripción de todos los datos en el ORC se junta con los datos almacenados y no se utiliza una base de datos externa.

Nota especial: las tablas de formato ORC también admiten transacciones ACID, pero las tablas que admiten transacciones deben ser tablas agrupadas, por lo que son adecuadas para actualizar grandes lotes de datos. No se recomienda utilizar transacciones para actualizar pequeños lotes de datos con frecuencia.

#开启并发支持,支持插入、删除和更新的事务
set hive. support concurrency=truei
#支持ACID事务的表必须为分桶表
set hive. enforce bucketing=truei
#开启事物需要开启动态分区非严格模式
set hive.exec,dynamicpartition.mode-nonstrict
#设置事务所管理类型为 org. apache.hive.q1. lockage. DbTxnManager
#原有的org. apache. hadoop.hive.q1.1 eckmar. DummyTxnManager不支持事务
set hive. txn. manager=org. apache. hadoop. hive. q1. lockmgr DbTxnManageri
#开启在相同的一个 meatore实例运行初始化和清理的线程
set hive. compactor initiator on=true:
#设置每个 metastore实例运行的线程数 hadoop
set hive. compactor. worker threads=l
#(2)创建表
create table student_txn
(id int,
name string
)
#必须支持分桶
clustered by (id) into 2 buckets
#在表属性中添加支持事务
stored as orc
TBLPROPERTIES('transactional'='true‘);
#(3)插入数据
#插入id为1001,名字为student 1001
insert into table student_txn values('1001','student 1001');
#(4)更新数据
#更新数据
update student_txn set name= 'student 1zh' where id='1001';
# (5)查看表的数据,最终会发现id为1001被改为 sutdent_1zh

1.2 Configuración de Hive sobre ORC

Propiedades de configuración de la tabla (configuradas cuando se crea la tabla, por ejemplo tblproperties ('orc.compress'='snappy');:

  • orc.compress: indica el tipo de compresión de los archivos ORC. Los tipos disponibles son NONE, ZLB y SNAPPY. El valor predeterminado es ZLIB (Snappy no admite la división), esta configuración es la más crítica.
  • orc. compress.Slze: representa el tamaño de los fragmentos comprimidos, el valor predeterminado es 262144 (256 KB).
  • orc. stripe.size: write stripe, el tamaño del grupo de búfer de memoria que se puede usar, el valor predeterminado es 67108864 (64 MB)
  • orc. row. index. stride: el tamaño de los datos del índice de nivel de grupo de filas, el valor predeterminado es 10000 y debe establecerse en un número mayor o igual a 10000
  • orc. create index: ya sea para crear un índice de nivel de grupo de filas, el valor predeterminado es verdadero
  • orc. filtro de floración. columnas: es necesario crear un grupo de filtro de floración.
  • orc. bloom filter fpp: Falso Probabilidad positiva de usar el filtro bloom, el valor predeterminado es 0.

Extensión: con el filtro de floración en Hive, puede determinar rápidamente si los datos se almacenan en la tabla con menos espacio de archivo, pero también hay casos en los que se considera que los datos que no pertenecen a esta tabla pertenecen a esta tabla, esto es llamada probabilidad falsa positiva, el desarrollador puede ajustar la probabilidad, pero cuanto menor sea la probabilidad, el filtro Bloom necesita

2 、 Parquet

Después de hablar sobre ORC anteriormente, también tenemos una comprensión básica del almacenamiento determinante, y Parquet es otra estructura de almacenamiento determinante de alto rendimiento.

2.1 Estructura de almacenamiento de parquet

Dado que ORC es tan eficiente, ¿por qué necesita otro Parquet? Esto se debe a que Parquet permitirá que cualquier proyecto del ecosistema de Hadoop utilice una representación de datos en columnas comprimida y eficiente . Admite formatos de compresión: Snappy, GZIP, Lzo

Parquet 是语言无关的,而且不与任何一种数据处理框架绑定在一起,适配多种语言和组件,能够与 Parquet 配合的组件有:

查询引擎: Hive, Impala, Pig, Presto, Drill, Tajo, HAWQ, IBM Big SQL

计算框架: MapReduce, Spark, Cascading, Crunch, Scalding, Kite

数据模型: Avro, Thrift, Protocol Buffers, POJOs

Echemos un vistazo a la estructura de almacenamiento de Parquet, primero en el sitio web oficial

Inserte la descripción de la imagen aquí

Bueno, es un poco grande, dibujaré una versión simple

Inserte la descripción de la imagen aquí

Los archivos Parquet se almacenan en modo binario, por lo que no se pueden leer directamente. Al igual que ORC, los metadatos y los datos del archivo se almacenan juntos, por lo que los archivos en formato Parquet se autoanalizan.

  1. Grupo de filas: cada grupo de filas contiene un cierto número de filas, y al menos un grupo de filas se almacena en un archivo HDFS, similar al concepto de banda de orcos.
  2. Fragmento de columna: cada columna de un grupo de filas se almacena en un bloque de columnas, y todas las columnas del grupo de filas se almacenan consecutivamente en este archivo de grupo de filas. Los valores de un bloque de columnas son todos del mismo tipo y se pueden comprimir diferentes bloques de columnas utilizando diferentes algoritmos.
  3. Página: cada bloque de columna se divide en varias páginas. Una página es la unidad más pequeña de codificación. Las diferentes páginas del mismo bloque de columna pueden utilizar diferentes métodos de codificación.

2.2 Propiedades de configuración de la mesa de aparcamiento

  • tamaño de bloque de parquet: el valor predeterminado es 134217728byte, que es de 128 MB, que representa el tamaño de bloque del grupo de filas en la memoria. Establecer este valor en un valor alto puede mejorar la eficiencia de lectura de los archivos Parquet, pero en consecuencia, necesita consumir más memoria al escribir.
  • parquet.page: size: El valor predeterminado es 1048576byt, que es 1 MB, que significa el tamaño de cada página (página). Esto se refiere específicamente al tamaño de la página comprimida, y los datos de la página se descomprimirán primero cuando se lean. Una página es la unidad más pequeña de datos operativos de Parquet. Debe leer una página completa de datos cada vez que la lea antes de poder acceder a los datos. Si este valor se establece demasiado pequeño, causará problemas de rendimiento durante la compresión.
  • parquet .compresión: el valor predeterminado es SIN COMPRIMIR, que significa el método de compresión de la página. Los métodos de compresión disponibles son SIN COMPRIMIR, SNAPPY, GZP y LZO.
  • Parquet enable. Dictionary: el valor predeterminado es tue, que indica si se debe habilitar la codificación del diccionario.
  • parquet. diccionario page.size: el valor predeterminado es 1048576byte, que es 1 MB. Cuando se utiliza la codificación de diccionario, se crea una página de diccionario en cada fila y columna de Parquet. Con la codificación de diccionario, si hay muchos datos duplicados en las páginas de datos almacenadas, puede tener un buen efecto de compresión y también puede reducir el uso de memoria de cada página.

3. Comparación de ORC y Parquet

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

Al mismo tiempo, a partir del caso del autor de "Hive Performance Tuning", se importaron dos tablas en formatos de almacenamiento ORC y Parquet, se importaron los mismos datos y se realizaron consultas SQL. Se encontró que las filas se leen usando ORC eran mucho más pequeños que Parquet, por lo que se utilizó ORC. Como almacenamiento, se pueden filtrar más datos innecesarios con la ayuda de metadatos, y los recursos de clúster necesarios para la consulta son menores que Parquet. (Para un análisis de rendimiento más detallado, vaya a https://blog.csdn.net/yu616568/article/details/51188479)
Por lo tanto, ORC aún se ve mejor en términos de almacenamiento

Método de compresión

formato Divisible Velocidad de compresión media Eficiencia de compresión de archivos de texto Códec de compresión Hadoop Implementación pura de Java Primitivo Observaciones
gzip no rápido elevado org.apache.hadoop.io.compress.GzipCodec  
lzo Sí (según la biblioteca utilizada) muy rapido medio com.hadoop.compression.lzo.LzoCodec Necesita instalar LZO en cada nodo
bzip2 lento muy alto org.apache.hadoop.io.compress.Bzip2Codec Use Java puro para la versión divisible
zlib no lento medio org.apache.hadoop.io.compress.DefaultCodec Códec de compresión predeterminado de Hadoop
Rápido no muy rapido bajo org.apache.hadoop.io.compress.SnappyCodec no Snappy tiene un puerto Java puro, pero no se puede usar en Spark / Hadoop

¿Cómo elegir la combinación de almacenamiento y compresión?

Según los requisitos de ORC y parquet, generalmente disponible

1. Almacenamiento en formato ORC, compresión rápida

create table stu_orc(id int,name string)
stored as orc 
tblproperties ('orc.compress'='snappy');

2. Almacenamiento en formato parquet, compresión Lzo

create table stu_par(id int,name string)
stored as orc 
tblproperties ('parquet.compression'='lzo');

3. Almacenamiento en formato parquet, compresión Snappy

create table stu_par(id int,name string)
stored as orc 
tblproperties ('parquet.compression'='snappy');

Debido a que el SQL de Hive se convertirá en tareas de MR, si el archivo se almacena en ORC y Snappy lo comprime, debido a que Snappy no admite la división de archivos, el archivo comprimido solo será leído por una tarea. Si el archivo comprimido es grande, entonces Tomará mucho más tiempo procesar el Mapa del archivo que leer el Mapa de un archivo ordinario Este es el sesgo de datos del archivo de lectura de mapas que se menciona a menudo.

Para evitar esta situación, es necesario utilizar algoritmos de compresión que admitan la segmentación de archivos como bzip2 y Zip al comprimir datos. Pero es precisamente que ORC no admite los métodos de compresión que acabamos de mencionar, por lo que esta se ha convertido en la razón por la que no elige ORC cuando puede encontrar archivos grandes para evitar sesgos de datos.

En el enfoque de Hve on Spark, ocurre lo mismo: como arquitectura distribuida, Spark normalmente intenta leer datos de varias máquinas diferentes juntas. Para lograr esta situación, cada nodo de trabajo debe poder encontrar el comienzo de un nuevo registro, lo que requiere que el archivo se pueda dividir, pero para algunos archivos comprimidos que no se pueden dividir, se debe usar un solo nodo para leer todos los datos. Esto puede provocar fácilmente cuellos de botella en el rendimiento. (El siguiente artículo escribe en detalle el análisis del código fuente de los archivos de lectura de Spark)

Por lo tanto, en la producción real, es más común utilizar almacenamiento de Parquet y compresión lzo. En este caso, se puede evitar la desviación de datos causada por la lectura de archivos grandes indivisibles.
Sin embargo, si la cantidad de datos no es grande (se predice que no habrá archivos grandes, más de unos pocos G), utilizando el almacenamiento ORC, la eficiencia de la compresión rápida sigue siendo muy alta.

 

Supongo que te gusta

Origin blog.csdn.net/qq_32445015/article/details/115312951
Recomendado
Clasificación