Как стать автором
Обновить

Погружение в ClickHouse: делаем первые и успешные шаги

Уровень сложностиПростой
Время на прочтение6 мин
Количество просмотров9.8K

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

Пара слов о компании Hybrid. Мы — независимая AdTech-экосистема с собственным стеком технологий и решений для любых рекламных целей. Развиваем собственные технологии благодаря in-house отделу разработки, который каждый день работает над их улучшением. ClickHouse — инструмент, который мы выбираем для хранения данных за высокую скорость обработки запросов, эффективное сжатие данных и масштабируемость.

Введение в ClickHouse

Преимущества

  • Высокая производительность: ClickHouse обрабатывает миллиарды строк данных за считанные секунды, даже для сложных запросов.

  • Колоночное хранение данных: Чтение только необходимых столбцов снижает объем обработанных данных и повышает скорость запросов.

  • Партиционирование и индексация: Логическое разделение данных по партициям (например, по дате) ускоряет поиск.

  • Сжатие данных: Алгоритмы сжатия минимизируют использование дискового пространства, сохраняя производительность.

  • Масштабируемость: Распределенное хранение позволяет ClickHouse работать на кластерах серверов.

Как работает ClickHouse

  • Колоночное хранение: Данные хранятся в столбцах, что позволяет извлекать только нужные поля, что может быть удобно при больших количествах монотонных данных

  • Партиционирование: Данные разделяются на логические блоки (партиции), что ускоряет доступ к информации.

Сценарии использования ClickHouse

  • Аналитика данных в реальном времени: Подходит для обработки потоков данных в режиме реального времени и построения онлайн-дашбордов.

  • Хранение логов и событий: Например, логов веб-серверов или пользовательских действий.

  • Машинное обучение: Поддерживает хранение больших датасетов для обучения моделей.

Интеграция с BI-системами: Работает с инструментами, такими как Grafana или Apache Superset, для визуализации данных.

Как начать работать с ClickHouse

Сначала давайте поговорим как можно поставить Clickhouse, если вы с этим столкнулись в первый раз. 

Для установки на Ubuntu необходимо сделать шаги:

  1. Добавить репозитории и ключи репозитория

sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gnupg

curl -fsSL 'https://packages.clickhouse.com/rpm/lts/repodata/repomd.xml.key' | sudo gpg --dearmor -o /usr/share/keyrings/clickhouse-keyring.gpg

ARCH=$(dpkg --print-architecture)

echo "deb [signed-by=/usr/share/keyrings/clickhouse-keyring.gpg arch=${ARCH}] https://packages.clickhouse.com/deb stable main" | sudo tee /etc/apt/sources.list.d/clickhouse.list
sudo apt-get update

2. Установить Clickhouse

sudo apt-get install clickhouse-server clickhouse-client
sudo systemctl start clickhouse-server

Дизайн таблиц

Теперь когда у нас есть сервер, давайте немного поговорим про таблицы и данные.

Немного поэкспериментируем, чтобы показать, как это работает. Создаем базу данных и переключимся в нее.

CREATE DATABASE webinar;
USE webinar;

Теперь создаем таблицу, которая будет хранить события, происходящие с рекламным баннером:

