Learning Platform
Глоссарий Troubleshooting
Урок 03.07 · 20 мин
Средний
ParquetFile ViewerInteractiveByte OffsetsInspection

Интерактивный Parquet File Viewer

Зачем нужен File Viewer

В предыдущих уроках мы изучили каждый слой отдельно: row groups, column chunks, pages, encodings, metadata. Теперь соберём все вместе — в интерактивном viewer, который показывает реальную структуру Parquet-файла.

Viewer ниже представляет файл с 200 000 строк в 2 row groups по 3 колонки (user_id: INT64, username: BYTE_ARRAY, score: DOUBLE). Это типичная структура, которую вы увидите при инспекции реального файла через pyarrow.parquet.read_metadata().

Кликайте на Row Groups и Column Chunks, чтобы раскрыть их содержимое.

Интерактивный Parquet File Viewer
PAR1Magic number (4 bytes: 0x50 0x41 0x52 0x31)
File:version:v2rows:200,000row groups:2size:3.8 MB
schema:user_id: INT64username: BYTE_ARRAY (UTF8)score: DOUBLE
parquet-rs version 53.4.0
File Metadata (Thrift)offset:0x3C4004length:4.0 KB
Metadata Length: 4096 (4 bytes LE)
PAR1
Кликните для раскрытия:● Row Group● Column Chunk● Data Page● Dictionary Page

Как читать viewer

Уровень файла

Верхний блок — файловые метаданные. Здесь вы видите:

  • PAR1 — 4-байтовая магическая сигнатура в начале и конце файла
  • version — версия формата Parquet (v2 = поддержка Data Page V2, ColumnIndex)
  • rows — общее количество строк в файле
  • schema — типы колонок в Thrift-нотации
Что reader читает первым

Конец файла: PAR1 + metadata length

Reader начинает с конца файла. Читает последние 8 байт: 4 байта metadata length + 4 байта PAR1. Это даёт offset footer.

Footer: FileMetaData (Thrift)

По metadata length reader вычисляет offset и читает Thrift-сериализованный FileMetaData. Это единственный I/O для метаданных — один запрос.

Планирование чтения: какие chunks читать

Из FileMetaData reader узнаёт: количество row groups, offset каждого column chunk, схему, статистики. Всё остальное — point reads по offset.

Уровень Row Group

Раскройте Row Group в viewer. Вы увидите:

  • rows — количество строк в этой группе (100 000)
  • size — общий размер несжатых данных (2.5 MB)
  • columns — количество column chunks (3 — по одному на колонку)

Каждый row group содержит полный набор column chunks для своего диапазона строк.

Уровень Column Chunk

Раскройте любой column chunk. Обратите внимание:

  • offset — позиция в файле в hex (например, 0x4 = 4 байта от начала). Это byte offset, по которому reader находит данные
  • comp — сжатый размер. Сравните с ratio — это коэффициент сжатия (raw / compressed)
  • min/max — chunk-level статистики для predicate pushdown
  • enc — используемые кодировки (RLE_DICTIONARY + PLAIN для user_id, BYTE_STREAM_SPLIT для score)
  • nulls — количество null-значений (username имеет 12 null в Row Group 0)
Что говорят byte offsets
user_id chunk (RG 0)Offset 0x4 — сразу после PAR1 (4 байта). Это первый column chunk в файле. Сжат с 800 KB до 403 KB (ratio 1.9×).
username chunk (RG 0)Offset 0x41F04 — сразу после user_id chunk. Chunks идут последовательно внутри row group. Строковые данные сжимаются хуже — ratio 1.5×.
score chunk (RG 0)Offset 0x142184 — после username chunk. BYTE_STREAM_SPLIT encoding для float/double — разделяет байты значения по потокам, улучшая сжатие.

Уровень Page

