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

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

MAATRIX

SonarQube редко падает от нехватки CPU — он падает от нехватки памяти, причём тихо: сначала тормозит анализ, потом отваливается встроенный Elasticsearch с ошибкой bootstrap checks, а потом Compute Engine начинает копить очередь задач, которая никогда не разгребается. Разберём, из чего складывается потребление RAM у SonarQube, сколько закладывать под разные размеры команд и как настроить JVM-параметры, чтобы сервер не падал в самый неподходящий момент — например, посреди ночного прогона CI.

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

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

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

Из чего состоит SonarQube и почему он ест так много памяти

SonarQube — это не один процесс, а связка из нескольких JVM, каждая со своей кучей:

  • Web Server — отдаёт интерфейс и API, обслуживает запросы плагинов и CI-раннеров;
  • Compute Engine (CE) — асинхронно обрабатывает отчёты анализа, которые присылают сканеры; именно здесь происходит основная нагрузка после того, как sonar-scanner отработал на стороне CI;
  • Search Server — встроенный Elasticsearch, в котором хранится индекс для поиска по issues, hotspots и метрикам;
  • база данных — PostgreSQL (единственная официально поддерживаемая СУБД для продакшена, начиная с версии 8.x линейка на MySQL и Oracle убрана из новых релизов) — как правило, отдельный процесс, часто вообще отдельный сервер.

Каждый из первых трёх компонентов — это отдельная JVM со своим heap, и они не делят память автоматически: сколько вы выделили Elasticsearch через sonar.search.javaOpts, столько он и займёт, даже если Web Server в этот момент простаивает. Поэтому расчёт RAM для SonarQube — это по сути сумма трёх независимых Java-куч плюс overhead ОС, плюс память под PostgreSQL, если база живёт на том же сервере.

Отдельная деталь, которая часто ломает голову новичкам: в Community Edition Compute Engine работает только в один поток (sonar.ce.workerCount фактически зафиксирован на 1) — параллельная обработка отчётов нескольких проектов доступна только в Developer Edition и выше. Это значит, что при большом потоке анализов из CI очередь в Community Edition будет копиться последовательно независимо от того, сколько RAM вы добавите — узкое место здесь не память, а лицензия.

Сколько RAM нужно: ориентировочные цифры по размеру команды

Официальный минимум SonarQube (по документации) — довольно скромный и рассчитан на ознакомительный запуск, а не на боевую эксплуатацию. На практике реальное потребление сильно зависит от объёма кодовой базы, числа языков в проекте и частоты запусков анализа. Ниже — ориентировочные цифры, которые стоит воспринимать как отправную точку, а не как гарантию: на вашем проекте с 15 языками и монорепо на 2 млн строк цифры будут другими.

Профиль использованияРазмер кодовой базыRAM сервераvCPU
Тест / один разработчик, редкие сканыдо 50 тыс. строк4 ГБ2
Малая команда, 1 проект в CI ежедневно50–300 тыс. строк8 ГБ2–4
Средняя команда, несколько проектов, частые сканы300 тыс.–1 млн строк16 ГБ4
Крупный монорепо или много проектов параллельно1 млн+ строк32 ГБ и больше8+

Важный нюанс: сама SonarQube-инсталляция (Web + CE + ES) — это не то же самое, что память, которая нужна sonar-scanner на этапе сбора данных. Сканер обычно запускается на стороне CI-раннера (Jenkins-агент, GitLab Runner) и туда закладывается отдельная память — под него тоже нужен heap, особенно для больших Java/C++ проектов с полным анализом покрытия. Если у вас Jenkins и GitLab Runner крутятся на том же сервере, что и SonarQube, RAM нужно считать по сумме, а не по максимуму из компонентов — подробнее про типовую нагрузку CI-стека можно посмотреть в статье про настройку VPS под разработчика и CI/CD.

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

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

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

Настройка памяти JVM: три независимых кучи

Все параметры памяти задаются в $SONARQUBE_HOME/conf/sonar.properties (при установке "с нуля" на VPS) или через переменные окружения (в Docker). Актуальные ключи:

# Web-сервер — интерфейс, API, аутентификация
sonar.web.javaOpts=-Xmx1G -Xms256m -XX:+HeapDumpOnOutOfMemoryError

