MAATRIX / Блог / Сколько RAM нужно для Zammad

Сколько RAM нужно для Zammad

MAATRIX

Zammad — это не один процесс, а связка из пяти-шести сервисов: Rails-сервер, планировщик, вебсокет, база, кэш и (обычно) Elasticsearch. Поэтому вопрос «сколько нужно RAM» упирается не в число тикетов, а в то, какие из этих сервисов вы держите включёнными и сколько агентов работает одновременно. Ниже — конкретные цифры по конфигурациям, откуда берётся потребление и как не упереться в OOM в первую же неделю.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Из чего состоит Zammad и куда уходит память

Официальный docker-compose.yml Zammad поднимает не два контейнера, а целый стек:

  • zammad-railsserver — сам Rails-бэкенд, интерфейс агента и API. Базовый Ruby-процесс на старте держит около 300-500 МБ, под нагрузкой (несколько воркеров Puma) легко уходит за 1 ГБ.
  • zammad-scheduler — фоновые задачи: разбор почты по IMAP/POP3, эскалации SLA, триггеры. Ещё один Ruby-процесс, +250-400 МБ.
  • zammad-websocket — реалтайм-обновления в интерфейсе агента (новые тикеты, статусы без перезагрузки страницы). Лёгкий, но постоянно работающий процесс.
  • PostgreSQL — основная БД. Потребление растёт с объёмом тикетов и вложений, но на старте это 150-300 МБ, которые PostgreSQL с удовольствием займёт под shared_buffers и кэш, если вы ему это позволите.
  • Memcached — кэш сессий и рендеров, обычно фиксированный лимит (по умолчанию 64-100 МБ).
  • Redis — используется вебсокет-сервисом и Action Cable для пуш-обновлений между агентами; сам по себе лёгкий, десятки мегабайт.
  • Elasticsearch — опциональный, но по факту обязательный для комфортной работы компонент: полнотекстовый поиск по тикетам, вложениям (через Ingest Attachment plugin) и знания. Это самый прожорливый сервис в стеке — о нём отдельно ниже.
  • zammad-nginx — фронт, отдаёт статику и проксирует на railsserver. Память измеряется единицами мегабайт.

Если сложить всё, кроме Elasticsearch, минимальный работающий стек Zammad помещается в 1.5-2 ГБ. Как только включаете Elasticsearch (а без него поиск по тикетам и база знаний работают в урезанном режиме), добавляйте отдельный бюджет памяти под JVM — и вот тут промахи с размером сервера случаются чаще всего.

Сколько RAM нужно: по размеру команды

Точные цифры зависят от объёма истории тикетов, числа каналов (почта, чат, телефония) и того, включён ли Elasticsearch. Ниже — ориентировочные диапазоны из практики разворачивания похожих стеков на Rails + Elasticsearch, а не измеренный бенчмарк одной конкретной инсталляции — у вас цифры сдвинутся в зависимости от нагрузки.

КомандаАгентовElasticsearchRAMvCPU
Тест/пилот1-3выключен2 ГБ1-2
Малый саппортдо 10включён4 ГБ2
Средний саппорт10-30включён6-8 ГБ4
Крупный саппорт30-80включён12-16 ГБ4-6
Enterprise / мультиканал80+ES на отдельном сервере16 ГБ на Zammad + отдельный ES-сервер6-8

Официальные требования Zammad для продакшена стартуют от 2 ГБ RAM и 2 CPU для совсем маленькой команды без Elasticsearch — это работает, но поиск по тикетам будет ограничен, а любой скачок нагрузки (массовая рассылка, импорт истории) уронит сервис в своп. На практике для реального саппорт-отдела с почтой, чатом на сайте и хотя бы парой интеграций комфортный старт — это 4 ГБ с Elasticsearch. Для сравнения по соседнему классу инструментов есть отдельный разбор — сколько RAM нужно для Mattermost, там логика похожая: чат-сервисы на Rails/Go тоже упираются в БД и поиск раньше, чем в сам веб-процесс.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Elasticsearch: главный пожиратель памяти

Elasticsearch — это JVM, и JVM просит память заранее, а не по факту использования. Дефолтная куча (ES_JAVA_OPTS=-Xms1g -Xmx1g) в официальном docker-compose.yml Zammad — это минимум, который работает только для тестовых инсталляций. Правило для Elasticsearch простое: куча JVM не должна занимать больше 50% доступной RAM сервера, потому что вторая половина нужна файловому кэшу ОС, через который Lucene реально читает индексы.

Практический ориентир:

# .env для docker-compose Zammad
ES_JAVA_OPTS=-Xms2g -Xmx2g

Если сервер на 4 ГБ, ставьте кучу 1 ГБ и не выше — иначе Rails-серверу, планировщику и PostgreSQL просто не останется места, и первым делом упадёт по OOM либо Elasticsearch, либо Postgres (в зависимости от того, кого раньше заметит OOM killer). На 8 ГБ разумно выделить Elasticsearch 2-3 ГБ кучи, остальное — под Rails-стек и БД. Отдельно про сайзинг и лимиты для самого Elasticsearch есть разбор — сколько RAM нужно для Elasticsearch, там подробнее про heap, file cache и когда есть смысл выносить его на отдельный узел.

Если Elasticsearch физически не помещается в бюджет (сервер на 2 ГБ), его можно отключить в настройках Zammad — поиск станет работать через встроенный поиск PostgreSQL, менее качественный, но не требующий отдельного JVM-процесса. Для пилота или команды до 3-5 агентов это разумный компромисс.