Раскройте column chunk дальше — вы увидите отдельные страницы:

  • DICTIONARY — словарная страница (если кодировка RLE_DICTIONARY). Всегда первая в chunk. Содержит уникальные значения
  • DATA_PAGE_V2 — страницы данных. Каждая содержит закодированные значения для порции строк
  • min/max на каждой data page — это page-level статистики из ColumnIndex
TIP

Обратите внимание: колонка score (DOUBLE) не имеет dictionary page — она использует BYTE_STREAM_SPLIT, который кодирует float/double напрямую без словаря. А user_id и username начинаются с DICTIONARY_PAGE, за которой следуют DATA_PAGE_V2 с индексами в словарь.

Инспекция реального файла

В viewer мы используем захардкоженные данные. В реальной работе вы будете инспектировать файлы через PyArrow:

import pyarrow.parquet as pq

# Метаданные файла
meta = pq.read_metadata('users.parquet')
print(f"Rows: {meta.num_rows}")
print(f"Row groups: {meta.num_row_groups}")
print(f"Format: {meta.format_version}")
print(f"Created by: {meta.created_by}")

# Метаданные row group
rg = meta.row_group(0)
print(f"RG 0: {rg.num_rows} rows, {rg.total_byte_size} bytes")

# Метаданные column chunk
col = rg.column(0)
print(f"Column: {col.path_in_schema}")
print(f"Codec: {col.compression}")
print(f"Encodings: {col.encodings}")
print(f"Stats: min={col.statistics.min}, max={col.statistics.max}")
print(f"Nulls: {col.statistics.null_count}")
PyArrow metadata API: навигация по уровням
pq.read_metadata('file.parquet')pq.read_metadata() читает только footer файла — не загружает данные. На S3 это один Range Read последних ~8 KB.

FileMetaData

FileMetaData объект. .num_rows, .num_row_groups, .schema, .format_version, .created_by, .serialized_size, .metadata (key-value)
meta.row_group(i) → RowGroupMetaData.row_group(i) возвращает RowGroupMetaData. .num_rows, .total_byte_size, .num_columns — описание одной горизонтальной порции.
rg.column(j) → ColumnChunkMetaData.column(j) возвращает ColumnChunkMetaData. .path_in_schema, .compression, .encodings, .statistics (min, max, null_count, distinct_count), .total_compressed_size
NOTE

pq.read_metadata() не загружает данные — только footer. Это единственный I/O, необходимый для инспекции файла. На S3/GCS это один Range Read. Для быстрой проверки структуры файла в production — это штатный инструмент.

Паттерны для инспекции

ЗадачаКоманда / API
Размер row groupsmeta.row_group(i).total_byte_size
Кодировки колонкиrg.column(j).encodings
Статистики для pruningrg.column(j).statistics.min / .max
Null countrg.column(j).statistics.null_count
Compression ratiocompressed_size / uncompressed_size
Схема файлаpf = pq.ParquetFile('f.parquet'); pf.schema_arrow

Ключевые выводы

  1. Viewer показывает все уровни одновременно: File → Row Groups → Column Chunks → Pages с byte offsets и статистиками
  2. Byte offsets — ключ к пониманию физического layout: chunks идут последовательно, каждый начинается по offset из metadata
  3. Compression ratio сильно зависит от типа данных: INT64 (1.9×), strings (1.5×), DOUBLE с BYTE_STREAM_SPLIT (1.2×)
  4. Dictionary vs no dictionary: integer и string колонки с low cardinality используют RLE_DICTIONARY, float/double — BYTE_STREAM_SPLIT
  5. В реальной работе используйте pq.read_metadata() — один I/O вызов для полной инспекции структуры файла

Проверьте понимание

Результат: 0 из 0
Прикладной
Вопрос 1 из 4. При инспекции Parquet-файла через PyArrow: `pf = pq.ParquetFile('data.parquet'); meta = pf.metadata`. Поле `meta.num_row_groups` = 4, `meta.num_columns` = 10. Сколько column chunks содержит файл?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 7