Сколько RAM нужно для Apache Superset
Apache Superset обещает Tableau-уровень визуализации бесплатно и с открытым кодом — и в целом держит слово. Но стоит развернуть его на скромной VPS «на попробовать», как через пару дней active работы с дашбордами начинаются OOM-килы, зависшие запросы и gunicorn-воркеры, падающие один за другим. Проблема не в самом Superset, а в том, что это не однопроцессный сервис, а связка из веб-приложения, брокера очередей и воркеров для тяжёлых запросов — и память нужно считать под каждый компонент отдельно.
Содержание
- Из чего вообще состоит потребление памяти Superset
- Сколько нужно для теста и одиночной работы
- Продакшн: считаем по gunicorn-воркерам
- Метаданные-БД и источник данных — не путайте два разных потребления памяти
- Docker Compose с лимитами памяти — рабочий пример
- Что реально снижает потребление памяти
- Superset на фоне альтернатив по памяти
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Из чего вообще состоит потребление памяти Superset
Superset — это Flask-приложение поверх SQLAlchemy, которое само по себе не хранит аналитические данные: оно подключается к вашим источникам (PostgreSQL, ClickHouse, MySQL, Trino и так далее) и рендерит результаты запросов. Но в развёртывании, пригодном для реальной работы, вокруг этого ядра стоит ещё три обязательных элемента:
- Веб-сервер (gunicorn) — обслуживает HTTP-запросы, рендерит дашборды, отдаёт API. Каждый воркер — это отдельный процесс со своей копией приложения в памяти.
- Celery worker — выполняет асинхронные запросы к источникам данных (SQL Lab, тяжёлые чарты с
asyncрендерингом). Без него длинные запросы либо блокируют веб-воркер, либо упираются в таймаут. - Redis (или другой брокер + кеш-бэкенд) — хранит очередь задач для Celery и кеширует результаты запросов и рендеры чартов.
- Метаданные-БД (обычно PostgreSQL) — хранит сами дашборды, слайсы, права доступа. Она отдельная от источников аналитических данных, но тоже требует памяти на своей стороне.
Итого даже "простой" Superset — это минимум 4 процесса, которые надо уместить в память сервера одновременно. Официальная документация проекта прямо говорит, что для нормальной работы нужен отдельный источник данных, отдельная метаданные-БД и отдельный message queue — то есть Superset изначально проектировался не как моностек для VPS на 1 ГБ, а как компонент более крупной инфраструктуры.
Сколько нужно для теста и одиночной работы
Если вы разворачиваете Superset, чтобы посмотреть на интерфейс, подключить один источник и покрутить несколько чартов в одиночку — с этим справится и скромная конфигурация:
| Профиль | RAM | CPU | Что уместится |
|---|---|---|---|
| Пробный запуск (SQLite metadata, 1 gunicorn worker) | 2 ГБ | 1 vCPU | Работает, но еле-еле — риск OOM при тяжёлых запросах |
| Одиночная работа, PostgreSQL metadata + Redis | 4 ГБ | 2 vCPU | Комфортно для 1 пользователя, лёгкие дашборды |
| Небольшая команда (3-5 человек) | 8 ГБ | 4 vCPU | 2-3 gunicorn воркера + 1 celery worker + Redis |
На 2 ГБ Superset формально стартует — есть даже docker-compose.yml из официального репозитория для знакомства с продуктом. Но использовать SQLite как метаданные-БД в проде не стоит: SQLite не переживает параллельную запись от нескольких воркеров и быстро становится узким местом по блокировкам. Как только вы переходите на PostgreSQL для метаданных (что рекомендует сама документация Superset), закладывайте от 4 ГБ — сам PostgreSQL под лёгкой нагрузкой съедает 200-400 МБ, плюс Redis (обычно 50-150 МБ), плюс сам Superset-процесс.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверПродакшн: считаем по gunicorn-воркерам
Основной драйвер потребления памяти в проде — количество gunicorn-воркеров, обслуживающих веб-интерфейс. Стандартная формула для gunicorn (не специфичная для Superset, но применимая к нему) — (2 × число ядер) + 1. На 4-ядерном сервере это 9 воркеров, что для Superset обычно избыточно: он не такой лёгкий, как условный REST API на Flask, и каждый воркер тянет за собой загруженные модули визуализации, драйверы БД, кеш SQLAlchemy.
На практике для Superset чаще стартуют с меньшего числа и смотрят на реальную нагрузку:
# docker-compose.yml, фрагмент — команда запуска superset_app
command: >
gunicorn
--bind 0.0.0.0:8088
--workers 4
--worker-class gthread
--threads 4
--timeout 60
"superset.app:create_app()"
Ориентировочно каждый gunicorn-воркер Superset в простое занимает 150-300 МБ, а под нагрузкой с большими датасетами в SQL Lab может кратковременно уходить за 500 МБ-1 ГБ — это сильно зависит от объёма данных, которые попадают в память при рендере таблицы результатов. Это ориентир, не измеренный бенчмарк: у вас цифры будут отличаться в зависимости от источников данных, объёма выгружаемых строк и того, включён ли ROW_LIMIT.
Отдельно стоит Celery worker — он выполняет тяжёлые SQL-запросы асинхронно, чтобы не блокировать веб-воркеры. Один Celery worker с параллелизмом 2-4 (--concurrency) добавляет ещё 200-500 МБ в зависимости от того, что именно он в моменте обрабатывает.
Грубая прикидка для команды из 10-20 активных пользователей, с несколькими подключёнными источниками данных и включённым асинхронным рендерингом чартов:
- 4 gunicorn-воркера: ~1-1.5 ГБ
- 1 Celery worker (concurrency 2): ~0.5-1 ГБ
- Redis: ~0.2-0.5 ГБ (зависит от объёма кеша)
- PostgreSQL metadata: ~0.5-1 ГБ
- Запас на пики (большие SQL Lab-запросы, экспорт CSV): ~1-2 ГБ
Итого разумный минимум — 8 ГБ, комфортный уровень для команды — 16 ГБ. Если в SQL Lab пользователи гоняют запросы, возвращающие сотни тысяч строк, или дашборды строятся поверх тяжёлых агрегаций без предагрегации на стороне источника — закладывайте больше, потому что именно результаты запросов, временно попадающие в память воркера перед отрисовкой, а не сам Superset, становятся главным потребителем.
Метаданные-БД и источник данных — не путайте два разных потребления памяти
Частая ошибка при планировании ресурсов — забыть, что Superset сам по себе не хранит и не обрабатывает аналитические данные. Вся тяжёлая работа (агрегация, джойны, сортировка миллионов строк) происходит на стороне источника — будь то PostgreSQL, ClickHouse или Trino. Superset лишь отправляет SQL и получает результат, который дальше рендерит.
Это значит, что память нужно планировать раздельно:
- Память под сам Superset (веб + celery + redis + metadata-БД) — обычно 4-16 ГБ в зависимости от числа пользователей и воркеров, как описано выше.
- Память под источник аналитических данных — считается отдельно и зависит от объёма данных и характера запросов. Если источник — ClickHouse, у него свои требования к RAM, обычно куда более серьёзные, чем у самого Superset.
Частая архитектура — Superset на одном сервере (веб-слой, лёгкий по сравнению с базой), а аналитические данные — на отдельном, более мощном. Разносить их разумно ещё и потому, что профили нагрузки разные: Superset пиково грузит CPU и немного RAM на рендер, а аналитическая СУБД жрёт RAM и диск под сканы и агрегации.
Docker Compose с лимитами памяти — рабочий пример
Ниже — упрощённый docker-compose.yml для развёртывания Superset с явными лимитами памяти на каждый сервис, рассчитанный на сервер с 8 ГБ RAM:
version: "3.8"
services:
superset-db:
image: postgres:16
restart: unless-stopped
environment:
POSTGRES_DB: superset
POSTGRES_USER: superset
POSTGRES_PASSWORD: ${SUPERSET_DB_PASSWORD}
volumes:
- superset_db_data:/var/lib/postgresql/data
deploy:
resources:
limits:
memory: 1g
redis:
image: redis:7-alpine
restart: unless-stopped
deploy:
resources:
limits:
memory: 512m
superset:
image: apache/superset:latest
restart: unless-stopped
depends_on:
- superset-db
- redis
environment:
SUPERSET_SECRET_KEY: ${SUPERSET_SECRET_KEY}
ports:
- "8088:8088"
command: >
gunicorn --bind 0.0.0.0:8088 --workers 3
--worker-class gthread --threads 4 --timeout 60
"superset.app:create_app()"
deploy:
resources:
limits:
memory: 3g
superset-worker:
image: apache/superset:latest
restart: unless-stopped
depends_on:
- superset-db
- redis
command: celery --app=superset.tasks.celery_app:app worker --concurrency=2
deploy:
resources:
limits:
memory: 1.5g
volumes:
superset_db_data:
Сумма лимитов здесь — 6 ГБ, что оставляет запас на ОС и файловый кеш на сервере с 8 ГБ. Ключевой момент: секция deploy.resources.limits в связке с обычным docker compose up (без Swarm) применяется не во всех версиях Docker Compose одинаково — проверьте, что ваша версия действительно её учитывает, иначе лимиты будут проигнорированы и контейнер расползётся по всей доступной памяти хоста.
Что реально снижает потребление памяти
Несколько настроек, которые ощутимо влияют на память Superset в проде, если у вас её впритык:
ROW_LIMITвsuperset_config.py— ограничивает число строк, которые Superset подтягивает из источника для рендера чарта. По умолчанию это уже небольшое число, но если кто-то его увеличил "чтобы видеть больше данных", память на каждый такой запрос вырастет пропорционально.SQLLAB_TIMEOUTи лимит строк в SQL Lab — отдельный лимит для интерактивных запросов, которые пользователи гоняют руками. Без разумного потолка один "SELECT * FROM big_table" без LIMIT способен утащить воркер в OOM.- Кеширование результатов через Redis (
CACHE_CONFIG/DATA_CACHE_CONFIG) — снижает число повторных обращений к источнику и, как следствие, число "тяжёлых" моментов в памяти веб-воркера. Настраивается TTL кеша под частоту обновления ваших данных. - Асинхронный рендеринг чартов через Celery (
FEATURE_FLAGS = {"GLOBAL_ASYNC_QUERIES": True}) — переносит нагрузку по построению тяжёлых чартов с gunicorn-воркера на отдельный Celery-воркер, что позволяет держать веб-слой отзывчивым и не раздувать память каждого web-процесса. - Меньше воркеров с бОльшим числом потоков (
--worker-class gthread --threads N) вместо большого числа sync-воркеров — часто экономнее по памяти, поскольку потоки в рамках одного процесса делят загруженные модули, а не дублируют их.
Если после всех настроек память всё равно уходит в потолок регулярно, а не эпизодически — это, скорее, сигнал не тюнить Superset ещё сильнее, а добавить памяти на сервере или разнести компоненты по нескольким машинам.
Superset на фоне альтернатив по памяти
Если Superset для вашей задачи избыточен по требованиям к ресурсам, стоит сравнить его с более лёгкими BI-инструментами:
| Инструмент | Минимум для старта | Комфортный продакшн | Особенность по памяти |
|---|---|---|---|
| Apache Superset | 4 ГБ | 8-16 ГБ | Gunicorn + Celery + Redis + metadata-БД — четыре компонента |
| Metabase | 1-2 ГБ | 4 ГБ | Один Java-процесс (JVM), проще в развёртывании, но менее гибкая визуализация |
| Redash | 2 ГБ | 4-8 ГБ | Похожая на Superset архитектура (worker + Redis), но легче за счёт меньшего числа фич |
Superset выигрывает у Metabase и Redash богатством визуализаций и гибкостью (кастомные чарты, SQL Lab с полноценным редактором, ролевая модель доступа), но платит за это более сложной архитектурой и, соответственно, более высоким порогом входа по памяти. Если нужен просто "дашборд с графиками для команды из 5 человек без сложных прав доступа" — присмотритесь к Metabase или Redash, они стартуют на заметно более скромном сервере.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Superset упадёт, если памяти не хватит на секунду пиковой нагрузки?
Скорее всего да — OOM killer в Linux завершает процесс, потребляющий больше всего памяти, когда её физически не хватает. Обычно первой жертвой становится gunicorn-воркер, обрабатывающий самый тяжёлый запрос в моменте. Настройте своп как страховку (см. материал про размер swap для VPS), но не рассчитывайте на него как на постоянное решение — своп сильно просаживает отзывчивость интерфейса.
Можно ли обойтись без Celery для небольшой команды?
Технически да — Superset может работать в синхронном режиме, без асинхронных запросов. Но тогда любой тяжёлый чарт блокирует gunicorn-воркер на всё время выполнения запроса, и при нескольких одновременных пользователях интерфейс начинает подвисать. Для команды больше 3-5 человек Celery стоит подключать сразу.
Сколько памяти закладывать под Redis отдельно?
Для типичного использования (очередь Celery + кеш чартов) обычно достаточно 256-512 МБ. Если включаете кеширование данных с долгим TTL для больших датасетов, Redis может вырасти заметнее — стоит настроить maxmemory с политикой вытеснения (allkeys-lru), чтобы он не разрастался бесконтрольно.
Стоит ли ставить Superset и источник данных (например, ClickHouse) на один сервер?
Для теста — можно, для прода — лучше разнести. У аналитической СУБД и веб-слоя Superset разные профили нагрузки, и на одном сервере они будут конкурировать за память в самый неподходящий момент — обычно во время построения тяжёлого дашборда.
PostgreSQL для метаданных Superset — это тот же сервер, что и для аналитических данных?
Не обязательно и чаще всего лучше отдельный: метаданные-БД хранит только дашборды, права и настройки — она маленькая и лёгкая. Смешивать её с боевой аналитической базой не стоит по соображениям изоляции нагрузки и прав доступа.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →