Перейти к основному содержимому
Перейти к основному содержимому

Сжатие в ClickHouse

Одним из секретов производительности запросов в ClickHouse является сжатие.

Меньше данных на диске означает меньше I/O и более быстрые запросы и вставки. В большинстве случаев накладные расходы любого алгоритма сжатия по отношению к 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 улучшает ZSTDZSTD является эффективным кодеком для дельта-данных - наоборот, кодирование дельты может улучшить сжатие ZSTD. В присутствии ZSTD другие кодеки редко предлагают дальнейшие улучшения.
LZ4 вместо ZSTD, если возможноЕсли вы получаете сопоставимое сжатие между LZ4 и ZSTD, отдавайте предпочтение первому, так как он предлагает более быстрое разжатие и требует меньше CPU. Однако, в большинстве случаев, ZSTD существенно превосходит LZ4. Некоторые из этих кодеков могут работать быстрее в сочетании с LZ4, сохраняя при этом схожее сжатие по сравнению с ZSTD без кодека. Однако это будет зависеть от данных и требует тестирования.
T64 для разреженных или небольших диапазоновT64 может быть эффективным при разреженных данных или когда диапазон в блоке мал. Избегайте T64 для случайных чисел.
Gorilla и T64 для неизвестных шаблонов?Если данные имеют неизвестный шаблон, стоит попробовать Gorilla и T64.
Gorilla для данных по измерениямGorilla может быть эффективным для данных с плавающей запятой, специально для представления измерений, т.е. случайных всплесков.

Смотрите здесь для получения дополнительной информации.

Ниже мы задаем кодек Delta для Id, ViewCount и AnswerCount, предполагая, что они будут линейно коррелированы с ключом сортировки и, таким образом, должны извлечь выгоду из кодирования дельты.

Улучшения сжатия для этих колонок показаны ниже:

Сжатие в ClickHouse Cloud

В ClickHouse Cloud по умолчанию используется алгоритм сжатия ZSTD (с значением по умолчанию 1). Хотя скорости сжатия могут варьироваться для этого алгоритма в зависимости от уровня сжатия (выше = медленнее), он имеет преимущество в том, что всегда быстро разжимается (в пределах ~20% вариации) и также использует возможность параллелизации. Наши исторические тесты также показывают, что этот алгоритм часто достаточно эффективен и даже может превзойти LZ4 в сочетании с кодеком. Он эффективен для большинства типов данных и распределений информации и, таким образом, является разумным вариантом общего назначения, в связи с чем наше первоначальное сжатие уже отличное даже без оптимизации.