Proceso de consulta de parquet

El proceso general: De acuerdo con el Filtro proporcionado por el usuario, primero filtre todos los RowGroup (Block) en el archivo y deje el RowGroup que cumpla con los requisitos. Lea todos los fragmentos involucrados en estos grupos de filas, descomprima las páginas una por una, combínelas en registros y luego fíltrelas.

detalle:

  • Independientemente de si una página cumple las condiciones, se deserializará.
  • Combine elementos de varias páginas en un registro, fíltrelos, coloque los resultados filtrados en el predicado IncrementallyUpdatedFilterPredicate y elija si desea devolver esta fila de datos en función de este resultado.

Proceso de lectura

  • Leer metadatos de archivos

    Primero, en ParquetReader.build, lea el pie de página al final del archivo, que contiene los metadatos de todo el archivo, es decir, ParquetMetadata.

  • Inicialización: ParquetReader.initReader ()

    • Filtrar RowGroup. De acuerdo con las estadísticas y el filtro en el grupo de filas, filtre todos los grupos de filas del archivo y descarte los grupos de filas insatisfechos.
  • 构造 RecordReader: InternalParquetRecordReader.checkRead ()

    • Leer un RowGroup (PageReader que contiene cada Chunk) y leer los bytes de todos los Chunks involucrados en la consulta en la memoria.
    • Para cada fragmento, construya todas sus páginas, rellénelas con matrices de bytes y use estas páginas comprimidas y decodificadores para construir un ColumnChunkPageReader.
    • Construya un RecordReader basado en estos ColumnChunkPageReader. Construyó un RecordReaderImplementation. Y comience a leer Page en el método checkRead () de ColumnReaderImpl y descomprima la página.
  • Leer una fila de datos

    • De acuerdo con el método de cálculo de Nivel de Definición y Nivel de Repetición, se construye un Registro fila por fila Si esta fila de Registro es Nula, la condición no se cumple y se continúa construyendo el Registro. Durante el filtrado, siempre se mantiene un IncrementallyUpdatedFilterPredicate. Este predicado registra si el registro actual cumple las condiciones. En IncrementallyUpdatedFilterPredicateBuilder, el estado del predicado se actualiza de acuerdo con los nuevos datos.

Código de consulta

  • confiar
	<dependency>
      <groupId>org.apache.hadoop</groupId>
      <artifactId>hadoop-client</artifactId>
      <version>2.7.7</version>
    </dependency>

    <dependency>
      <groupId>org.apache.spark</groupId>
      <artifactId>spark-sql_2.11</artifactId>
      <version>2.3.0</version>
    </dependency>
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.parquet.column.ParquetProperties;
import org.apache.parquet.example.data.Group;
import org.apache.parquet.example.data.simple.SimpleGroupFactory;
import org.apache.parquet.filter2.compat.FilterCompat;
import org.apache.parquet.hadoop.ParquetInputFormat;
import org.apache.parquet.hadoop.ParquetReader;
import org.apache.parquet.hadoop.ParquetWriter;
import org.apache.parquet.hadoop.api.ReadSupport;
import org.apache.parquet.hadoop.example.GroupReadSupport;
import org.apache.parquet.hadoop.example.GroupWriteSupport;
import org.apache.parquet.hadoop.metadata.CompressionCodecName;
import org.apache.parquet.schema.MessageType;
import org.apache.parquet.schema.PrimitiveType;
import org.apache.parquet.schema.Type;
import org.apache.parquet.schema.Types;

Configuration conf = new Configuration();
    ParquetInputFormat.setFilterPredicate(conf,
        and(gtEq(longColumn("long_column"), startTime),
            ltEq(longColumn("long_column"), endTime)));
    FilterCompat.Filter filter = ParquetInputFormat.getFilter(conf);

    Types.MessageTypeBuilder builder = Types.buildMessage();
    builder.addField(new PrimitiveType(Type.Repetition.REQUIRED, PrimitiveType.PrimitiveTypeName.INT64, "long_column"));
    builder.addField(new PrimitiveType(Type.Repetition.OPTIONAL, PrimitiveType.PrimitiveTypeName.DOUBLE, "double_column"));

    MessageType querySchema = builder.named("default_schema_name");
    conf.set(ReadSupport.PARQUET_READ_SCHEMA, querySchema.toString());

    // set reader
    ParquetReader.Builder<Group> reader= ParquetReader
            .builder(new GroupReadSupport(), new Path("file_path"))
            .withConf(conf)
            .withFilter(filter);

    ParquetReader<Group> build;
    int result = 0;
    try {
      build = reader.build();
      Group line;
      while((line=build.read())!=null) {
        result++;
      }
    } catch (IOException e) {
      e.printStackTrace();
    }

Supongo que te gusta

Origin blog.csdn.net/qiaojialin/article/details/90245209
Recomendado
Clasificación