Я пытаюсь использовать Spark SQL для записи файла parquet
.
По умолчанию Spark SQL поддерживает gzip
, но также поддерживает и другие форматы сжатия, такие как snappy
и lzo
.
В чем разница между этими форматами сжатия?
Я пытаюсь использовать Spark SQL для записи файла parquet
.
По умолчанию Spark SQL поддерживает gzip
, но также поддерживает и другие форматы сжатия, такие как snappy
и lzo
.
В чем разница между этими форматами сжатия?
Просто попробуйте их на своих данных.
lzo и snappy — это быстрые компрессоры и очень быстрые декомпрессоры, но с меньшим сжатием, по сравнению с gzip, который сжимает лучше, но немного медленнее.
Коэффициент сжатия. Сжатие GZIP использует больше ресурсов ЦП, чем Snappy или LZO, но обеспечивает более высокий коэффициент сжатия.
Общее использование: GZip часто является хорошим выбором для холодных данных, к которым обращаются нечасто. Snappy или LZO лучше подходят для горячих данных, к которым часто обращаются.
Snappy часто работает лучше, чем LZO. Стоит запустить тесты, чтобы увидеть, обнаружите ли вы значительную разницу.
Разделение. Если вам нужно, чтобы сжатые данные можно было разделить, форматы BZip2, LZO и Snappy можно разделить, а GZip — нет.
GZIP сжимает данные на 30% больше по сравнению со Snappy и в 2 раза больше использует ЦП при чтении данных GZIP по сравнению с тем, который потребляет данные Snappy.
LZO фокусируется на скорости декомпрессии при низкой загрузке ЦП и более высоком сжатии за счет увеличения ЦП.
Для долгосрочного/статического хранения лучше использовать сжатие GZip.
Используйте Snappy, если вы можете справиться с более высоким использованием диска для повышения производительности (более низкий процессор + Splittable).
Когда Spark по умолчанию переключился с GZIP на Snappy, это было причиной:
Согласно нашим тестам, распаковка gzip выполняется очень медленно (‹ 100 МБ/с), что ограничивает распаковку запросов. Snappy может распаковывать со скоростью ~ 500 МБ/с на одном ядре.
Быстро:
GZIP:
1) http://boristyukin.com/is-snappy-compressed-parquet-file-splittable/
Основываясь на приведенных ниже данных, я бы сказал, что gzip
выигрывает за пределами таких сценариев, как потоковая передача, где важна задержка во время записи.
Важно помнить, что скорость — это, по сути, стоимость вычислений. Однако облачные вычисления — это разовые затраты, а облачное хранилище — постоянные затраты. Компромисс зависит от периода хранения данных.
Проверим скорость и размер больших и малых parquet
файлов в Python.
Результаты (большой файл, 117 МБ):
+----------+----------+--------------------------+
| snappy | gzip | (gzip-snappy)/snappy*100 |
+-------+----------+----------+--------------------------+
| write | 1.62 ms | 7.65 ms | 372% slower |
+-------+----------+----------+--------------------------+
| size | 35484122 | 17269656 | 51% smaller |
+-------+----------+----------+--------------------------+
| read | 973 ms | 1140 ms | 17% slower |
+-------+----------+----------+--------------------------+
Результаты (небольшой файл, 4 КБ, набор данных Iris):
+---------+---------+--------------------------+
| snappy | gzip | (gzip-snappy)/snappy*100 |
+-------+---------+---------+--------------------------+
| write | 1.56 ms | 2.09 ms | 33.9% slower |
+-------+---------+---------+--------------------------+
| size | 6990 | 6647 | 5.2% smaller |
+-------+---------+---------+--------------------------+
| read | 3.22 ms | 3.44 ms | 6.8% slower |
+-------+---------+---------+--------------------------+
small_file.ipynb
import os, sys
import pyarrow
import pandas as pd
import numpy as np
from sklearn.datasets import load_iris
iris = load_iris()
df = pd.DataFrame(
data= np.c_[iris['data'], iris['target']],
columns= iris['feature_names'] + ['target']
)
# ========= WRITE =========
%timeit df.to_parquet(path='iris.parquet.snappy', compression='snappy', engine='pyarrow', index=True)
# 1.56 ms
%timeit df.to_parquet(path='iris.parquet.gzip', compression='snappy', engine='pyarrow', index=True)
# 2.09 ms
# ========= SIZE =========
os.stat('iris.parquet.snappy').st_size
# 6990
os.stat('iris.parquet.gzip').st_size
# 6647
# ========= READ =========
%timeit pd.read_parquet(path='iris.parquet.snappy', engine='pyarrow')
# 3.22 ms
%timeit pd.read_parquet(path='iris.parquet.gzip', engine='pyarrow')
# 3.44 ms
большой_файл.ipynb
import os, sys
import pyarrow
import pandas as pd
df = pd.read_csv('file.csv')
# ========= WRITE =========
%timeit df.to_parquet(path='file.parquet.snappy', compression='snappy', engine='pyarrow', index=True)
# 1.62 s
%timeit df.to_parquet(path='file.parquet.gzip', compression='gzip', engine='pyarrow', index=True)
# 7.65 s
# ========= SIZE =========
os.stat('file.parquet.snappy').st_size
# 35484122
os.stat('file.parquet.gzip').st_size
# 17269656
# ========= READ =========
%timeit pd.read_parquet(path='file.parquet.snappy', engine='pyarrow')
# 973 ms
%timeit pd.read_parquet(path='file.parquet.gzip', engine='pyarrow')
# 1.14 s
Я согласен с 1 ответом(@Mark Adler) и у меня есть некоторая исследовательская информация[1], но я не согласен со вторым ответом(@Garren S)[2]. Возможно, Гаррен неправильно понял вопрос, потому что: [2] Parquet можно разделить со всеми поддерживаемыми кодеками: Разделяется ли сжатый файл Parquet в HDFS для Spark?, Tom White's Hadoop: The Definitive Guide, 4-е издание, Глава 5: ввод-вывод Hadoop, стр. 106. [1] Мои исследования: источник данных - 205 ГБ. Текст (разделенные поля), несжатый. выходные данные:
<!DOCTYPE html>
<html>
<head>
<style>
table,
th,
td {
border: 1px solid black;
border-collapse: collapse;
}
</style>
</head>
<body>
<table style="width:100%">
<tr>
<th></th>
<th>time of computing, hours</th>
<th>volume, GB</th>
</tr>
<tr>
<td>ORC with default codec</td>
<td>3-3,5</td>
<td>12.3</td>
</tr>
<tr>
<td>Parquet with GZIP</td>
<td>3,5-3,7</td>
<td>12.9</td>
</tr>
<tr>
<td>Parquet with SNAPPY</td>
<td>2,5-3,0</td>
<td>60.4</td>
</tr>
</table>
</body>
</html>
Трансформацию проводили с помощью Hive на EMR, состоящем из 2 м4.16xlarge. Преобразование - выделить все поля с упорядочением по нескольким полям. Это исследование, конечно, не стандартное, но хоть немного показывает реальное сравнение. С другими наборами данных и результаты вычислений могут быть другими.