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