Перейти к основному содержимому
Версия: 3.0

Требования к серверам iQBot

Из чего состоит установка​

iQBot состоит из нескольких процессов, которые работают с одной базой данных PostgreSQL:

КомпонентЧто делаетПорт по умолчаниюНужен снаружи
iQBot (ядро и Studio)Диалоговый движок, административная консоль, Studio, API для iQChannels. Studio работает отдельным процессом и доступна через порт ядра.3000 (Studio: 4000, внутренний)Да, только порт 3000
iQBot NLUРаспознавание намерений и сущностей, обучение моделей.3200Нет
Языковой серверЯзыковые модели (векторы слов) для NLU. Запускается отдельной командой, см. Установка iQBot на Linux.3150Нет
iQBot MessagingХранение бесед и сообщений, доставка событий.3100Нет
PostgreSQLДанные ботов, диалоги, модели NLU.5432Нет
Duckling (по желанию)Извлечение системных сущностей: время, числа, суммы, e-mail. Поставляется образом iqbot-platform/duckling.8000Нет

Ядро запускает NLU и Messaging само, из каталога bin рядом с исполняемым файлом. Если порт занят, процесс выбирает ближайший свободный (для самого ядра в журнал пишется предупреждение). Языковой сервер и Duckling ядро не запускает.

Порты языкового сервера и Messaging

Раньше языковой сервер по умолчанию слушал порт 3100, тот же, что Messaging, и на одном сервере их приходилось разводить ключом --port. В текущих сборках языковой сервер по умолчанию слушает 3150. Если вы обновляете установку, где порт задан явно, ничего менять не нужно.

Ресурсы компонентов​

Таблица показывает, сколько оперативной памяти и дискового пространства занимает каждый компонент в работающей установке: один бот, русский язык, процессы после обучения модели. При обучении потребление памяти выше, поэтому в конфигурациях ниже оно взято с запасом.

КомпонентОперативная памятьДиск
Ядро и Studio (два процесса)около 0,7 ГБ в покое, 1,6–1,9 ГБ под нагрузкой, пики до 2,8 ГБдистрибутив около 1 ГБ вместе с NLU и Messaging
NLU: сервер и три рабочих процесса обученияоколо 2 ГБмодели хранятся в базе данных
Языковой серверзависит от размерности векторов, см. ниже: при размерности 100 закладывайте 1,3 ГБ на языкпри размерности 100 около 1 ГБ файлов на язык
Messagingоколо 0,3 ГБ
PostgreSQLот 0,2 ГБ, растёт с даннымизависит от числа диалогов

Память ядра под нагрузкой растёт, пока процесс не выполнит сборку мусора, затем падает: график похож на пилу с размахом около 1 ГБ. Закладывайте для узла с ядром и Studio не менее 3 ГБ свободной памяти.

Память языкового сервера и размерность векторов​

Языковой сервер держит в памяти векторы слов каждого языка. Их размер определяется размерностью модели: файл iqbot.<язык>.<размерность>.bin при размерности 100 занимает около 1 ГБ, при 300 — около 3 ГБ, и памяти сервер занимает примерно столько же, сколько весят файлы загруженных языков, плюс запас на запросы. Сервер с русским и английским языками размерности 100 занимал 1,3 ГБ в покое.

РазмерностьФайл векторов на языкПамять на язык, для расчёта
100около 1 ГБ1,3 ГБ
300около 3 ГБ4 ГБ

Нехватка памяти проявляется не сразу: системе приходится останавливать языковой сервер, а сервер NLU продолжает отвечать. Обучение при этом заканчивается ошибкой. Следите за компонентом lang в /health и /status и за плашкой «Языки» в консоли, а память узла планируйте с запасом: языковой сервер, сервер NLU, ядро и PostgreSQL вместе не должны подходить к границе доступной памяти. На Docker Desktop и Colima проверьте, сколько памяти отдано виртуальной машине, а не только хосту.

Если вам поставят модели другой размерности, пересчитайте память узлов или вынесите языковой сервер на отдельный сервер (адрес задаётся в IQB_MODULE_NLU_LANGUAGESOURCES). Размерность задаётся ключом --dim при запуске сервера и должна совпадать с именем файла.