# Compute Engine — обработка отчётов анализа
sonar.ce.javaOpts=-Xmx2G -Xms512m -XX:+HeapDumpOnOutOfMemoryError

# Elasticsearch (поиск/индекс) — самый чувствительный к памяти компонент
sonar.search.javaOpts=-Xmx2G -Xms2G -XX:+UseG1GC -server

Значения по умолчанию в свежих версиях заметно скромнее (это отправная точка для трафика "из коробки", не для продакшена) — при установке обязательно сверьтесь с актуальным sonar.properties вашей версии, а не берите цифры на веру из старых мануалов. Общее правило: для Elasticsearch -Xms и -Xmx должны быть равны — это стандартная рекомендация самого Elasticsearch, она исключает паузы на изменение размера кучи в рантайме.

Ещё три системных требования, без которых SonarQube просто не стартует — встроенный Elasticsearch проверяет их при загрузке (bootstrap checks) и завершает процесс, если условия не выполнены:

# увеличить лимит memory-mapped areas — жёсткое требование Elasticsearch
sudo sysctl -w vm.max_map_count=262144
echo "vm.max_map_count=262144" | sudo tee -a /etc/sysctl.conf

# лимиты на файловые дескрипторы и число процессов для пользователя sonarqube
echo "sonarqube   -   nofile   65536" | sudo tee -a /etc/security/limits.conf
echo "sonarqube   -   nproc    4096"  | sudo tee -a /etc/security/limits.conf

Если запускаете SonarQube в Docker — vm.max_map_count всё равно нужно выставлять на хосте: это параметр ядра, контейнер его не переопределяет.

Elasticsearch и swap — источник самых частых падений

Отдельно про память Elasticsearch — это тот компонент, где экономия обходится дороже всего. Если у ES не хватает heap, он не просто тормозит — он может уйти в OutOfMemoryError и утянуть за собой весь процесс SonarQube, а восстановление индекса после аварийного завершения занимает время и грузит диск. Общие правила для встроенного ES в SonarQube такие же, как для обычного Elasticsearch:

  • не давайте heap больше половины физической RAM сервера — вторая половина нужна файловому кэшу ОС, через который ES реально читает индекс с диска;
  • не превышайте ~31–32 ГБ heap даже на очень мощных серверах — при переходе этой границы JVM теряет compressed oops и эффективность памяти резко падает;
  • по возможности избегайте swap для процесса ES — своп превращает паузы сборщика мусора в затяжные подвисания. Если на сервере вообще есть своп, стоит понимать как правильно настроить его размер под VPS, чтобы он не подменял собой нехватку физической памяти, а служил лишь страховкой.

Если сервер регулярно уходит в OOM именно на Elasticsearch — это почти всегда сигнал не "добавить ещё гигабайт", а "проект слишком большой для текущего sizing", и стоит пересчитать по таблице выше на следующий тир.

Установка в Docker Compose с явными лимитами памяти

Для тестового или небольшого прод-окружения удобнее всего поднимать SonarQube с PostgreSQL через Docker Compose — так лимиты памяти видны в одном файле и не потеряются при обновлении:

services:
  sonarqube:
    image: sonarqube:community
    depends_on:
      - db
    environment:
      SONAR_JDBC_URL: jdbc:postgresql://db:5432/sonar
      SONAR_JDBC_USERNAME: sonar
      SONAR_JDBC_PASSWORD: ${SONAR_DB_PASSWORD}
      SONAR_WEB_JAVAOPTS: -Xmx1G -Xms256m
      SONAR_CE_JAVAOPTS: -Xmx2G -Xms512m
      SONAR_SEARCH_JAVAOPTS: -Xmx2G -Xms2G
    ulimits:
      nofile: { soft: 65536, hard: 65536 }
      nproc: 4096
    mem_limit: 6g
    mem_reservation: 4g
    volumes:
      - sonarqube_data:/opt/sonarqube/data
      - sonarqube_extensions:/opt/sonarqube/extensions
      - sonarqube_logs:/opt/sonarqube/logs
    ports:
      - "9000:9000"
    restart: unless-stopped

  db:
    image: postgres:16
    environment:
      POSTGRES_USER: sonar
      POSTGRES_PASSWORD: ${SONAR_DB_PASSWORD}
      POSTGRES_DB: sonar
    volumes:
      - postgresql_data:/var/lib/postgresql/data
    mem_limit: 2g
    restart: unless-stopped

