- PVSM.RU - https://www.pvsm.ru -
Про ClickHouse есть много разной информации, но мало про то, как готовить инфраструктуру с ним. Мы потратили примерно полгода вялого набивания шишек, чтобы это заработало именно так, как нас наконец-то устраивает. Нужно было найти конфигурацию эффективную и в плане денег, и в плане работы базы как таковой.
На момент написания статьи хранилищем и результатами его работы пользуются 16+ команд (11+ аналитиков и 2 data scientist, 70+ разработчиков, руководители и менеджерский состав).
Ежесуточно в хранилище поступает ~1,2 ТБ данных, пользователи и автоматика для построения отчётности генерируют ~35 000 запросов в сутки на выборки различной сложности. Подробнее про наше хранилище и то, какие задачи для бизнеса им решаем, можно почитать по ссылке [1].
Мы прошли путь от СlickНouse as a service у облачного провайдера к своей инсталляции, и до недавнего времени у нас уже более года существовал кластер ClickHouse из пяти нод без репликации и был развёрнут на гиперконвергентной инфраструктуре с гибридными дисками (SSD в качестве кеша + HDD), у инсталляции был ряд проблем:
Большинство данных, которые хранились в ClickHouse, мы в случае потерь могли восстановить из других источников (OLTP-баз данных или S3), но это потребовало бы значительного времени, по нашим оценкам, около 1 недели, потому как при потере одного сервера из кластера нужно было бы восстанавливать весь объём данных, что конечно же ни нас, ни бизнес не устроило.
К этому моменту у нас был механизм бекапов данных из ClickHouse, который работал не всегда стабильно, но даже если бы работал — мог гарантировать восстановление кластера в течение 1-2 суток, но при этом нам пришлось бы перезапускать все ETL и ELT-процессы, чтобы записать данные повторно с момента создания бекапа и до выхода из строя кластера, что заняло бы тоже значительное время.
Поэтому было решено использовать механизмы репликации в ClickHouse, которые имеют существенные сложности в использовании, с точки зрения разработчика, если вы привыкли к зрелым RDBMS, таким как PostgreSQL и MySQL.
Аналитическая нагрузка от ClickHouse мешала работе сервисов, которые чувствительны к latency, поэтому было принято решение, сразу выносить в отдельный контур на отдельные сервера. Изоляции, которая предлагалась на основе гиперконвергентной инфраструктуры, нам было недостаточно. Не хватало производительности гибридных дисков (SSD + HDD), хотели перейти на SSD only.
К текущему моменту мы понимали, что новая инсталляция хранилища будет существовать минимум пару лет. У нас есть выстроенная команда, поддерживающая парк серверов, в связи с этим разворачивание ClickHouse на наших железных серверах было экономически выгодным. Мы не рассматривали разворачивание в облаках основной инсталляции, но хотели бы иметь возможность расширить нашу инсталляцию, если такая потребность возникнет. Также по нашему опыту на обслуживание собственных серверов приходится тратить меньше времени, чем на решение проблем и разных спецэффектов в облаках.
Для защиты от рисков и ухода от проблем мы рассматривали разные варианты конфигурации ClickHouse и то, где всё это будет жить. Мы хотели подобрать решение, чтобы не пришлось переделывать через полгода и снова возвращаться к этому вопросу, потому как хранилище достаточно консервативное решение из-за многих связей с ним, которые появляются в процессе использования.
Как было описано выше, мы остановились на своих железных серверах, так как для нас это было экономически выгодным решением и исключало проблемы производительности, с которыми мы столкнулись ранее.
Мы заранее понимали, что у нас экспертов по ClickHouse будет один-два, а пользователей будет 40-50. Мы хотели изолировать знания об инфраструктуре, кластере и его топологии от обычных пользователей. Если нужно просто создать табличку — вот вам простая команда, вы её делаете через SQL и не знаете, как кластер в динамике меняется. Классические базы данных изолируют этот уровень и дают удобный инструментарий, чтобы отделить роль человека, который поддерживает инфраструктуру и пользуется инфраструктурой. Вся нужная информация есть в документации, но из неё сложно вытаскивать точечно куски — потому что документации очень много, а не потому что она плохая. И документация предполагает, что ты — эксперт, через пару неделек ковыряния можно выйти со знанием. Но наши пользователи не должны так делать. Для них у нас есть инструкция, которую можно впитать за 1 час, и работать спокойно.
И тут у ClickHouse есть две фишки, которые решают эти потребности.
На момент создания кластера мы нашли только опыт компаний, которые предлагали использовать круговую репликацию [4]. И такой подход предполагал, что коду, который пишут разработчики и аналитики вне команды, которая поддерживает хранилище, нужно было знать топологию кластера, распределение нод по физическим серверам. Что нас в корне не устраивало, потому как мы стремимся снижать порог входа для пользователей хранилища.
Вкратце репликация выглядит так: данные с первой ноды должны реплицироваться на вторую, со второй на третью и так далее.
У нас уже был опыт использования такого подхода и с ним были неудобства.
Выглядеть будет примерно так:
Создавать такие таблицы придётся на каждом шарде в отдельности.
Пример запросов создания таблиц для Shard #1:
CREATE TABLE db_shard_1.test_table_shard
(
id UInt32,
name String,
cdate DateTime
)
ENGINE ReplicatedMergeTree('/clickhouse/tables/db_shard_1/test_table_shard', 'replica_1')
ORDER BY (id)
PARTITION BY (cdate);
CREATE TABLE db_shard_2.test_table_shard
(
id UInt32,
name String,
cdate DateTime
)
ENGINE ReplicatedMergeTree('/clickhouse/tables/db_shard_2/test_table_shard', 'replica_2')
ORDER BY (id)
PARTITION BY (cdate);
Минус такого подхода ещё в том, что все созданные реплицируемые таблицы в кластере будут находиться только в определённых БД. Нет возможности ограничить права доступа к определённым базам.
<default_database>...</default_database>
.
После определения default_database, при создании distributed-таблицы можно не указывать название базы, так как значение подставится из конфига.
CREATE TABLE default.test_table
(
id UInt32,
name String,
cdate DateTime
)
ENGINE = Distributed('test_cluster', '', 'test_table_shard', rand());
Такие макросы удобно использовать для создания таблиц с использованием ON CLUSTER [2], можно выполнить один запрос, и на всех нодах будут созданы необходимые таблицы. Но при круговой репликации есть проблема, так как таблицы лежат в разных базах, предположительно, такой запрос должен создать все необходимые таблицы:
CREATE TABLE test_table_shard
(
id UInt32,
name String,
cdate DateTime
)
ENGINE ReplicatedMergeTree('/clickhouse/tables/{database}/{shard}/{table}', '{replica}')
ORDER BY (id)
PARTITION BY (cdate);
Но мы получим предупреждение, что нужно явно указать базу, в которой создаётся таблица, в связи с этим нет возможности одним запросом создать все необходимые таблицы.
Code: 371, e.displayText() = DB::Exception: For a distributed DDL on circular replicated cluster its table name must be qualified by database name. (version 21.4.3.21 (official build))
Можно, конечно, выполнить запрос на каждой паре реплицируемых нод, но для этого нужно знать топологию кластера.
/var/lib/clickhouse/metadata/
с соседней ноды, так как нет ещё одной ноды, на которой были бы созданы точно такие же таблицы. Приходится смотреть конфигурацию и в соответствии с ней править метаданные для новой ноды.
Есть сложность ещё и с решардингом партиций, так как ClickHouse не предоставляет это в автоматическом режиме. Для этих целей можно воспользоваться утилитой СlickНouse-copier [7] (её уже немного упоминали на Habr: один [8], два [9]). Есть ещё один подход, немного о нём ниже.
Напомню, мы остановились на своих железных серверах, так как для нас это было экономически выгодным решением. И с учётом выше описанных ограничений было принято решение использовать виртуализацию. Поселить на каждый из серверов по две виртуальные машины с ClickHouse. Разместив так, чтобы реплики жили на разных физических хостах. Мы понимали, что таким решением мы теряем часть мощностей, но мы сделали упор на простоту для пользователей и эксплуатацию, а не оптимизировали потребление ресурсов.
Это решение очень похоже на пример с круговой репликацией, но для нас есть свои плюсы.
Запрос создания реплицируемой таблицы [5] выглядит так:
CREATE TABLE test_database.test_table_shard ON CLUSTER test_cluster
(
id UInt32,
name String,
cdate DateTime
)
ENGINE ReplicatedMergeTree('/clickhouse/tables/{database}/{shard}/{table}', '{replica}')
ORDER BY (id)
PARTITION BY (cdate);
Макросы, используемые в запросе выше, на одной из нод:
С distributed-таблицей [3] аналогичная ситуация:
CREATE TABLE test_database.test_table ON CLUSTER test_cluster
(
id UInt32,
name String,
cdate DateTime
)
ENGINE = Distributed('test_cluster', 'test_database', 'test_table_shard', rand());
/var/lib/clickhouse/metadata/
) с оставшейся живой реплики. Запустить ClickHouse, дальше он сам создаст все необходимые базы, таблицы и зальёт данные.В дополнение получили увеличение скорости работы за счёт SSD only, обновились с версии 20.9.3.45 на 21.4.3.21 и получили новые фичи.
После переезда на SSD бекап также стал работать стабильнее.
Автор: Владимир
Источник [10]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/bazy-danny-h/367719
Ссылки в тексте:
[1] ссылке: https://habr.com/ru/company/tuturu/blog/576632/
[2] ON CLUSTER: https://clickhouse.tech/docs/ru/sql-reference/distributed-ddl/
[3] distributed-таблиц: https://clickhouse.tech/docs/ru/engines/table-engines/special/distributed/
[4] круговую репликацию: https://altinity.com/blog/2018/5/10/circular-replication-cluster-topology-in-clickhouse
[5] реплицируемых таблиц: https://clickhouse.tech/docs/ru/engines/table-engines/mergetree-family/replication/
[6] макросы: https://clickhouse.tech/docs/ru/engines/table-engines/mergetree-family/replication/#creating-replicated-tables
[7] СlickНouse-copier: https://clickhouse.tech/docs/ru/operations/utilities/clickhouse-copier/
[8] один: https://habr.com/ru/company/avito/blog/500678/#clickhouse-copier
[9] два: https://habr.com/ru/post/519168/
[10] Источник: https://habr.com/ru/post/576992/?utm_source=habrahabr&utm_medium=rss&utm_campaign=576992
Нажмите здесь для печати.