Пропускная способность узла​

Ядро платформы обрабатывает диалоги в одном потоке, поэтому один узел под нагрузкой занимает одно ядро процессора. Дополнительные ядра одному узлу производительность не добавляют, добавляют узлы.

Измерение проведено на стенде по методике нагрузочного тестирования. Нагрузка: клиенты ведут диалог банковского бота из трёх сообщений (приветствие, выбор пункта меню, ввод четырёх цифр карты с выполнением действия), каждый клиент ждёт ответ перед следующим сообщением. Сообщением считается один запрос клиента и ответ бота.

Одновременно ждущих клиентовСообщений в секунду, один узелЗадержка ответа, медианаЗадержка ответа, 95 %
170,14 с0,16 с
10550,18 с0,23 с
30870,34 с0,57 с
6079–950,6–0,8 с1,0–1,1 с

Что важно знать при планировании.

  • Задержка ответа не бывает меньше 0,14 с даже на пустом узле: после ответа бота платформа ждёт ещё 100 мс (converse.bufferDelayMs) на случай запоздавших реплик. Поэтому один клиент даёт около 7 сообщений в секунду, а пропускная способность узла набирается числом одновременных клиентов.
  • Узел ограничивает число одновременно обрабатываемых сообщений (IQB_CONVERSE_MAX_IN_FLIGHT, по умолчанию 100). Сверх лимита запрос сразу получает 503 с заголовком Retry-After, узел продолжает обрабатывать принятые сообщения с той же скоростью. На стенде при 120 одновременных клиентах узел обработал 58 сообщений в секунду и отклонил лишние.
  • Для расчёта берите 50 сообщений в секунду на узел: это примерно две трети от измеренных 79–95 при 30–60 одновременных клиентах и оставляет запас на действия бота, которые обращаются к внешним системам и держат слот дольше.
  • Несколько узлов делят нагрузку: два узла на стенде обработали 120 сообщений в секунду при 60 клиентах. На отдельных серверах рост ближе к линейному.
  • PostgreSQL при 95 сообщениях в секунду занимала около 20 % одного ядра, при 120 — около 20 % на два узла, то есть база данных не была узким местом.

Тестовый сервер​

Конфигурация для стенда, разработки, обучения сотрудников и пилотного проекта: все компоненты на одном сервере, один язык. Для работы сценаристов и проверки бота тестовыми пользователями её достаточно. Для продуктива используйте расчёт из следующего раздела.

Процессор4 физических ядра
Оперативная память8 ГБ
Диск20 ГБ и больше, плюс место под базу данных

Если языковому серверу не хватает памяти, система останавливает его, в консоли это выглядит как сообщение Killed. Каждый дополнительный язык размерности 100 добавляет около 1,3 ГБ памяти и 10–15 секунд к времени запуска языкового сервера; при размерности 300 — около 4 ГБ.

Программное обеспечение​

  • Операционная система. Linux x64 с glibc 2.28 или новее. Docker-образы собраны на Debian 12.
  • PostgreSQL версии 13 или новее. Отдельная база, не входит в поставку.
  • Docker (по желанию), если установка идёт из образов. См. Установка iQBot в Docker.
  • Исходящий доступ в интернет для работы платформы не требуется: языковой сервер работает автономно (--offline), данные клиентов не покидают контур.

Продуктивные конфигурации​

Продуктивная установка собирается из узлов iQBot и общих служб. Что считать узлом и что выносить на отдельные серверы, описано в разделе Размещение компонентов ниже: по умолчанию узел — это ядро, Studio, NLU, Messaging и языковой сервер вместе, а общие для всех узлов только база данных и, в кластере, Redis.

Узлы ядра. Рассчитайте число узлов по пиковой нагрузке в сообщениях клиентов в секунду. Один узел рассчитывайте на 50 сообщений в секунду (измерено 78–95 на стенде, запас на действия бота и на оборудование). Число рабочих узлов равно пиковой нагрузке, делённой на 50 и округлённой вверх. К ним добавьте один узел запаса на отказ.

Пик нагрузки, сообщений в секундуРабочих узловС запасом на отказ
до 5012
до 10023
до 20045
до 40089

Каждому узлу выделите 4 ядра и 8 ГБ оперативной памяти, если на нём работают свои NLU, Messaging и языковой сервер (один язык размерности 100), и 2 ядра и 4 ГБ, если они вынесены на отдельные серверы. Схемы установки нескольких узлов описаны в разделе Установка в режиме кластера.

База данных. По результатам измерений PostgreSQL расходует около 20 % одного ядра при 95–120 сообщениях в секунду, поэтому для расчёта важнее диск. Одно сообщение клиента вместе с ответами бота занимает в базе около 5 КБ (события и история диалога вместе с индексами): при 10 миллионах сообщений в месяц это около 50 ГБ в месяц, срок хранения задают настройки журналов. Под продуктив выделяйте отдельный сервер с репликой.

NLU и языковой сервер на отдельных серверах. Нужны только в вариантах размещения, описанных ниже. Для сервера NLU рассчитывайте 4 ядра и 8 ГБ, плюс память языкового сервера по таблице выше.

Размещение компонентов​

iQBot состоит из нескольких процессов, и каждый из них можно запустить на отдельном сервере: ядро подключается к внешнему NLU параметром nluServer в nlu.json, к внешнему Messaging — переменными IQB_MESSAGING_ENDPOINT и IQB_MESSAGING_ADMIN_KEY, к языковому серверу — IQB_MODULE_NLU_LANGUAGESOURCES. Возможность есть, но пользоваться ею нужно не всегда.

По умолчанию всё на одном узле. Ядро само запускает NLU и Messaging рядом с собой, языковой сервер ставят на тот же сервер. Так узел — самодостаточная единица: добавили узел — получили и обработку диалогов, и распознавание, и доставку сообщений для него, без лишнего сетевого шага на каждом сообщении и без отдельной точки отказа. Общими для узлов остаются только база данных (и Redis в кластере). Все замеры и расчёты в этом документе сделаны для такой схемы.

Когда компонент выносят на отдельный сервер:

КомпонентОставить на узлеВынести отдельно
Языковой серверДо трёх узлов или один язык размерности 100: 1,3 ГБ на узел терпимо.От четырёх узлов, несколько языков или модели размерности 300: один общий сервер (или два за виртуальным адресом) экономит по 1,3–4 ГБ на каждом узле. Сервер не хранит состояния, его можно перезапускать и резервировать независимо. Адрес задаётся в IQB_MODULE_NLU_LANGUAGESOURCES на всех узлах.
NLUОбычная нагрузка: распознавание идёт локально, обучение редкое.Обучение больших ботов или частое обучение мешает диалогам на узле (обучение занимает до трёх процессов и 2 ГБ). Выделенный сервер NLU разгружает узлы; за ним нужен собственный балансировщик или виртуальный адрес, иначе он становится единой точкой отказа. Настройка: nluServer: {"autoStart": false, "endpoint": "http://nlu.example.com:3200"} в nlu.json.
MessagingВсегда, если каналы связи идут через iQChannels: Messaging тогда обслуживает только внутренний обмен и эмулятор.Только если веб-чат или другие каналы подключены к платформе напрямую и нужен один адрес входа для них, либо если база iqbot_messaging требует отдельного обслуживания. У внешнего Messaging свои переменные (ADMIN_KEY, DATABASE_URL, ENCRYPTION_KEY) и своя кластеризация через Redis.
База данныхНикогда: на узле только для тестового стенда.Всегда отдельный сервер с репликой.
Redis—Всегда отдельно от узлов, когда используется распределение нагрузки.

Выделенные серверы NLU и языкового сервера убирают из узлов их память и процессор, но добавляют сетевой шаг на каждое сообщение (обычно единицы миллисекунд внутри одной площадки).

Как проверить на своём оборудовании​

Измерение повторяется по методике, которая хранится в репозитории платформы, в каталогах docs/load-testing и scripts/load-test. Методика описывает топологии, сценарии диалога, метрики и порядок запуска. Основная проверка для проекта: запустить на целевом оборудовании один узел, затем два, дать каждому узлу нагрузку из 30 одновременно ждущих клиентов и сравнить пропускную способность. Если два узла дали не меньше 1,8 пропускной способности одного, оборудование подходит для схемы с распределением нагрузки.

