Сжатие в ClickHouse
Одним из секретов производительности запросов ClickHouse является сжатие.
Меньше данных на диске означает меньше ввода-вывода и более быстрые запросы и вставки. Накладные расходы любого алгоритма сжатия в отношении CPU в большинстве случаев будут компенсированы уменьшением ввода-вывода. Улучшение сжатия данных должно быть первым приоритетом при работе над обеспечением быстрой работы запросов ClickHouse.
Что касается того, почему ClickHouse так хорошо сжимает данные, мы рекомендуем этот артикул. В двух словах, как столбцовая база данных, значения будут записываться в порядке столбцов. Если эти значения отсортированы, одни и те же значения будут рядом друг с другом. Алгоритмы сжатия используют непрерывные шаблоны данных. Сверх того, ClickHouse имеет кодеки и гранулярные типы данных, которые позволяют пользователям дополнительно настраивать методы сжатия.
Сжатие в ClickHouse будет зависеть от трех основных факторов:
- Ключ сортировки
- Типы данных
- Используемые кодеки
Все эти факторы настраиваются через схему.
Выберите правильный тип данных для оптимизации сжатия
Давайте используем набор данных Stack Overflow в качестве примера. Сравним статистику сжатия для следующих схем таблицы posts
:
posts
- несортированная схема без ключа сортировки.posts_v3
- Отсортированная схема с соответствующим типом и размером бит для каждого столбца с ключом сортировки(PostTypeId, toDate(CreationDate), CommentCount)
.
Используя следующие запросы, мы можем измерить текущий сжатый и несжатый размер каждого столбца. Давайте рассмотрим размер начальной оптимизированной схемы posts
без ключа сортировки.
Мы показываем как сжатый, так и несжатый размер здесь. Оба важны. Сжатый размер соответствует тому, что нам нужно будет считать с диска - что мы хотим минимизировать для производительности запросов (и затрат на хранение). Эти данные нужно будет распаковать перед чтением. Размер несжатого размера будет зависеть от используемого типа данных в этом случае. Минимизация этого размера снизит накладные расходы памяти запросов и количество данных, которые необходимо обработать запросом, улучшая использование кешей и, в конечном итоге, время выполнения запросов.
Приведенный выше запрос полагается на таблицу
columns
в системной базе данных. Эта база данных управляется ClickHouse и является кладезем полезной информации, от метрик производительности запросов до фоновых журналов кластера. Мы рекомендуем "Системные таблицы и взгляд внутрь внутренностей ClickHouse" и сопровождающие статьи[1][2] для любопытного читателя.
Чтобы подвести итог общему размеру таблицы, мы можем упростить предыдущий запрос:
Повторив этот запрос для posts_v3
, таблицы с оптимизированным типом и ключом сортировки, мы можем увидеть значительное уменьшение несжатых и сжатых размеров.
Полный разбор столбцов показывает значительную экономию для столбцов Body
, Title
, Tags
и CreationDate
, достигнутую за счет упорядочивания данных до сжатия и использования соответствующих типов.
Выбор правильного кодека для сжатия колонок
С кодеками сжатия колонок мы можем изменить алгоритм (и его настройки), используемый для кодирования и сжатия каждой колонки.
Кодирование и сжатие немного различаются, но с одной и той же целью: уменьшить размер наших данных. Кодирования применяют отображение к нашим данным, преобразуя значения на основе функции с помощью свойств типа данных. Напротив, сжатие использует общий алгоритм для сжатия данных на уровне байтов.
Как правило, кодирования применяются сначала, прежде чем используется сжатие. Поскольку разные кодировки и алгоритмы сжатия эффективны при различных распределениях значений, мы должны понимать наши данные.
ClickHouse поддерживает большое количество кодеков и алгоритмов сжатия. Вот некоторые рекомендации в порядке важности:
Рекомендация | Обоснование |
---|---|
ZSTD лучшее решение | Сжатие ZSTD предлагает лучшие коэффициенты сжатия. ZSTD(1) должен быть значением по умолчанию для большинства обычных типов. Более высокие коэффициенты сжатия можно попробовать, изменив числовое значение. Мы редко видим достаточные преимущества при значениях выше 3 из-за увеличенных затрат на сжатие (замедленная вставка). |
Delta для дат и последовательностей целых чисел | Кодеки на основе Delta хорошо работают, когда у вас есть монотонные последовательности или маленькие дельты в последовательных значениях. Более конкретно, кодек Delta хорошо работает, при условии, что производные дают маленькие числа. Если нет, стоит попробовать DoubleDelta (это обычно добавляет немного, если первая производная от Delta уже очень мала). Последовательности, где монотонное увеличение одинаково, будут сжиматься еще лучше, например, поля DateTime. |
Delta улучшает ZSTD | ZSTD является эффективным кодеком для данных delta - наоборот, кодирование delta может улучшить сжатие ZSTD . В присутствии ZSTD другие кодеки редко предлагают дальнейшее улучшение. |
LZ4 вместо ZSTD , если возможно | если вы получаете сопоставимое сжатие между LZ4 и ZSTD , предпочтение следует отдавать первому, поскольку он обеспечивает более быстрое распаковку и требует меньше CPU. Тем не менее, ZSTD будет значительно превосходить LZ4 в большинстве случаев. Некоторые из этих кодеков могут работать быстрее в сочетании с LZ4 , обеспечивая аналогичное сжатие по сравнению с ZSTD без кодека. Однако это будет зависеть от данных и требует тестирования. |
T64 для разреженных или малых диапазонов | T64 может быть эффективным для разреженных данных или когда диапазон в блоке мал. Избегайте T64 для случайных чисел. |
Gorilla и T64 для未知 шаблонов? | Если данные имеют неизвестный шаблон, возможно, стоит попробовать Gorilla и T64 . |
Gorilla для данных с показателями | Gorilla может быть эффективным для плавающих данных, особенно для данных, представляющих показания инструментов, т.е. случайные выбросы. |
Смотрите здесь для получения дополнительных опций.
Ниже мы указываем кодек Delta
для Id
, ViewCount
и AnswerCount
, предполагая, что они будут линейно связаны с ключом сортировки и, таким образом, должны извлечь выгоду от кодирования Delta.
Улучшения сжатия для этих столбцов показаны ниже:
Сжатие в ClickHouse Cloud
В ClickHouse Cloud по умолчанию используется алгоритм сжатия ZSTD
(с значением по умолчанию 1). Хотя скорость сжатия может варьироваться для этого алгоритма в зависимости от уровня сжатия (выше = медленнее), у него есть преимущество, заключающееся в том, что он постоянно быстр при распаковке (около 20% изменчивости) и также получает выгоду от возможности параллелизации. Наши исторические тесты также показывают, что этот алгоритм часто достаточно эффективен и даже может превзойти LZ4
, комбинированный с кодеком. Он эффективен для большинства типов данных и распределений информации, и поэтому является разумным общим решением по умолчанию, а вот именно поэтому наше начальное сжатие уже отлично, даже без оптимизации.