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

Сжатие в ClickHouse

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

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