Масштабирование и отказоустойчивость​

Нагрузку увеличивают двумя способами: добавляют ресурсы серверу или устанавливают платформу на несколько серверов. Для нескольких серверов есть два варианта, их описывает раздел Установка в режиме кластера:

  • Резервный узел: платформа работает на одном узле, второй запускается при отказе первого;
  • Распределение нагрузки: диалоги обрабатывают несколько равноправных узлов за балансировщиком, узлы связаны через Redis.

В обоих вариантах база данных PostgreSQL резервируется репликацией. Резервные копии описаны в разделе Резервное копирование и обновление.

Типовые конфигурации​

Готовые наборы оборудования под пиковую нагрузку. Расчёт: один узел iQBot на 50 сообщений в секунду плюс один узел запаса на отказ (см. раздел «Продуктивные конфигурации»). Каждый узел iQBot — полная установка: ядро, Studio, консоль, NLU, Messaging и языковой сервер для одного языка с векторами размерности 100; на второй язык добавьте 1,5 ГБ памяти каждому узлу, а для моделей размерности 300 берите узлы с 16 ГБ памяти (плюс 4 ГБ на каждый дополнительный язык). Балансировщик и виртуальные адреса базы данных и Redis обеспечивает инфраструктура заказчика. Диск базы данных указан на хранение диалогов за 30 дней при средней нагрузке в треть от пиковой (около 5 КБ на сообщение); при другом сроке хранения пересчитайте пропорционально.

50 сообщений в секунду100 сообщений в секунду200 сообщений в секунду400 сообщений в секунду
Схемарезервный узел: работает один узел, второй запускается при отказераспределение нагрузкираспределение нагрузкираспределение нагрузки
Узлы iQBot2 × (4 ядра, 8 ГБ, 40 ГБ)3 × (4 ядра, 8 ГБ, 40 ГБ)5 × (4 ядра, 8 ГБ, 40 ГБ)9 × (4 ядра, 8 ГБ, 40 ГБ)
Redisне нужен2 × (1 ядро, 1 ГБ) с Sentinel или виртуальным адресом2 × (1 ядро, 1 ГБ)2 × (2 ядра, 2 ГБ)
PostgreSQLосновной и реплика, 2 × (4 ядра, 8 ГБ)основной и реплика, 2 × (4 ядра, 8 ГБ)основной и реплика, 2 × (4 ядра, 16 ГБ)основной и реплика, 2 × (8 ядер, 32 ГБ)
Диск базы данных на 30 дней220 ГБ440 ГБ870 ГБ1,7 ТБ
Балансировщиквиртуальный адрес (keepalived на узлах)NGINX, 2 × (2 ядра, 2 ГБ)NGINX, 2 × (2 ядра, 2 ГБ)NGINX, 2 × (4 ядра, 4 ГБ)
Итого ядер и памяти16 ядер, 32 ГБ26 ядер, 46 ГБ34 ядра, 78 ГБ64 ядра, 148 ГБ

Как читать таблицу.

  • Узлы iQBot: 4 ядра на узел, потому что кроме ядра платформы (одно ядро под нагрузкой) на узле работают NLU с обучением моделей, Messaging и языковой сервер. Память: ядро и Studio до 3 ГБ под нагрузкой, NLU 2 ГБ, языковой сервер 1,3 ГБ на язык при размерности 100, Messaging 0,3 ГБ, остальное системе и запасу.
  • Число узлов включает запасной: при отказе одного узла остальные принимают его клиентов без потери пропускной способности.
  • Redis хранит только служебные данные (задания, инвалидация кэша, комнаты socket.io, блокировки), ему хватает минимальной машины; важна отказоустойчивость, а не ресурсы.
  • PostgreSQL на стенде занимала около 20 % одного ядра при 100 сообщениях в секунду; ресурсы базы заложены с запасом на отчёты, обучение NLU и обслуживание, диск — главный ресурс.
  • В конфигурациях на 200 и 400 сообщений в секунду языковой сервер выгоднее вынести на два отдельных сервера (по 2 ядра и 4 ГБ на язык размерности 100) и уменьшить память узлов до 6 ГБ, см. раздел «Размещение компонентов».