volumes:
  sonarqube_data:
  sonarqube_extensions:
  sonarqube_logs:
  postgresql_data:

На хосте перед запуском не забудьте выставить vm.max_map_count (см. выше) — контейнер стартует, но встроенный ES упадёт сразу при первом старте с понятной ошибкой в логах, если ядро хоста этого не позволяет. mem_limit в примере — 6 ГБ на сам SonarQube плюс 2 ГБ на PostgreSQL, итого сервер нужен не меньше 8–10 ГБ с запасом под ОС и файловый кэш. Если PostgreSQL уже крутится у вас отдельно под другие проекты — сравните варианты в статье PostgreSQL или MySQL для сервера, хотя для SonarQube выбор не стоит: официально поддерживается только PostgreSQL.

Как посчитать RAM под конкретный проект, а не по таблице

Таблица выше — это средняя температура по больнице. Чтобы прикинуть память под свой случай точнее, учитывайте четыре фактора:

  1. Число строк кода и языков. Многоязычный монорепо (Java + JS + Python в одном проекте) требует больше памяти на этапе Compute Engine, чем однородный проект того же размера — каждый язык обрабатывается своим анализатором.
  2. Частота и параллельность сканов. Если 10 CI-пайплайнов присылают отчёты SonarQube одновременно в час пик, а вы на Community Edition с одним CE-воркером — очередь будет расти, и лишняя RAM здесь не поможет: нужен либо Developer Edition с параллельными воркерами, либо более редкий график анализа.
  3. Глубина истории и retention. SonarQube хранит историю метрик и issues — чем дольше retention, тем больше индекс Elasticsearch и тем ощутимее нагрузка на поиск при открытии дашбордов.
  4. Плагины. Дополнительные языковые плагины (например, для ABAP, PL/SQL, специфичных фреймворков) добавляют собственный overhead при анализе — на глаз незаметно, но на графиках памяти видно.

Если сомневаетесь — закладывайте на один тир выше расчётного и наблюдайте за docker stats или top в первую неделю реальной нагрузки: SonarQube хорошо показывает узкое место буквально за пару дней активного использования, и всегда проще увеличить лимиты, чем гадать заранее.

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

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

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

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

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

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

SonarQube упадёт с ошибкой "max virtual memory areas vm.max_map_count is too low" — что делать?

Это стандартная bootstrap-проверка встроенного Elasticsearch. Выполните sudo sysctl -w vm.max_map_count=262144 и добавьте эту строку в /etc/sysctl.conf, чтобы значение сохранилось после перезагрузки. Для Docker параметр всё равно задаётся на хосте, а не в контейнере.

Можно ли запустить SonarQube на 2 ГБ RAM?

Формально стартует, но это подходит только для короткого ознакомительного теста на игрушечном проекте. При первом же реальном скане с несколькими файлами велика вероятность OOM у Elasticsearch или Compute Engine — для стабильной работы закладывайте минимум 4 ГБ даже под одиночного разработчика.

Нужно ли выделять память отдельно под sonar-scanner на CI-раннере?

Да, это отдельный процесс со своим heap (обычно задаётся через SONAR_SCANNER_OPTS или sonar.scanner.javaOpts), и он работает не на сервере SonarQube, а на агенте CI (Jenkins/GitLab Runner). Если раннер и сервер SonarQube на одной машине, считайте RAM по сумме обоих.

PostgreSQL обязательно нужен отдельным сервером?

Нет, для небольших команд база спокойно живёт на одном сервере с SonarQube — как в примере docker-compose выше. Разносить стоит, когда база начинает конкурировать за память с Elasticsearch, или когда нужна отдельная стратегия бэкапов и мониторинга.

Что если памяти не хватает уже после нескольких месяцев эксплуатации?

Чаще всего это не утечка, а рост индекса Elasticsearch вместе с историей проекта. Проверьте retention-политику хранения issues и метрик в настройках, и при необходимости мигрируйте на следующий тир по RAM.

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

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

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