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

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

Проверка обоих паркетных файлов-

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

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

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 КБ?

1 Ответ

0 голосов
/ 30 октября 2018

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 000 идентичных записей, выигрыш будет огромным, поскольку при кодировании словаря RLE каждое значение столбца нужно будет сохранять только один раз, а затем помечать как повторяющиеся 150 000 раз.

Однако кажется, что 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.

...