ClickHouse — колонкова СУБД для аналітичних запитів: підрахунок подій, розбір логів, агрегація метрик за тривалі періоди. У каталозі ZevsHost немає окремої статті про неї, хоча питання «куди складати логи і події, щоб не навантажувати основну базу MySQL» трапляється часто. Розберемо, коли ClickHouse виправданий поруч із MySQL на одному VDS і чого від нього не варто чекати.
Коли ClickHouse потрібен, а коли MySQL достатньо
ClickHouse виграває там, де потрібно просканувати мільйони рядків і підрахувати агрегат — суму, кількість унікальних відвідувачів за місяць, розбивку по годинах. Колонкове зберігання читає лише потрібні стовпці, а не весь рядок цілком, тому такі запити на порядки швидші, ніж на звичайній рядковій таблиці InnoDB з тим самим обсягом даних.
Якщо сайту достатньо вибірки «останні 50 замовлень клієнта» або «картка товару за id», ClickHouse не потрібен — для точкових вибірок за первинним ключем і для записів із частими точковими оновленнями MySQL залишається правильним вибором; різницю між реляційними СУБД детальніше розбирає стаття MySQL або PostgreSQL: як вибрати СУБД.
Як ClickHouse зберігає дані
Таблиці в ClickHouse створюють з двигуном сімейства MergeTree — саме він відповідає за сортування даних за ключем і фонове злиття дрібних кусків у великі.
CREATE TABLE events
(
event_date Date,
event_time DateTime,
user_id UInt64,
event_type String
)
ENGINE = MergeTree()
ORDER BY (event_date, user_id);
Дані фізично лежать відсортованими за ключем ORDER BY, а не за порядком вставки, тому вибірка за діапазоном дат читає лише потрібні куски з диска, а не всю таблицю.
Як перенести дані з MySQL
Прямий перенос порядковими INSERT з PHP-скрипта працює, але створює в ClickHouse багато дрібних кусків даних, які потім фоново зливаються і навантажують диск сильніше, ніж сама вставка.
- Вставляти дані партіями: однією вставкою надсилати від 1 000 до 100 000 рядків — чим більша партія, тим менше кусків має злити фон злиття, а конкретне число залежить від розміру рядка і частоти вставок.
- Використовувати табличний двигун MySQL або словник із джерелом MySQL для читання довідників без дублювання даних на обох сторонах.
- Для потоку подій — накопичувати події у файлі або в черзі та імпортувати пакетами за розкладом, а не писати в ClickHouse з кожного запиту користувача напряму.
- Для оновлення і видалення рядків використовувати мутації (ALTER TABLE ... UPDATE/DELETE) і пам'ятати, що вони виконуються асинхронно у фоні, а не миттєво, як UPDATE в InnoDB.
- Вимкнути вставку по одному рядку з веб-застосунку на проді — навіть рідкі прямі INSERT з обробника запиту створюють навантаження, непропорційне обсягу даних.
ClickHouse не замінює транзакційну базу — для нього немає багатотабличних транзакцій і зовнішніх ключів, які є в MySQL і в PostgreSQL; принципи вибору реляційної СУБД під транзакційне навантаження описані у статті про налаштування PostgreSQL на VPS.
Ресурси, які знадобляться на VDS
ClickHouse активно використовує оперативну пам'ять для кешу незтиснутих блоків і для проміжних структур при агрегації, а також постійно пише на диск при фоновому злитті кусків — на повільному мережевому диску це створює помітне навантаження по I/O навіть без запитів користувачів.
| Параметр | InnoDB (MySQL) | MergeTree (ClickHouse) |
|---|---|---|
| Зберігання рядків | За рядками, весь рядок цілком | За стовпцями, окремо кожен стовпець |
| Сильна сторона | Точкові вибірки і часті зміни рядків | Агрегати по мільйонах рядків |
| Оновлення рядка | Миттєве, у межах транзакції | Асинхронна мутація, без транзакцій |
| Навантаження на диск | Випадкові читання і записи | Послідовні читання, фонові злиття |
Скільки пам'яті і дискового простору потрібно під ClickHouse на конкретному VDS, залежить від обсягу історичних даних і від того, скільки стовпців бере участь у типовому запиті — для контролю вільного місця і навантаження на диск підходить звичайний моніторинг ресурсів VDS, налаштований на окремий розділ під базу.
Як стежити за ClickHouse на сервері
Сама СУБД пише власний журнал у системні таблиці — system.query_log зберігає текст і час виконання кожного запиту, а system.merges показує, які куски зливаються фоном прямо зараз.
Якщо фонові злиття не встигають за потоком вставок, кількість кусків у таблиці зростає, а нові запити на читання сповільнюються — це перша ознака того, що розмір партії вставки потрібно збільшити або перенести ClickHouse на диск із вищою швидкістю запису.
Часті питання
Чи можна поставити ClickHouse і MySQL на один VDS?
Так, за достатнього обсягу оперативної пам'яті для обох процесів це звичайна практика: MySQL обслуговує транзакційне навантаження сайту, а ClickHouse — аналітику і логи, підключені окремим процесом читання. Важливо розвести їх по різних дисках або хоча б розділах, якщо дискове навантаження від злиттів у ClickHouse заважає MySQL.
Чи підходить ClickHouse для зберігання замовлень інтернет-магазину?
Ні, для замовлень потрібні транзакції, зовнішні ключі і миттєві точкові оновлення статусу — це завдання MySQL або PostgreSQL. ClickHouse годиться для вітрини аналітики за тими самими замовленнями: скільки замовлень за годину, середній чек за категоріями, але не для самого запису, який повинен залишитися у реляційній базі.
Чи потрібен ClickHouse, якщо логів і подій небагато?
Якщо обсяг логів вимірюється тисячами записів на добу, звичайна таблиця InnoDB з правильними індексами впорається без проблем, а розгортати окрему аналітичну СУБД сенсу немає — ClickHouse виправданий, коли рахунок йде на мільйони рядків і агрегатні запити до InnoDB починають виконуватися помітно довше точкових.