Комментарии 9
То, что я увидел дальше, было самым быстрым временем, которое я видел при многократном выполнении каждого запроса в таблице trips_mergetree_x3.
Надеюсь что он не кэш ch проверял
Эх… прочитав подобную поверхностную статью, я тоже сильно воодушевился кликхаусом пару месяцев назад, решив использовав ch, как историческую базу для нескольких миллиардов транзакций в денормализованном виде, которые до этого хранились в партиционированной таблице с clustered columnstore index в MSSQL.
В итоге мы провели тесты на сервере с 72 железными ядрами (которые отображаются, как 144 логических), почти топовым NVMe диском, 512ГБ памяти.
Первое впечатление, что ch это очень круто. Да, агрегационные запросы сразу задействуют все ядра с первой секунды выполнения. Тупые запросы типа тех, что есть в статье, летают.
Но вот стоит написать что-то типа a join a on..., как потребление процессора падает до 1 ядра, и ch пытается в лоб в 1 поток это все просчитать. Более того, даже килл долгоотрабатывающих запросов отрабатывает как-то рандомно, и не с первого раза. То есть, если (применительно к домену примера) считать вещи типа "найти кластер пассажиров, которые имеют как минимум 10 одинаковых поездок с одним из членов кластера", или "вычислить семейные пары — люди, которые с одного района выезжают, едут на разные работы, но потом могут оттуда поехать в условный ресторан вместе (и, понятное дело, найти не конкретные кейсы, а принять решение статистически)", то ch показывает просто отвратительные результаты там, где mssql без проблем делает честный map-reduce под капотом с репартишенгом, где это надо. Хотя, кто знает, может есть какие-то неизвестные и неописанные в доке тонкости настройки или хинтов, которые включают магию… А такие задачи реально возникают, когда надо заготовить сложные фичи для ML, или искать кейсы фрода.
Из плюсов. Диалект SQL поражает некой правильностью и очевидностью мысли (видя вещи вроде приблизительного каунта, самого встречаемого значения, семплирования из коробки, неумножающего джойна, понимаешь что да, эти люди прямо залезли тебе в голову, и сделали то, чего давно подсознательно хотел). Но при этом, он лишен многих привычных вещей, и перестроить голову под сн — это непросто. Также есть прикольные административные фичи вроде ограничения памяти на юзера. Позволяет быстро отбивать бред типа джойнов с always true условием за несколько секунд.
Ну и, подводя итог, мы остались на mssql, принимая за ограничение, что о масштабировании выполнения больших аналитических запросов придется забыть (вертикально от 4 сокетов расти особо некуда — даже 8 сокетные системы на Xeon platinum уже неадекватно дороги, не говоря уже о монстрах вроде hp superdome x, а горизонтально не позволит mssql). Говоря же о сн, масштабирование тупых групбай по трем столбцам не сильно интересно в принципе. Тот же ms это делает и так очень быстро на одном сервере, и замедление даже на порядок вполне терпимо. И да, Google big query в свое время произвел куда лучше впечатление. Хотя, уверен, что есть масса примеров бизнесов, где надо считать примитивные аггрегации на кластерах на десятки тысяч ядер, и для них сн намного проще и эффективнее, чем любые другие решения (hadoop, написание шардинга на клиенте, сверхдорогие проприетарные решения)...
> колоночная база данных
Вы уверены, что у вас был денормализованный вид?
Для избежания join-ов в наш DWH на ClickHouse приходилось ради приемлемой денормализации докидывать данные, иногда полученные join'ами из боевой базы, иногда парсить логи, иногда даже лазить за данными в API к партнерам — еще до вставки в CH. Благо наполнение DWH было фоновой, относительно неприоритетной задачей, real-time там был не нужен.
Зато у аналитиков tableau просто летал.
Но да, ClickHouse это тоже лишь инструмент и нужно понимать, когда его можно использовать, а когда не стоит (например джойнить 2 больших таблицы по сути ClickHouse не может).
Если у вас данных действительно много и переделка структуры данных под ClickHouse будет дешевле, чем покупка железа (и софта), то оно того стоит. Иначе действительно, возможно, имеет смысл использовать другие решения вроде Exasol, BigQuery и т.д.
вещи типа «найти кластер пассажиров, которые имеют как минимум 10 одинаковых поездок с одним из членов кластера», или «вычислить семейные пары — люди, которые с одного района выезжают, едут на разные работы, но потом могут оттуда поехать в условный ресторан вместе (и, понятное дело, найти не конкретные кейсы, а принять решение статистически)»
Здесь вы, вероятно, хотите делать джойн таблицы сам на себя на лету, и это действительно ClickHouse не умеет делать. Но это не значит, что задачу нельзя решить в рамках ClickHouse. Для этого зачастую можно обойтись GROUP BY и правильной вставкой данных. Например, есть схожая задача — найти взаимные переписки пользователей (переписка пользователей это условно кортеж <from_user_id, to_user_id, message>). В наивном решении нам нужно делать что-то вроде
SELECT ... FROM messages AS m JOIN messages AS m2 ON m1.from_user_id = m2.to_user_id GROUP BY ...
. Это работать в ClickHouse будет очень плохо (действительно нужен map reduce в этом случае). Но если немного поменять условия задачи и учитывать то, как ClickHouse хранит данные, то неожиданно можно получить намного лучшее решение:Для каждой переписки мы вставляем по две записи, добавляя новое поле («тип»: исходящее или входящее сообщение):
<from_user_id, to_user_id, message, «out»>
<to_user_id, from_user_id, message, «in»>
Теперь, чтобы получить взаимные переписки (при условии сортировки по <user_id1, user_id2>), достаточно написать что-то вроде такого:
SELECT user_id1, user_id2 FROM messages GROUP BY user_id1, user_id2 WHERE uniqUpTo(2)(message_type) = 2
Где 2 — это 2 разных типа message_type: «out» и «in».
Похожим способом можно группировать другие сущности. Безусловно, это работает не для 100% случаев, но часто этого достаточно.
1.1 миллиард поездок на такси: 108-ядерный кластер ClickHouse