Классическое хранение данных в ClickHouse

Как настроить гибридное хранилище ClickHouse. Пример KazanExpress
Рассказываем про гибридное хранилище ClickHouse, особенности работы с ним и как настроить такое хранилище на примере компании KazanExpress.
Гибридное хранилище позволяет хранить часто используемые данные на сетевых дисках кластера Managed Service for ClickHouse, а редко используемые — в Yandex Object Storage.
ClickHouse позволяет собирать данные и создавать витрины данных. Пользователи получают безопасный доступ к той информации, которая им нужна, и могут ей делиться. Однако хранить много сырых данных в базе — это обычно дорогое удовольствие. Поэтому в современных облачных платформах используется такая важная внешняя система, как объектное хранилище. Во‑первых, в нём могут храниться необработанные данные (т. е. озеро данных), которые импортируются из других систем или экспортируются в них. Во‑вторых, это дешёвое и надёжное хранилище для табличных данных.


Гибридное хранилище данных
Автоматическое перемещение данных между этими уровнями хранения поддерживается только для таблиц семейства MergeTree.
В этой статье мы расскажем:
Как работает гибридное хранилище
Гибридное хранилище позволяет подключить для кластера ClickHouse S3‑бакет и хранить там практически неограниченное количество данных. Для пользователя различия между локальным диском и S3‑хранилищем в общем случае заключаются только в скорости чтения архивных данных.
Для начала объясним, как хранятся данные в таблицах семейства MergeTree. В ClickHouse данные разбиваются на разделы (partition
), а способ разбиения задаёт пользователь в свойствах таблицы. Каждый раздел состоит из частей (part
) — неизменяемого набора файлов с данными, для которого генерируется уникальный ключ и имя.
Для локального диска part
— это каталог с файлами. Гибридное хранилище подразумевает, что есть и локальный, и S3‑диск. Сперва новые данные записываются на локальный диск, все операции с ними происходят так, как описано выше. А позже данные при каких‑то условиях (TTL, заполненность локального диска, ручное перемещение) переезжают на S3. Чтобы ClickHouse воспринимала S3‑хранилище как локальный диск, была написана прослойка, обеспечивающая одинаковый интерфейс и для локальных, и для удалённых дисков.
Гибридное хранилище позволяет намного проще масштабироваться. Например, когда в обычный ClickHouse‑кластер добавляется ещё одна реплика, в неё копируются все данные существующей реплики. Если хранилище гибридное — в новую реплику копируются только часто используемые данные с сетевых дисков. А всё, что находится в Yandex Object Storage, не копируется.
Особенности работы с гибридным хранилищем
move_factor
При использовании гибридного хранилища включается настройка move_factor
, которая определяет долю необходимого свободного места на горячем диске. Если места мало — данные перемещаются в холодное хранилище, пока доля свободного места на диске не сравняется с move_factor
. В холодное хранилище может уехать и вся таблица. Данные не потеряются, но будут доступны только со скоростью холодного хранилища.
Например, если move_factor = 10%
, то для диска в 2 ТБ ClickHouse будет поддерживать 200 ГБ свободного пространства. Если вы настраиваете TTL и ожидаете, что на локальном диске будет 1,9 ТБ, то ClickHouse начнёт уносить данные в холодное хранилище до окончания условия в TTL, что может быть неожиданно.
Куски данных на разных дисках
Помните о том, что минимальная перемещаемая единица для MergeTree — кусок данных (data part
). Данные одного куска могут находится только на одном диске. Если ваш ключ партиционирования (PARTITION BY
) больше условия времени в TTL, то ClickHouse попытается слить куски данных в одной партиции, но на разных дисках. Для такой операции ClickHouse переместит кусок данных из холодного (S3) в горячее (локальный диск), произведёт слияние, а позже унесёт этот кусок в холодное. Регулярно перемещать куски между дисками — это дорого, такая операция необоснованно нагрузит кластер. Поэтому стоит избегать ситуаций, когда что‑то дописывается в партиции, уже перенесённые в холодное хранилище.
Yandex Object Storage
Гибридное хранилище на примере KazanExpress
KazanExpress — маркетплейс с бесплатной доставкой заказов за один день. Маркетплейс работает в 119 городах России, постоянно расширяется и уже собрал более 5 миллионов пользователей. Система аналитики событий на сайте и в мобильных приложениях KazanExpress полностью построена на управляемых сервисах Yandex Cloud, а Managed Service for ClickHouse применяется для хранения и обработки большого количества данных. Компания растёт ежегодно на 800%, соответственно, увеличиваются и объёмы информации, и стоимость её хранения в горячем хранилище.
Инженеры KazanExpress рассчитали несколько вариантов, как решить задачу хранения данных:
-
Удаление всех данных, которые не вмещаются на дисках.
-
Вертикальное масштабирование.
-
Горизонтальное масштабирование.
-
Архивирование данных во внешнем хранилище.
-
Гибридное хранилище.
Удалять ценные ассеты данных было нельзя, и первое время команда KazanExpress двигалась по пути вертикального масштабирования диска. Однако было посчитано, что для Managed Service for ClickHouse с одним шардом из двух реплик, где оригинальное хранилище состоит из 1 ТБ и каждый месяц добавляется 1 ТБ данных, стоимость хранения данных за год превысит 2 млн рублей.
Для горизонтального масштабирования пришлось бы изменить схему хранения данных. Это требовало больших ресурсов команды и адаптации схемы. Чтобы архивировать данные во внешнем хранилище — требовалось написать архиватор и адаптировать запросы к слою холодного хранения. Оба варианта не подходили, так как пришлось бы потратить очень много времени и даже отойти от концепции использования управляемых облачных сервисов.
Гибридное хранилище при тех же вводных обошлось бы примерно в 300 тыс. рублей в год. Экономия по сравнению с вертикальным масштабированием достигала 650%. Решили использовать этот вариант.
Managed Service for ClickHouse
«ClickHouse скрывает детали хранения от потребителей данных и позволяет делать как редкие запросы к холодным данным, так и частые запросы к горячим данным через единый интерфейс. Единый интерфейс делает доступ к данным удобным, а онбординг и поддержку пользователей простыми».
Как изменяется процесс создания таблицы
Добавить гибридное хранилище очень просто. Сначала в Yandex Cloud в настройках кластера включите Использовать гибридное хранилище, по умолчанию эта опция выключена. Затем:
Для существующей таблицы
Чтобы ClickHouse перенесла старые данные в холодное хранилище, добавьте к таблице TTL‑условие с помощью ALTER TABLE xxx MODIFY TTL
, где ххх — это параметры TTL.
ALTER TABLE clickstream.events
MODIFY TTL event_time + INTERVAL 60 DAY TO DISK 'object_storage';
Для новой таблицы
При создании таблицы укажите TTL xxx TO DISK 'object_storage'
, где ххх — это параметры TTL.
Без гибридного хранилища:
CREATE TABLE clickstream.events
(
`user_id` UUID,
`event_id` UUID,
`session_id` UUID,
`event_time` DateTime CODEC(Delta(4), LZ4),
`event_type` LowCardinality(String)
)
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/clickstream/events', '{replica}')
PARTITION BY toYYYYMM(event_time)
ORDER BY (event_type, event_time)
В данном примере партицирование происходит по месяцам. Если планируется перенос данных с диска на диск, то лучше делать более мелкие партиции, например по дням. Если вы не укажете TTL — данные всё равно будут переноситься в Yandex Object Storage, когда на локальном диске закончится место. Но в этом случае Managed ClickHouse сама выберет, какие части переносить.
В гибридном хранилище добавлена строчка с TTL, которая архивирует данные через 30 дней:
CREATE TABLE clickstream.events
(
`user_id` UUID,
`event_id` UUID,
`session_id` UUID,
`event_time` DateTime CODEC(Delta(4), LZ4),
`event_type` LowCardinality(String)
)
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/clickstream/events', '{replica}')
PARTITION BY toYYYYMM(event_time)
ORDER BY (event_type, event_time)
TTL event_time + toIntervalDay(30) TO DISK 'object_storage'
Как вернуть данные из холодного хранилища — ALTER TABLE, MOVE PARTITION
Иногда нужно проанализировать данные из кусков в холодном хранилище. Партиции и куски данных можно перемещать между дисками с помощью запросов ALTER TABLE... MOVE PARTITION
.
Например, компания хочет изучить январские паттерны поведения пользователя перед новым январём. Тогда достаточно вызвать ALTER TABLE events MOVE PARTITION '2022-01-01' TO DISK 'default'
, предварительно убедившись, что на горячем диске достаточно места для хранения. После перемещения партиции (можно мониторить прогресс с помощью SELECT * FROM system.mutations where not is_done;
или SELECT * FROM [system.parts](http://system.parts) where partition = '2022-01-01' and table = 'events')
запросы снова будут идти к данным на горячем диске и выполнятся быстро.
Результаты — как изменяется скорость запросов
Managed ClickHouse перемещает данные, только когда устаревают все данные в куске.
Вот пример с количеством уникальных пользователей Android за последнюю неделю. Данные лежат в горячем хранилище:
-- execution: 6 s 368 ms
SELECT uniq(user_id) as weekly_users
FROM events
WHERE event_time > now()- INTERVAL 1 WEEK
AND platform = 'ANDROID';
В первую неделю 2022 года данные лежат в холодном хранилище:
-- execution: 50 s 223 ms
SELECT uniq(user_id) as weekly_users
FROM events
WHERE event_time BETWEEN toDate('2022-01-01') AND toDate('2022-01-07')
AND platform = 'ANDROID';
Скорость исполнения запроса изменилась примерно в восемь раз.
Или пример с количеством просмотров товаров за последнюю неделю.
Данные в горячем хранилище:
-- execution: 518 ms
SELECT count() product_views
FROM events
WHERE event_time > now()- INTERVAL 1 WEEK and event_type = 'PRODUCT_VIEW';
В первую неделю 2022 года данные лежат в холодном хранилище:
-- execution: 5 s 147 ms
SELECT count() product_views
FROM events
WHERE event_time BETWEEN toDate('2022-01-07') AND toDate('2022-01-14')
and event_type = 'PRODUCT_VIEW';
Скорость исполнения запроса изменилась примерно в девять раз.
С версии ClickHouse 22.3, которая доступна в управляемом сервисе, появилась возможность использовать локальный кеш для S3‑диска. Планируется добавить поддержку в API/UI. Всё это значительно увеличит скорость запросов.
Постройте своё гибридное хранилище на сетевых дисках кластера Managed Service for ClickHouse.