Раздел 38 · ClickHouse и аналитические базы

Сжатие данных

junior~15 мин

без входаВойди, чтобы отмечать прогресс, вести заметки и решать задачи в редакторе. войти

В уроке про колоночное хранение мы обещали вернуться к сжатию. Пора. Сжатие в ClickHouse это не приятная мелочь, а половина скорости: с диска читаются сжатые байты, и чем их меньше, тем быстрее запрос. Бывает, что таблица на терабайт в ClickHouse занимает сто гигабайт.

Почему колонки жмутся хорошо

Возьми колонку kind таблицы событий: open, open, search, open, order, pay, open, ... Пять разных слов на сотни тысяч строк. Или колонку ts: время только растёт, соседние значения отличаются на секунды. В строке PostgreSQL рядом лежат число, строка, дата и цена, повторов почти нет. А в колонке повторы и закономерности на каждом шагу.

Алгоритм сжатия ищет такие повторы и записывает их короче. Похоже на то, как ты пишешь в списке покупок «яйца ×10», а не «яйца, яйца, яйца…».

Кодеки

Способ сжатия колонки в ClickHouse называется кодеком. Его задают в описании колонки:

CREATE TABLE events_codecs (
    ts DateTime CODEC(Delta, ZSTD),
    user_id UInt32 CODEC(ZSTD(3)),
    kind LowCardinality(String),
    duration_ms UInt32 CODEC(T64, LZ4)
) ...

Кодеки бывают двух видов.

Сжимающие работают с любыми байтами:

  • LZ4 стоит по умолчанию. Очень быстрый, сжимает средне;
  • ZSTD сжимает сильнее, но медленнее. ZSTD(1) быстрее, ZSTD(9) сильнее. Хорош для старых редко читаемых данных и для текстов.

Преобразующие не сжимают сами, а готовят данные, чтобы их лучше сжал следующий кодек в цепочке:

  • Delta хранит не значения, а разницы между соседними. Время 09:00:01, 09:00:03, 09:00:04 превращается в 09:00:01, 2, 1: маленькие числа сжимаются отлично. Подходит для отсортированных дат и счётчиков;
  • DoubleDelta хранит разницу разниц. Идеален для меток времени с ровным шагом: при шаге ровно в секунду почти всё становится нулями;
  • Gorilla для дробных чисел, которые меняются плавно: температура, загрузка процессора;
  • T64 обрезает лишние старшие нули у целых чисел, если значения маленькие для своего типа.

Ещё один приём ты уже знаешь: LowCardinality(String) хранит словарь и номера, это тоже сжатие, и очень эффективное.

урок из курса

Урок из курса «ClickHouse и аналитические базы». Курс покупается один раз и остаётся навсегда: 500 ₽.

Оплата пока не подключена: премиум и курсы открываются промокодом.