MAATRIX / Блог / Сколько почтовых ящиков на одном сервере: IMAP-сессии как скрытый потолок

Сколько почтовых ящиков на одном сервере: IMAP-сессии как скрытый потолок

MAATRIX

Когда планируют, сколько почтовых ящиков влезет на сервер, первым делом считают место на диске: средний размер ящика умножают на число пользователей, добавляют запас под рост — и вроде бы всё сходится. А потом сервер с наполовину пустым диском начинает отваливаться под нагрузкой, хотя писем на нём вроде бы немного. Причина почти всегда одна: упёрлись не в место, а в число одновременных IMAP-сессий — в память, которую держит под них Dovecot, и в лимит файловых дескрипторов. Разберём, как посчитать этот потолок заранее, а не находить его в проде.

Почему упираются не в диск, а в сессии

Место на диске растёт предсказуемо и линейно: чем больше писем, тем больше байт, и эту цифру легко спрогнозировать на месяцы вперёд. IMAP-сессии ведут себя совсем иначе — это не статика, а живая, постоянно колеблющаяся нагрузка, которая зависит не от объёма почты, а от поведения клиентов.

Ключевая особенность IMAP (в отличие от POP3) — протокол спроектирован под постоянное соединение. Клиент логинится и держит сокет открытым часами, периодически посылая команду IDLE (RFC 2177), чтобы сервер мог мгновенно уведомить о новом письме без опроса (poll). Это удобно для пользователя — почта приходит "пушем" — но означает, что сессия живёт не секунды, а весь рабочий день, а то и сутки, потребляя память и дескриптор всё это время.

Второй фактор — у одного пользователя обычно не одна сессия, а несколько одновременно:

  • десктопный клиент (Outlook, Thunderbird) — держит постоянное IMAP-соединение, часто ещё одно фоновое для синхронизации папок;
  • мобильный клиент (iOS Mail, Gmail-app, Outlook Mobile) — своя IDLE-сессия, плюс периодические переподключения при смене сети Wi-Fi/LTE;
  • веб-почта (Roundcube и подобные) — отдельные, обычно короткие соединения на каждую загрузку страницы, но при активной работе в браузере тоже накапливаются.

В сумме один активный сотрудник, у которого настроена почта на телефоне, ноутбуке и иногда открыта веб-версия, — это не одна сессия, а часто две-четыре одновременно. Именно эта множественность, а не размер ящика, определяет реальную нагрузку на сервер.

Из чего складывается "вес" одной IMAP-сессии

У Dovecot двухступенчатая модель процессов, и это важно понимать, прежде чем считать ёмкость.

До аутентификации запрос принимает лёгкий процесс imap-login. Его задача — TLS-хендшейк и передача учётных данных в auth/anvil; сам по себе он почти ничего не весит и может обслуживать несколько соединений на процесс (это регулируется client_limit в блоке service imap-login).

После аутентификации соединение передаётся полноценному процессу imap, который открывает почтовый ящик. Именно этот процесс и есть "тяжёлая" часть сессии:

  • держит открытым сокет клиента и, как правило, отдельные файловые дескрипторы на индексные файлы ящика (dovecot.index, dovecot.index.log, dovecot.index.cache — Dovecot маппит их через mmap);
  • хранит в памяти буферы команд и состояние выбранной папки;
  • если включён полнотекстовый поиск (FTS) или Sieve-фильтрация — добавляет ещё файловые дескрипторы и память под их состояние.

Точную цифру RSS на один такой процесс для вашей инсталляции никто не назовёт заранее — она зависит от числа писем и папок в ящике, размера индексов, включённых плагинов. Ориентировочно (это именно ориентир, у вас может быть иначе) процесс imap после логина в спокойном состоянии занимает от нескольких мегабайт до пары десятков — и растёт, если пользователь держит открытыми много папок или идёт полнотекстовый поиск по большому ящику. Единственный надёжный способ узнать цифру для своего сервера — измерить:

# средний RSS живых imap-процессов
ps -eo pid,rss,vsz,cmd | grep '[i]map '

# кто сейчас подключён и сколько у него сессий
doveadm who

# детальнее по конкретному пользователю
doveadm who '*' | grep user@domain.com

doveadm who — самый быстрый способ увидеть реальную картину: логин, IP, число одновременных подключений с этого IP. Именно эти данные, снятые в час пик, а не прикидка "на глаз", и должны лечь в основу расчёта ёмкости.

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

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

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

Как посчитать реальную ёмкость сервера под IMAP-сессии

Расчёт идёт по двум независимым ресурсам — памяти и дескрипторам — и берётся минимум из двух.

По памяти. Сначала вычтите из общего объёма RAM всё, что сервер тратит не на IMAP: систему, Postfix/приём почты, антиспам, бэкапы, веб-почту, файловый кэш под индексы (его тоже стоит оставить, иначе диск станет узким местом уже на чтении). Оставшееся — бюджет под сессии:

доступно_под_imap_MB = RAM_всего − (система + postfix + antispam + прочее + запас)
макс_сессий ≈ доступно_под_imap_MB / средний_RSS_на_сессию_MB

Здесь средний_RSS_на_сессию_MB — та самая величина, которую вы измерили через ps, а не число из чужой статьи: на разных инсталляциях (размер ящиков, включённый FTS, версия и сборка Dovecot) она отличается в разы.

По дескрипторам. Каждая живая IMAP-сессия держит не один fd, а несколько (сокет + индексные файлы + опционально Sieve/FTS). Методику подсчёта расхода дескрипторов на одно соединение и инструменты для замера (lsof, /proc/<pid>/fd) подробно разбирает статья про расчёт дескрипторов на один запрос — принцип тот же, просто вместо HTTP-запроса единица измерения — IMAP-сессия. Итоговый лимит — меньшее из fs.file-max (система) и ulimit -n для пользователя, под которым работает Dovecot; про сами лимиты и как их поднять — в статье про настройку ulimit.

От сессий — к ящикам. Дальше нужен коэффициент "сколько сессий приходится на один активный ящик" — тот самый разброс в 2-4, о котором шла речь выше, — и коэффициент одновременной активности (не все заведённые ящики открыты одновременно; часть принадлежит людям в отпуске, уволенным сотрудникам, редко проверяемым архивным адресам). Оба коэффициента — не универсальные константы, их надо снимать со своей базы пользователей через doveadm who в реальный пиковый час, а не брать "среднюю температуру по больнице". Итоговая формула:

хостится_ящиков ≈ макс_сессий / (сессий_на_активный_ящик × доля_одновременно_активных)

Число хостящихся ящиков почти всегда получается заметно больше числа одновременных сессий — это нормально, если только вы не строите почту для организации, где 100% сотрудников сидят в клиенте с 9 до 18: тогда доля активности близка к единице, и запас нужен максимальный.

Настройки Dovecot, которые определяют потолок

Расчёт бесполезен, если сам Dovecot настроен так, что упирается в лимиты раньше, чем в реальные RAM и fd сервера. Три группы директив стоит проверить.

mail_max_userip_connections (conf.d/10-mail.conf) — сколько одновременных IMAP/POP3-соединений разрешено одному пользователю с одного IP. В типовом конфиге дистрибутивных пакетов это значение по умолчанию довольно скромное (в районе десятка) — проверьте свой файл, значение могло быть изменено при установке:

mail_max_userip_connections = 10

Если пользователь держит десктоп, телефон и веб-почту за одним NAT-адресом офиса (а не по домашнему интернету каждый со своим IP), лимит считается не на человека, а на пару "пользователь+IP" — и упереться в него реальнее, чем кажется.

Лимиты процессов (conf.d/10-master.conf) — это уже потолок на весь сервер, а не на пользователя:

service imap-login {
  process_limit = 200
  client_limit   = 1
}

service imap {
  process_limit = 500
}

process_limit для imap — это, по сути, и есть ваш "макс_сессий" из формулы выше, только заданный вручную, а не рассчитанный. Если поставить его больше, чем реально выдерживает память сервера, при пиковой нагрузке вмешается OOM-killer вместо аккуратного отказа в новых подключениях. Если поставить меньше — сервер будет отказывать в логине, имея свободную память. Оба случая — следствие того, что цифру в конфиге не сверили с расчётом.

anvil — служебный процесс Dovecot, который как раз и считает число подключений на пару "пользователь+IP" для mail_max_userip_connections; трогать его конфигурацию обычно не требуется, но полезно знать, что именно он — источник счётчиков, которые видно через doveadm who.

Отдельно стоит imap-hibernate — сервис, которого в старых инсталляциях может не быть включён, но который прицельно решает проблему "много IDLE-сессий висят и просто едят память". Он переводит долго простаивающие IMAP-соединения в облегчённое "спящее" состояние, освобождая память тяжёлого imap-процесса, но сохраняя саму TCP-сессию и способность мгновенно разбудить её при новом письме или команде клиента. Включается через mail_hibernate_timeout в conf.d/20-imap.conf — если у вас много пользователей с постоянно открытым мобильным клиентом, это первое, что стоит проверить перед покупкой дополнительной памяти.

Типичные симптомы, что вы упёрлись в лимит

