Переразбиение сгенерированных паркетов parquet-mr с помощью pyarrow / parquet-cpp увеличивает размер файла в 30 раз?

Используя AWS Firehose, конвертирую входящие записи в паркет. В одном примере у меня есть 150 тысяч идентичных записей, поступающих в пожарный шланг, и один паркет размером 30 килобайт записывается в s3. Из-за того, как firehose разделяет данные, у нас есть вторичный процесс (лямбда, запускаемый событием s3 put), читаемый в паркете и перераспределяющий его на основе даты в самом событии. После этого процесса перераспределения размер файла с 30 КБ увеличивается до 900 КБ.

Осмотр обеих паркетных пилок.

  • Мета не меняется
  • Данные не меняются
  • Оба они используют сжатие SNAPPY.
  • Паркет пожарного шланга создается parquet-mr, паркет Pyarrow создается parquet-cpp.
  • Паркет, сгенерированный pyarrow, имеет дополнительные заголовки панд

Полный процесс передела-

import pyarrow.parquet as pq

tmp_file = f'{TMP_DIR}/{rand_string()}'
s3_client.download_file(firehose_bucket, key, tmp_file)

pq_table = pq.read_table(tmp_file)

pq.write_to_dataset(
    pq_table,
    local_partitioned_dir,
    partition_cols=['year', 'month', 'day', 'hour'],
    use_deprecated_int96_timestamps=True
)

Я предполагаю, что будут некоторые изменения в размерах, но я был удивлен, обнаружив такую ​​большую разницу. Учитывая описанный мною процесс, что может привести к увеличению размера исходного паркета с 30 до 900 КБ?


person micah    schedule 26.10.2018    source источник
comment
Нам будет сложно сказать почему без воспроизводимого примера. Я не могу придумать причину, почему с ума сойти   -  person Wes McKinney    schedule 26.10.2018
comment
Это могло быть просто из-за количества созданных файлов. Фиксированные накладные расходы на файл Parquet составляют 4 Кбайт +. Когда вы переразбиваете слишком много файлов, это может быть одним из источников.   -  person Uwe L. Korn    schedule 27.10.2018


Ответы (1)


Parquet использует разные кодировки столбцов для очень эффективного хранения данных с низкой энтропией. Например:

  • Он может использовать дельта-кодирование только для хранения различий между значениями. Например, 9192631770, 9192631773, 9192631795, 9192631797 будет эффективно храниться как 9192631770, +3, +12, +2.
  • Он может использовать кодировку словаря для краткого обращения к общим значениям. Например, Los Angeles, Los Angeles, Los Angeles, San Francisco, San Francisco будет сохранен как словарь 0 = Los Angeles, 1 = San Francisco, а ссылки 0, 0, 0, 1, 1
  • Он может использовать кодирование длин серий только для хранения количества повторяющихся значений. Например, Los Angeles, Los Angeles, Los Angeles будет эффективно храниться как Los Angeles×3. (На самом деле, насколько мне известно, в настоящий момент чистый RLE используется только для логических типов, но идея та же.)
  • Комбинация вышеперечисленного, в частности RLE и словарная кодировка. Например, Los Angeles, Los Angeles, Los Angeles, San Francisco, San Francisco будет сохранен как словарь 0 = Los Angeles, 1 = San Francisco, а ссылки 0×3, 1×2

При значениях от 3 до 5 в приведенных выше примерах экономия не так значительна, но чем больше значений у вас есть, тем больше выигрыш. Поскольку у вас есть 150 тыс. Идентичных записей, выигрыш будет огромным, поскольку с кодировкой словаря RLE каждое значение столбца нужно будет сохранить только один раз, а затем пометить как повторяющееся 150 тыс. Раз.

Однако похоже, что pyarrow не использует эти компактные кодировки. Вы можете убедиться в этом, взглянув на метаданные двух файлов с помощью parquet-tools meta. Вот пример вывода:

file schema: hive_schema 
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
id:          OPTIONAL INT32 R:0 D:1
name:        OPTIONAL BINARY O:UTF8 R:0 D:1

row group 1: RC:61 TS:214 OFFSET:4 
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
id:           INT32 UNCOMPRESSED DO:0 FPO:4 SZ:107/107/1.00 VC:61 ENC:BIT_PACKED,RLE,PLAIN_DICTIONARY ST:[min: 1, max: 5, num_nulls: 0]
name:         BINARY UNCOMPRESSED DO:0 FPO:111 SZ:107/107/1.00 VC:61 ENC:BIT_PACKED,RLE,PLAIN_DICTIONARY ST:[min: Los Angeles, max: San Francisco, num_nulls: 0]

Кодировка отображается как ENC:BIT_PACKED,RLE,PLAIN_DICTIONARY.

person Zoltan    schedule 30.10.2018
comment
В этом есть смысл - спасибо! Однако в этом примере это только попытка перераспределения. В результате данные не разделяются. 1 файл - ›Переразбивка -› 1 файл. Значит, где-то в процессе передела он сжимается неэффективно? - person micah; 30.10.2018
comment
Хм, действительно, при идентичных записях раздел будет таким же, я должен был это понимать. :) В этом случае я могу только предположить, что pyarrow по какой-то причине не использовал или не может использовать какие-либо из этих компактных кодировок. Не могли бы вы опубликовать результат parquet-tools meta для обоих файлов? Я ожидаю увидеть разные кодировки для двух файлов. - person Zoltan; 30.10.2018
comment
Вы были правы насчет метода сжатия. Pandas в настоящее время не поддерживает и, возможно, никогда не будет поддерживать такой вид сжатия. Поэтому, если у вас есть 1000 значений NULL, pandas фактически заполнит 1000 значений NULL вместо того, чтобы отмечать следующие 1000 значений NULL. - person micah; 20.11.2018
comment
То, что я написал, в основном применимо к обычным значениям, поскольку значения NULL обрабатываются несколько особым образом. Тем не менее, отсутствие поддержки некоторых кодировок, безусловно, может увеличить размер файлов. - person Zoltan; 21.11.2018
comment
Надеюсь, это не звучало так, как будто это вам противоречило. Значения NULL обрабатываются специально в файлах паркета. Но библиотека pandas не использует это в своей реализации паркета, что приводит к гораздо большему размеру файла после входа и выхода pandas. - person micah; 21.11.2018
comment
Нет, я просто хотел указать на дополнительную сложность в том, что значения NULL обрабатываются по-другому. - person Zoltan; 21.11.2018