CREATE TABLE events (
    event_date Date,
    event_time DateTime,
    user_id UInt32,
    event_type String,
    platform String,
    country String
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(event_date)
ORDER BY (event_date, user_id, event_time);

Для вставки данных выполним INSERT запрос c данными в формате JSONEachRow:

INSERT INTO events FORMAT JSONEachRow
{
    "event_date": "2024-01-01",
    "event_time": "2024-01-01 12:00:00",
    "user_id": 12345,
    "event_type": "click",
    "platform": "mobile",
    "country": "US"
}

Чтобы прочитать данные о событиях необходимо выполнить запрос следующего вида:

SELECT
    event_date,
    event_type,
    COUNT(*) AS event_count
FROM events

Однако по мере роста количества данных в таблице, запрос будет становиться все сложнее в обработке. Чтобы в фоне выполнять такие предварительные расчеты можно завести материализованное представление:

CREATE MATERIALIZED VIEW summary_view
ENGINE = SummingMergeTree()
PARTITION BY toYYYYMM(event_date)
ORDER BY (event_date, event_type)
AS
SELECT
    event_date,
    event_type,
    COUNT(*) AS event_count
FROM events
GROUP BY event_date, event_type;

В Hybrid Platform мы практически повсеместно используем материализованные представления для ускорения запросов. Предварительный сбор данных позволяет нам ускорять загрузку статистических данных. 

Недавно мы столкнулись с задачей разделения наших материализованных представлений на таблицу и запрос. Для этого было решено сделать апдейт устаревших настроек, которые нельзя было произвести без замены таблиц.

Опираясь на документацию, наш и индустриальный опыт, мы сделали следующее. Разберем на примере статистики кампаний:

  1. Сначала — самые важные и «грубые» фильтры  

Почти все запросы мы фильтруем по дате. Все записи у нас содержат дату и это довольно низкокардинальные данные (данные с меньшим количеством уникальных значений), а этот столбец отлично подходил на роль первого в ORDER BY.  

ORDER BY (EventDate, ...) 

2. Добавляем чуть более точные фильтры  

Дальше шли project_id и source_id — их кардинальность повыше, но они тоже часто встречались в WHERE. Расположили их по убыванию важности.

Мы посмотрели на запросы из HybridPlatform и на логику интерфейса. У нас довольно часто встречается привязка к TradingDesk и агентству. А следующим большим фильтром является рекламодатель:

ORDER BY (…TradingDeskId, AgencyId, AdvertiserId…)

3. Остались «неохваченные» фильтры — добавляем их

В таблице, которая агрегирует статистику по кампаниям было бы все же неплохо иметь фильтр по этим самым кампаниям, поэтому добавили еще и CampaignId:  

ORDER BY (…CampaignId,…)

4. Улучшаем сжатие за счет похожих данных  

Если строки всё ещё неуникальны, можно добавить что-то вроде user_id или EventName, чтобы похожие данные лежали рядом. Это помогло сжать данные на 20-30% лучше.  

ORDER BY (...EventName, …)

5. Временные ряды: timestamp в конец  

Наша идея была затащить в материализованные представления информацию о времени. Но нас интересовало округленное значение. Мы уже в одном представлении использовали функцию toStartOfHourDate, поэтому решили ее принести и в остальные таблицы для удобства работы. 

ORDER BY (…StartOfHourDate)

Итоговый ORDER BY получился следующий:

ORDER BY (EventDate, TradingDeskId, AgencyId, AdvertiserId, CampaignId, EventName, StartOfHourDate)

На что мы смотрели при выборе столбцов для первичного ключа?

В ClickHouse первичный ключ (PRIMARY KEY) и ORDER BY — это одно и то же. Формально ORDER BY определяет физический порядок хранения данных, а первичный ключ влияет на индексацию.

В отличие от традиционных реляционных баз данных, ClickHouse использует разреженные индексы. Это означает, что вместо индексации каждой строки, ClickHouse группирует строки в гранулы (обычно по 8192 строки) и создает индексные отметки только для первой строки в каждой грануле. Такой подход значительно ускоряет фильтрацию данных, так как бинарный поиск по индексным отметкам требует всего нескольких шагов.

В большинстве случаев роль первичного ключа в ClickHouse выполняет ORDER BY. Однако в MergeTree и его вариациях есть особенности.

В MergeTree PRIMARY KEY можно задать короче, чем ORDER BY.
Если ORDER BY состоит из нескольких столбцов, можно задать PRIMARY KEY, включающий только первые N столбцов. Это уменьшит размер индексов, сохранив эффективность фильтрации.

Чтобы ускорить работу с таблицами выбирайте столбцы с низкой кардинальностью, чтобы ускорить построение индексов. Если первичный ключ не указан, ClickHouse использует для этого ключ сортировки.

Хороший ORDER BY обычно включает 3-5 столбцов, расположенных в порядке увеличения кардинальности: от наименьшей (и самой важной для фильтрации) слева до наибольшей (менее важной для фильтрации) справа.

ClickHouse идеально подходит для хранения и анализа данных из DSP и SSP, через которые проходит огромный поток информации об аукционах, показах и кликах. Он позволяет эффективно собирать, обрабатывать и анализировать эти данные в режиме реального времени.

В компании Hybrid мы выбрали ClickHouse, потому что он обеспечивает:

  • Высокую скорость обработки запросов — критично при работе с большими объемами данных.

  • Эффективное сжатие — позволяет хранить терабайты статистики без избыточных затрат на инфраструктуру.

  • Масштабируемость легко справляется с растущими нагрузками и увеличением количества данных.

Если вы используете наши продукты Hybrid Platform или VOX, то могли видеть статистику в личных кабинетах — она как раз хранится и обрабатывается в ClickHouse. Это позволяет обеспечивать быстрый доступ к данным и детальную аналитику для наших пользователей.

Заключение

Наша команда активно использует ClickHouse для аналитики, ведь он идеально подходит для работы с большими объемами информации в реальном времени. В конце ноября 2024 года я провел вебинар «Быстрое погружение в ClickHouse». Он и послужил в качестве основы для этого материала. Вот ссылки, по которым вы можете ознакомиться с ним подробнее.

Если после вебинара у вас возник дополнительный интерес к Clickhouse, дайте знать об этом в комментариях. Мы открыты к обсуждению новых тем и готовы делиться опытом: будь то успешные кейсы применения инструмента, его интеграция с различными платформами или другие аспекты, которые могут быть полезны вам.

Теги:
Хабы:
+5
Комментарии5

Публикации

Работа

Data Scientist
46 вакансий

Ближайшие события