Пример docker-compose с лимитами памяти

Официальный образ Zammad не ограничивает контейнеры по умолчанию — на маленьком сервере это опасно: один процесс (обычно Elasticsearch или Rails при импорте почты) может съесть всю память и уронить соседей. Добавьте mem_limit и mem_reservation на каждый сервис:

services:
  zammad-railsserver:
    image: zammad/zammad:6.5
    mem_limit: 1200m
    mem_reservation: 600m

  zammad-scheduler:
    image: zammad/zammad:6.5
    mem_limit: 700m
    mem_reservation: 350m

  zammad-websocket:
    image: zammad/zammad:6.5
    mem_limit: 300m

  elasticsearch:
    image: zammad/zammad-docker-compose:elasticsearch-8.5.3
    mem_limit: 1500m
    environment:
      ES_JAVA_OPTS: "-Xms1g -Xmx1g"

  postgresql:
    image: postgres:15
    mem_limit: 700m

  memcached:
    image: memcached:1.6-alpine
    mem_limit: 128m

  redis:
    image: redis:7-alpine
    mem_limit: 128m

Сумма лимитов здесь — около 4.6 ГБ, то есть под такую раскладку берите сервер на 6 ГБ, оставляя запас ОС и на пики (импорт почты, массовая переиндексация). Подробнее про то, как mem_limit работает вместе с cgroups и swap, разобрано в статье про лимиты CPU и памяти в Docker.

Мониторинг и что делать при нехватке памяти

Перед тем как заказывать сервер побольше, посмотрите, кто именно ест память:

docker stats --no-stream

Если строка elasticsearch стабильно держится у потолка mem_limit, а railsserver спокоен — это не общая нехватка RAM, а неверно выставленная куча JVM. Если наоборот, растёт railsserver — смотрите число воркеров Puma (RAILS_MAX_THREADS и WEB_CONCURRENCY в .env), при overprovisioning воркеров Rails съедает память линейно от их числа.

Признаки того, что памяти реально не хватает на весь стек:

  • docker stats показывает, что несколько контейнеров упираются в лимит одновременно;
  • в dmesg появляются записи Out of memory: Killed process;
  • Elasticsearch периодически уходит в red статус кластера после рестарта — верный признак, что ему обрезали кучу ниже разумного.

Если сервер работает без запаса и падает под пиковой нагрузкой (утренний наплыв тикетов, массовая рассылка) — это отдельная и частая проблема, разобранная в статье что делать при нехватке RAM: своп, приоритеты OOM killer и когда действительно пора апгрейдить сервер, а когда достаточно подрезать лимиты сервисам.

Тюнинг PostgreSQL и Elasticsearch под маленький сервер

На серверах до 8 ГБ стандартные дефолты PostgreSQL и Elasticsearch слишком щедрые для одиночного инстанса — оба сервиса рассчитаны по умолчанию на то, что они единственные потребители памяти на машине. Для PostgreSQL в postgresql.conf (или через переменные окружения образа) имеет смысл выставить:

shared_buffers = 256MB
effective_cache_size = 768MB
work_mem = 8MB
maintenance_work_mem = 64MB

Эти значения — под сервер на 4-6 ГБ с несколькими сервисами рядом; для отдельной выделенной БД можно повышать shared_buffers до 25% RAM. Для Elasticsearch, кроме кучи JVM, важно ограничить число шардов на индекс — Zammad по умолчанию создаёт индексы с несколькими primary shard, и на маленьком кластере (фактически один узел) это чистый оверхед по памяти без пользы:

curl -X PUT "localhost:9200/_template/zammad" -H 'Content-Type: application/json' -d '{
  "index_patterns": ["zammad*"],
  "settings": { "number_of_shards": 1, "number_of_replicas": 0 }
}'

Такой шаблон нужно применить до первой полной переиндексации (rails r Zammad::Rebuild.run в контейнере railsserver), иначе он не подхватится для уже созданных индексов.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Можно ли запустить Zammad без Elasticsearch вообще?

Да, в настройках админки поиск можно переключить на встроенный (PostgreSQL-based). Это экономит 1-1.5 ГБ RAM, но поиск по вложениям и полнотекстовый поиск по длинным тикетам станут заметно хуже.

Хватит ли 2 ГБ RAM для продакшена?

Технически стек стартует и работает, но только без Elasticsearch и с 1-3 агентами. Уже на 5-10 агентах с почтовым каналом сервис начнёт уходить в своп при любом пике.

Redis обязателен для Zammad?

В официальном docker-compose да — он используется вебсокет-сервисом для realtime-обновлений между агентами. Памяти он просит немного, десятки мегабайт, и не является узким местом.

Что съедает память быстрее всего при росте базы тикетов?

Индексы Elasticsearch и кэш PostgreSQL — оба растут пропорционально числу тикетов и вложений, а не числу активных агентов. Регулярно проверяйте размер индекса Elasticsearch (curl localhost:9200/_cat/indices?v) и планируйте апгрейд заранее, а не по факту OOM.

Стоит ли выносить Elasticsearch на отдельный сервер?

Для команд от ~50 агентов или при большом объёме вложений — да, это снимает конкуренцию за память с остальным стеком и упрощает апгрейд каждого компонента отдельно.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →