Этот репозиторий содержит спецификацию определений Apache Parquet и Apache Thrift для чтения и записи метаданных Parquet.
Apache Parquet — это формат файлов данных с открытым исходным кодом, ориентированный на столбцы, предназначенный для эффективного хранения и извлечения данных. Он обеспечивает высокопроизводительные схемы сжатия и кодирования для массовой обработки сложных данных и поддерживается во многих языках программирования и аналитических инструментах.
Мы создали Parquet, чтобы сделать преимущества сжатого и эффективного представления данных в виде столбцов доступными для любого проекта в экосистеме Hadoop.
Parquet создается с нуля с учетом сложных вложенных структур данных и использует алгоритм уничтожения и сборки записей, описанный в статье Dremel. Мы считаем, что этот подход превосходит простое выравнивание вложенных пространств имен.
Parquet создан для поддержки очень эффективных схем сжатия и кодирования. Несколько проектов продемонстрировали влияние на производительность применения правильной схемы сжатия и кодирования данных. Parquet позволяет указывать схемы сжатия на уровне каждого столбца и ориентирован на будущее, позволяя добавлять больше кодировок по мере их изобретения и реализации.
Паркет создан для того, чтобы им мог пользоваться каждый. Экосистема Hadoop богата платформами обработки данных, и мы не заинтересованы в том, чтобы выбирать фаворитов. Мы считаем, что эффективная, хорошо реализованная подложка столбчатого хранилища должна быть полезна для всех платформ без затрат на обширные и сложные в настройке зависимости.
Проект parquet-format
содержит спецификации формата и определения метаданных Thrift, необходимые для правильного чтения файлов Parquet.
Проект parquet-java
содержит несколько подмодулей, которые реализуют основные компоненты чтения и записи вложенного столбцово-ориентированного потока данных, сопоставляют это ядро с форматом паркета и предоставляют форматы ввода/вывода Hadoop, загрузчики Pig и другие Java-утилиты для взаимодействия с Parquet.
Проект parquet-compatibility
содержит тесты совместимости, которые можно использовать для проверки того, что реализации на разных языках могут читать и записывать файлы друг друга.
Ресурсы Java можно собрать с помощью mvn package
. Текущая стабильная версия всегда должна быть доступна на Maven Central.
Экономичные ресурсы C++ можно создавать с помощью make.
Thrift также можно сгенерировать кодом на любом другом языке, поддерживающем thrift.
Блок (блок HDFS): это означает блок в HDFS, и значение для описания этого формата файла остается неизменным. Формат файла разработан для хорошей работы поверх HDFS.
Файл: файл HDFS, который должен включать метаданные файла. Он не обязательно должен содержать данные.
Группа строк: логическое горизонтальное разделение данных на строки. Для группы строк не существует гарантированной физической структуры. Группа строк состоит из фрагмента столбца для каждого столбца в наборе данных.
Кусок столбца: фрагмент данных для определенного столбца. Они находятся в определенной группе строк и гарантированно будут смежными в файле.
Страница: фрагменты столбцов разделены на страницы. Страница концептуально представляет собой неделимую единицу (с точки зрения сжатия и кодирования). Может быть несколько типов страниц, которые чередуются в фрагменте столбца.
Иерархически файл состоит из одной или нескольких групп строк. Группа строк содержит ровно один фрагмент столбца на каждый столбец. Фрагменты столбцов содержат одну или несколько страниц.
Этот файл и определение Thrift следует читать вместе, чтобы понять формат.
4-byte magic number "PAR1"
<Column 1 Chunk 1>
<Column 2 Chunk 1>
...
<Column N Chunk 1>
<Column 1 Chunk 2>
<Column 2 Chunk 2>
...
<Column N Chunk 2>
...
<Column 1 Chunk M>
<Column 2 Chunk M>
...
<Column N Chunk M>
File Metadata
4-byte length in bytes of file metadata (little endian)
4-byte magic number "PAR1"
В приведенном выше примере в этой таблице есть N столбцов, разделенных на M групп строк. Метаданные файла содержат местоположения всех начальных положений фрагментов столбцов. Более подробную информацию о том, что содержится в метаданных, можно найти в определении Thrift.
Метаданные файла записываются после данных, чтобы обеспечить возможность записи за один проход.
Предполагается, что читатели сначала прочитают метаданные файла, чтобы найти все интересующие их фрагменты столбцов. Затем фрагменты столбцов следует читать последовательно.
Существует два типа метаданных: метаданные файла и метаданные заголовка страницы. Все сберегательные структуры сериализуются с использованием TCompactProtocol.
Типы, поддерживаемые форматом файла, должны быть минимально возможными, с упором на то, как эти типы влияют на дисковое пространство. Например, 16-битные целые числа явно не поддерживаются в формате хранения, поскольку они покрываются 32-битными целыми числами с эффективной кодировкой. Это снижает сложность реализации устройств чтения и записи для этого формата. Типы:
Логические типы используются для расширения типов, которые можно использовать для хранения паркета, путем указания того, как следует интерпретировать примитивные типы. Это сводит к минимуму набор примитивных типов и повторно использует эффективные кодировки паркета. Например, строки хранятся с примитивным типом BYTE_ARRAY с аннотацией STRING. Эти аннотации определяют, как дальше декодировать и интерпретировать данные. Аннотации хранятся в виде полей LogicalType
в метаданных файла и документируются в LogicalTypes.md.
Parquet хранит минимальную/максимальную статистику на нескольких уровнях (например, фрагмент столбца, индекс столбца и страница данных). Сравнение значений типа подчиняется следующим правилам:
Каждый логический тип имеет определенный порядок сравнения. Если столбец помечен неизвестным логическим типом, статистика не может использоваться для сокращения данных. Порядок сортировки логических типов описан на странице LogicalTypes.md.
Для примитивных типов применяются следующие правила:
BOOLEAN – ложь, правда
INT32, INT64 — Знаковое сравнение.
FLOAT, DOUBLE — сравнение знаков со специальной обработкой чисел NaN и нулей со знаком. Подробности описаны в определении Thrift в объединении ColumnOrder
. Они кратко изложены здесь, но авторитетным считается определение бережливости:
+0.0
.-0.0
.Для обратной совместимости при чтении файлов:
BYTE_ARRAY и FIXED_LEN_BYTE_ARRAY — лексикографическое беззнаковое побайтовое сравнение.
Для кодирования вложенных столбцов Parquet использует кодировку Dremel с уровнями определения и повторения. Уровни определения определяют, сколько дополнительных полей в пути к столбцу определено. Уровни повторения указывают, в каком повторяющемся поле пути повторяется значение. Максимальные уровни определения и повторения можно вычислить из схемы (т.е. степень вложенности). Это определяет максимальное количество битов, необходимое для хранения уровней (уровни определяются для всех значений в столбце).
Поддерживаются две кодировки уровней BIT_PACKED и RLE. Теперь используется только RLE, поскольку он заменяет BIT_PACKED.
Недействительность кодируется на уровнях определения (которые кодируются по длине). Значения NULL не кодируются в данных. Например, в невложенной схеме столбец с 1000 значениями NULL будет закодирован с помощью кодирования длины серии (0, 1000 раз) для уровней определения и ничего больше.
Для страниц данных три фрагмента информации кодируются последовательно после заголовка страницы. На странице данных не допускается заполнение. По порядку у нас есть:
Значение uncompressed_page_size
, указанное в заголовке, относится ко всем трем частям вместе взятым.
Закодированные значения для страницы данных требуются всегда. Уровни определения и повторения являются необязательными и зависят от определения схемы. Если столбец не является вложенным (т.е. путь к столбцу имеет длину 1), мы не кодируем уровни повторения (он всегда будет иметь значение 1). Для необходимых данных уровни определения пропускаются (если они закодированы, они всегда будут иметь значение максимального уровня определения).
Например, в случае, когда столбец не является вложенным и является обязательным, данные на странице представляют собой только закодированные значения.
Поддерживаемые кодировки описаны в Encodings.md.
Поддерживаемые кодеки сжатия описаны в Compression.md.
Фрагменты столбцов состоят из страниц, записанных одна за другой. Страницы имеют общий заголовок, и читатели могут пропускать страницы, которые им не интересны. Данные страницы следуют за заголовком и могут быть сжаты и/или закодированы. Сжатие и кодировка указаны в метаданных страницы.
Фрагмент столбца может быть частично или полностью закодирован по словарю. Это означает, что индексы словаря сохраняются на страницах данных вместо фактических значений. Фактические значения хранятся на странице словаря. Подробности смотрите в Encodings.md. Страница словаря должна быть размещена в первой позиции фрагмента столбца. В фрагмент столбца можно поместить не более одной страницы словаря.
Кроме того, файлы могут содержать дополнительный индекс столбца, позволяющий читателям более эффективно пропускать страницы. Подробности и причины добавления их в формат см. на странице PageIndex.md.
Страницы всех типов могут иметь индивидуальную контрольную сумму. Это позволяет отключить контрольные суммы на уровне файла HDFS, чтобы лучше поддерживать поиск по одной строке. Контрольные суммы вычисляются с использованием стандартного алгоритма CRC32, который используется, например, в GZip, для сериализованного двоичного представления страницы (не включая сам заголовок страницы).
Если метаданные файла повреждены, файл будет потерян. Если метаданные столбца повреждены, этот фрагмент столбца будет потерян (но фрагменты столбца для этого столбца в других группах строк в порядке). Если заголовок страницы поврежден, остальные страницы этого фрагмента будут потеряны. Если данные на странице повреждены, эта страница будет потеряна. Файл будет более устойчив к повреждению при использовании меньших групп строк.
Возможное расширение: при небольших группах строк самая большая проблема — размещение метаданных файла в конце. Если при записи метаданных файла произойдет ошибка, все записанные данные будут нечитабельны. Это можно исправить, записав метаданные файла в каждую N-ю группу строк. Метаданные каждого файла будут накопительными и будут включать все записанные на данный момент группы строк. Объединив это со стратегией, используемой для файлов rc или avro с использованием маркеров синхронизации, программа чтения может восстановить частично записанные файлы.
Формат специально разработан для отделения метаданных от данных. Это позволяет разбивать столбцы на несколько файлов, а также иметь один файл метаданных, ссылающийся на несколько файлов паркета.
В формате много мест для совместимых расширений:
Parquet Thrift IDL резервирует идентификатор поля 32767
каждой структуры Thrift для расширений. Тип (Бережливость) этого поля всегда является binary
.
Apache/parquet-testing содержит набор файлов Parquet для целей тестирования.
Прокомментируйте проблему и/или свяжитесь со списком рассылки parquet-dev со своими вопросами и идеями. Изменения в этом базовом определении формата предлагаются и подробно обсуждаются в списке рассылки. Вас также может заинтересовать участие в подпроекте Parquet-Java, который содержит все реализации и API на стороне Java. См. раздел «Как внести свой вклад» проекта Parquet-Java.
Мы придерживаемся и сообщества разработчиков Parquet кодекса поведения, описанного Twitter OSS: https://github.com/twitter/code-of-conduct/blob/master/code-of-conduct.md.
Авторские права принадлежат Twitter, Cloudera и другим участникам, 2013 г.
Лицензия Apache, версия 2.0: http://www.apache.org/licenses/LICENSE-2.0.