Три разных лимита дают три разные картины в логах — и важно не перепутать их между собой.

  • Упёрлись в mail_max_userip_connections. В логе Dovecot (обычно /var/log/mail.log или journal) — строка вида Maximum number of connections from user+IP exceeded. Пользователь получает отказ выборочно: одно устройство уже подключено, второе или третье не может залогиниться, пока первое не отвалится по таймауту. Классика — сотрудник с несколькими устройствами за офисным NAT.
  • Упёрлись в fs.file-max или ulimit -n. В логах — Too many open files, причём часто не в самом Dovecot, а в соседних сервисах на той же машине, потому что лимит системный. Симптом отличает то, что затрагивает не одного пользователя, а всех разом, и часто совпадает по времени с ростом числа сессий, а не с действиями конкретного клиента.
  • Упёрлись в process_limit. Новые подключения не проходят, хотя ни memory, ни fd формально не кончились — просто Dovecot не запускает больше процессов imap, чем разрешено в конфиге. Диагностируется сравнением текущего числа процессов (ps -C imap | wc -l или вывод doveadm who по числу уникальных сессий) с заданным process_limit.
  • Упёрлись в реальную память. Здесь симптом жёстче — dmesg показывает срабатывания OOM-killer, убивающего процессы imap или imap-login. Пользователи видят не отказ в подключении, а обрывы уже установленных сессий, часто без внятной ошибки в клиенте — просто "переподключается".

Общая черта всех четырёх случаев: жалобы приходят волнами, привязанными к времени суток (утренний вход в офис, обеденный пик проверки почты с телефона), а не равномерно — потому что именно в эти окна одновременная активность ящиков максимальна.

Тюнинг vs апгрейд: что делать, когда упёрлись в потолок

Первый шаг — не увеличивать лимиты вслепую, а понять, какой из четырёх сработал, через логи и doveadm who в момент проблемы. Дальше варианты по цене:

  • Поднять mail_max_userip_connections, если проблема именно в нём и реальных ресурсов сервера хватает — это самое дешёвое изменение, правка одной строки и doveadm reload. Но помните: это не добавляет ёмкости, а просто разрешает больше сессий на пользователя, перекладывая давление на память и process_limit — их тоже придётся пересчитать.
  • Включить imap-hibernate, если много сессий висят в IDLE подолгу без активности — типовой случай для мобильных клиентов. Даёт заметную экономию памяти без апгрейда железа и без изменения поведения для пользователя.
  • Пересмотреть настройки веб-почты. Если Roundcube или другой webmail открывает новое IMAP-соединение на каждую загрузку страницы вместо переиспользования сессии — это лишняя нагрузка, которую можно снять конфигурацией самого webmail, а не сервера.
  • Добавить память и пересчитать process_limit — если измерения показывают, что реальный потолок ниже потребности, а не просто криво настроен. Это тот случай, когда апгрейд обоснован цифрами, а не паникой.
  • Развести нагрузку на несколько нод. Когда один сервер физически не тянет пиковую активность всех ящиков (крупная компания, все в клиенте одновременно), Dovecot поддерживает распределение через director — почтовые ящики закрепляются за конкретными бэкендами, а фронт распределяет соединения. Это уже архитектурное решение, и для него разумнее сразу считать конфигурацию выделенного сервера под корпоративную почту, чем донастраивать единственную машину до предела.

Если вы только разворачиваете почтовый сервер с нуля и ещё не сталкивались с этими лимитами на практике, посмотрите базовую установку Dovecot — там же стоит сразу заложить измерение RSS и doveadm who в мониторинг, чтобы не искать причину проблемы постфактум.

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

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

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

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

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

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

Сколько IMAP-сессий держит один активный ящик одновременно?

Единого числа нет — зависит от того, сколько устройств у пользователя и держит ли веб-почта постоянное соединение. Реалистичный диапазон для сотрудника с телефоном и ноутбуком — от двух до четырёх сессий; точную цифру для своей базы пользователей нужно снимать через doveadm who.

Можно ли просто поднять mail_max_userip_connections до большого значения и забыть про проблему?

Нет — это снимает один конкретный лимит, но не увеличивает ни память, ни process_limit, ни дескрипторы. Без пересчёта остальных параметров вы просто переносите точку отказа с "клиент не может подключиться" на "сервер падает под OOM".

POP3 создаёт такую же нагрузку, как IMAP?

Обычно нет. POP3-сессии в норме короткоживущие: клиент подключился, забрал почту, отключился. Проблема с числом одновременных сессий — это в первую очередь про IMAP с его постоянными соединениями и IDLE.

Как понять, в какой именно лимит упёрся сервер, если жалобы уже пошли?

Смотрите лог Dovecot на характерные строки (Maximum number of connections, Too many open files), dmesg на предмет OOM-killer и сравнивайте текущее число процессов imap с process_limit в конфиге. Три разных лимита дают три разных симптома, и лечатся они по-разному.

Стоит ли закладывать запас по сессиям заранее или можно донастроить по факту?

Лучше заложить запас с самого начала расчёта ёмкости (и по памяти, и по process_limit), потому что упор в лимит на проде — это не плавная деградация, а резкий отказ конкретным пользователям, и разбираться с этим приходится уже во время жалоб, а не спокойно.

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

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

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