Когда изоляция оправданаИзоляция рассчитана на крупные развертывания с непрерывной ингестией. При объёме хранимых данных менее примерно 100 ТБ в месяц один сервис с возможностью чтения и записи обычно справляется с обеими рабочими нагрузками, и второй сервис, скорее всего, не потребуется. Для оценки сжатого объёма данных в месяц используйте модель сайзинга.
Зачем изолировать чтение от записи
- Запись больше не ухудшает чтение. Непрерывная ингестия OpenTelemetry — сами вставки и следующие за ними фоновые слияния — конкурирует с запросами панелей мониторинга и поиска за CPU и память. Пока идёт ингестия, задержка чтения может заметно вырастать, а после её остановки возвращается к норме.
- Чтение больше не мешает записи. Конкуренция работает в обе стороны: тяжёлый ad-hoc запрос или ресурсоёмкая отрисовка панели мониторинга могут исчерпать память сервиса, и вставки не просто замедлятся, а полностью завершатся ошибкой.
- Вычислительные ресурсы только для чтения полностью отданы запросам. Сервисы только для чтения не выполняют фоновых слияний за пределами системных таблиц. Кроме того, они переходят в простой без задержки — в отличие от сервисов с возможностью чтения и записи, которые слияния могут удерживать в активном состоянии.
- Каждая сторона рассчитывается отдельно. Модель оценки ресурсов оценивает вычислительные ресурсы для приёма и для запросов по отдельности, а хранилище позволяет выделить под каждую задачу собственный сервис. Выше заложенного в модели базового уровня в 1 QPS преобладают вычислительные ресурсы под запросы: в разобранном примере при 5 QPS получается 58 vCPU на приём против 290 на запросы — то есть небольшой сервис записи может обслуживать значительно более крупный сервис чтения.
- Простой и autoscaling настраиваются для каждого сервиса отдельно. У каждого сервиса своё количество реплик и свои настройки автомасштабирования и автоматического перехода в простой, поэтому сервис записи может работать постоянно для непрерывной ингестии, а сервис чтения — простаивать в нерабочие часы.
- Хранилище не дублируется. Сервисы в составе хранилища используют одну и ту же папку объектного хранилища и одни и те же таблицы, а хранилище оплачивается только один раз.
- Доступ можно ограничить для каждой конечной точки. IP Access List применяются к каждому сервису отдельно, поэтому конечная точка записи может быть доступна только с ваших коллекторов, а конечная точка чтения — только из вашего развертывания ClickStack. См. наше руководство по управлению сетевым доступом.
Архитектура
Рекомендуемая топология — хранилище, в котором есть один сервис с возможностью чтения и записи для ингестии и один сервис только для чтения для ClickStack:
При планировании топологии учитывайте следующее:
- Первый сервис в хранилище всегда создаётся с возможностью чтения и записи, а тип сервиса задаётся при создании и не меняется — чтобы перейти от режима только для чтения к режиму чтения и записи (или наоборот), создайте в хранилище новый сервис.
- Все сервисы в хранилище используют одного облачного провайдера, один регион, одну версию ClickHouse и один Keeper, а также расписание обновлений основного сервиса.
- Для ингестии используйте один сервис с возможностью чтения и записи. Слияния распределяются между всеми сервисами с возможностью чтения и записи, которые используют общее хранилище, поэтому слияние для вставки на одном сервисе может быть выполнено другим. Если этот другой сервис при этом обслуживает тяжёлые запросы, они будут конкурировать со слиянием за CPU и память на том сервисе, где оно выполняется, — тем самым замедляя слияния для вставок первого сервиса, а вместе с ними и производительность вставки. Оставьте запросные рабочие нагрузки на сервисе только для чтения и добавляйте второй сервис с возможностью чтения и записи только в том случае, если требуется отделить слияния от ингестии.
Настройка изолированного развертывания
1
Подготовьте сервис с возможностью чтения и записи
Используйте существующий сервис — или основной сервис нового хранилища — для ингестии, выбрав его размер исходя из требуемых вычислительных ресурсов на приём данных согласно модели сайзинга.Создайте на этом сервисе базу данных и отдельного пользователя для ингестии. Поскольку все сервисы в хранилище используют общее управление доступом, созданные здесь пользователи будут доступны на каждом сервисе хранилища:Сгенерируйте пароль с помощью какого-либо инструмента, например
openssl rand -base64 24, и храните его в менеджере секретов, а не в манифесте или в истории команд shell. Подробнее см. в нашем руководстве Создание пользователя для ингестии.Если этот сервис уже входит в состав хранилища, учтите, что DDL-запросы на уровне базы данных могут зависать, когда другой сервис в этом хранилище переведён в состояние idled — см. Администрирование и DDL.2
Добавьте в хранилище сервис только для чтения
В консоли ClickHouse Cloud нажмите на знак «плюс» рядом с только что подготовленным сервисом, чтобы создать второй сервис, использующий те же данные. В качестве типа сервиса выберите read-only и подберите его размер под вычислительные ресурсы для запросов согласно модели сайзинга.Полное пошаговое описание приведено в нашем руководстве Как настроить хранилище.
3
Направьте приём данных в сервис с возможностью чтения и записи
Настройте collector на экспорт в конечную точку сервиса с возможностью чтения и записи, выполняя аутентификацию от имени пользователя, отвечающего за ингестию:Подробнее см. параметры конфигурации collector, а также аналогичные настройки для Vector и других способов ингестии.Операции записи, направленные на конечную точку только для чтения, отклоняются, поэтому collector всегда должен обращаться к сервису с возможностью чтения и записи.
4
Настройте ClickStack для использования сервиса только для чтения
Интерфейс ClickStack всегда подключается к тому сервису ClickHouse, из которого он был запущен в консоли ClickHouse Cloud. Чтобы запустить его на compute только для чтения:
- Выберите сервис только для чтения в консоли ClickHouse Cloud.
- Выберите ClickStack в левом меню навигации.
5
Проверьте разбиение
Выполните поиск или откройте панель мониторинга в ClickStack, а затем проверьте, куда попали запросы. Таблицы Пустой результат сам по себе не означает, что запросы ушли куда-то ещё: При работе с этим запросом следует помнить о двух моментах: сервисы, переведённые в режим ожидания, не возвращают строк, поэтому, если нужны полные результаты, сначала пробудите их; кроме того,
system пишутся на том узле, который выполнил запрос, поэтому для сервиса с более чем одной репликой понадобится clusterAllReplicas с именем кластера default, чтобы охватить их все. На сервисе, работающем в режиме только для чтения, вы должны увидеть запросы ClickStack:system.query_log сбрасывается на диск периодически — по умолчанию каждые 7,5 секунды, — поэтому запрос, выполненный сразу после поиска, может в нём ещё не отображаться. Подождите немного и выполните его снова либо принудительно сбросьте журналы с помощью SYSTEM FLUSH LOGS, если у вас есть соответствующий grant.Именно группировка по user и http_user_agent позволяет определить источник трафика: она отличает интерфейс от SQL console и от всего остального, что подключается к конечной точке, независимо от того, на какие таблицы указывают ваши sources. Фильтрация по is_initial_query = 1 оставляет по одной строке на каждый запрос в том виде, в каком он был отправлен: вторичные запросы распределённого выполнения и внутренние запросы, вычисляющие materialized views, записываются отдельно со значением is_initial_query = 0.На сервисе с возможностью чтения и записи тот же запрос должен показать вставки от пользователя ингестии и отсутствие трафика запросов ClickStack.Поочерёдное выполнение запроса на каждом сервисе — надёжный способ проверки, поскольку кластер default содержит только реплики того сервиса, к которому вы подключены. Чтобы получить агрегированную картину по всему хранилищу, используйте вместо него имя кластера all_groups.default:hostName() указывает на реплику, а не на сервис — чтобы соотнести активность с конкретным сервисом, отправляйте запрос непосредственно к нему.Разделение слияний и ингестии
При очень высоких устойчивых скоростях приёма основной нагрузкой на сервис приёма становятся слияния, а не сами вставки. Поскольку слияния распределяются между всеми сервисами с возможностью чтения и записи, совместно использующими хранилище, они могут попасть и на сервис, предназначенный для других задач. В таких развертываниях слияния можно полностью вынести с сервиса приёма, получив топологию из трёх сервисов:Требуется обращение в службу поддержкиОтключение слияний на сервисе с возможностью чтения и записи нельзя настроить из консоли Cloud. Обратитесь в службу поддержки, чтобы применить эту настройку к сервису.
- Не полагайтесь на автоматический переход в режим ожидания ни для одного из сервисов с возможностью чтения и записи. Сервис с отключёнными слияниями всё равно обрабатывает события загрузки и удаления частей, порождаемые вставками в других местах хранилища, а большое количество неслитых частей само по себе может препятствовать переходу в режим ожидания. Рассчитывайте на то, что оба сервиса с возможностью чтения и записи будут постоянно активны.
- Не направляйте запросы ни на один из сервисов с возможностью чтения и записи. Тяжёлые запросы
SELECTна таком сервисе конкурируют со слияниями за CPU и память — а именно этот сценарий отказа данная топология и позволяет избежать. Направьте ClickStack на сервис только для чтения, как описано выше. - Мутации, если они у вас есть, отслеживаются на том сервисе, который их выполняет. В обсервабилити мутации редки: схема ClickStack задаёт
ttl_only_drop_parts = 1, поэтому при обычном хранении данных во время TTL-слияний удаляются целые истёкшие части, а не вычищаются отдельные строки мутациями. Если вы всё же отправите на сервис приёмаALTER, порождающий мутацию, она будет выполнена сервисом слияний, и её прогресс появится вsystem.mutationsименно там, а не на сервисе приёма.
Администрирование и DDL
Все изменения схемы должны выполняться на сервисе с возможностью чтения и записи, в том числе:- Создание таблиц — выполняется автоматически коллектором ClickStack при первом приёме данных
- Изменение TTL для настройки срока хранения
- Создание materialized view для ускорения запросов
- Добавление индексов пропуска данных, проекций и других оптимизаций производительности
Изоляция агентных рабочих нагрузок
ИИ-ассистенты, подключённые через MCP-сервер ClickStack, создают такой же трафик чтения, как и любая панель мониторинга, но характер нагрузки у них иной: агент, разбирающий инцидент, выполняет множество исследовательских запросов подряд по диапазонам, которые никто не выбирал заранее. Если агенты и интерфейс работают с одним и тем же сервисом только для чтения, этот всплеск нагрузки встанет впереди тех панелей мониторинга, которые инженер просматривает во время того же инцидента. Здесь применим тот же подход с хранилищем — выделите агентам собственные вычислительные ресурсы только для чтения:1
Добавьте второй сервис только для чтения
Создайте в хранилище ещё один сервис только для чтения — точно так же, как в настройке выше. Он читает те же таблицы, что и сервис, обслуживающий интерфейс, поэтому копировать данные не нужно.Затем один раз запустите на нём ClickStack из консоли Cloud, как описано в разделе направление ClickStack на сервис только для чтения. Для Cloud MCP нужен сервис, на котором включён ClickStack, а также сам MCP — см. предварительные требования MCP.Подберите его размер исходя из ожидаемой нагрузки запросов от агентов, а не из QPS панелей мониторинга в модели расчёта размера, и оставьте автоматический переход в режим ожидания включённым: агентное использование обычно носит эпизодический характер, поэтому между исследованиями сервис может простаивать.
2
Включите MCP на этом сервисе
Откройте сервис только для чтения в консоли ClickHouse Cloud, нажмите Connect, выберите Connect with MCP и включите переключатель. См. включение удалённого MCP-сервера.
3
Направьте MCP-клиенты на него
Конечная точка Cloud MCP одинакова для всех сервисов — запросы маршрутизируются по заголовку Передавать этот заголовок может любой MCP-клиент — см. указание конкретного сервиса для эквивалентной конфигурации в Cursor, VS Code и других инструментах.
x-service-id, а без него попадают на первый сервис ClickStack, использованный вашей учётной записью. Скопируйте существующую конфигурацию MCP и добавьте заголовок с ID нового сервиса только для чтения:Alerts
ClickStack вычисляет оповещение на том сервисе, в котором он был создан, поэтому оповещения выполняются на тех же вычислительных ресурсах, что и интерфейс, — в данной топологии это сервис только для чтения.Управляемый ClickStackЧтобы включить оповещения, необходимо, чтобы хотя бы один пользователь с разрешениями Service Admin хотя бы раз вошел в ClickStack. При этом создается выделенный пользователь базы данных, от имени которого выполняются запросы оповещений; этот пользователь является общим для всех сервисов в хранилище. См. наше руководство по выдаче доступа к Управляемому ClickStack.
Изоляция вычисления оповещений
Нагрузку от оповещений нельзя направить централизованно, поскольку оповещения создают сами пользователи: тот, кто добавляет оповещение в ClickStack, добавляет его к тому сервису, в котором работает, и вычисляется оно на вычислительных ресурсах этого сервиса. Настройки, которая перенесла бы оповещения сервиса куда-то ещё, не существует. Изолировать можно те оповещения, которыми вы управляете централизованно, — те, что платформенная команда поддерживает для всей организации и которые обычно вычисляются чаще всего. Выделите им отдельный сервис только для чтения в хранилище и создавайте их из запущенного там ClickStack:
Остальные компромиссы вытекают из того, что состояние хранится отдельно для каждого сервиса:
- Общие оповещения и связанные с ними панели мониторинга существуют только на сервисе оповещений и не видны пользователям, работающим с сервисом запросов. Уведомления в любом случае доставляются в те же пункты назначения, так что пользователи теряют из виду определения, а не сами оповещения.
- Источники на сервисе оповещений — это отдельные объекты. Те из них, что используют стандартную схему OpenTelemetry, определяются автоматически, но пользовательские источники нужно настроить и там, прежде чем оповещение сможет на них ссылаться.