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

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

MAATRIX

Если вы уже щупали MinIO для геораспределённого кластера, то знаете боль: он проектировался под один дата-центр с быстрой сетью между нодами, и стоит развести узлы по разным континентам — начинаются проблемы с erasure coding и требованиями к латентности. Garage изначально писали для другого сценария — кластер из нод в разных локациях, разное железо, разная сеть, никакого доверия к однородности инфраструктуры. И один из практических вопросов, который встаёт сразу: сколько оперативной памяти закладывать на узел, чтобы Garage не упал под нагрузкой и не тормозил на листинге бакетов.

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

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

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

Что вообще ест память в Garage

Garage написан на Rust, и в состоянии покоя это один из самых экономных S3-совместимых серверов, которые вы найдёте. Пустой узел с несколькими небольшими бакетами держится в районе 40-80 МБ резидентной памяти — это меньше, чем у MinIO в холостом режиме. Но реальный расход растёт по трём направлениям, и их стоит разбирать по отдельности.

Первое — метаданные. Garage хранит индекс объектов в собственной таблице (на базе LMDB или Sled, в зависимости от версии и конфигурации metadata_db), и часть этого индекса кэшируется в памяти для быстрого листинга и поиска по ключам. Чем больше объектов в кластере, тем больше памяти уходит на кэш метаданных — это единственный параметр, который линейно растёт с количеством файлов, а не с их размером.

Второе — буферы приёма и отдачи данных. Каждый одновременный upload или download держит в памяти чанк данных (по умолчанию Garage режет объекты на блоки — block_size, обычно 1 МиБ) плюс накладные расходы на репликацию этого блока на соседние узлы. При параллельных загрузках это умножается на число одновременных соединений.

Третье — фоновые задачи: resync между узлами, garbage collection старых версий, проверка целостности блоков (scrub). Они разовые по нагрузке, но в момент восстановления после падения ноды или добавления нового узла в кластер память может подскочить заметно выше базового уровня.

Минимальная конфигурация для теста и небольшого проекта

Для одного узла с несколькими гигабайтами данных, без серьёзной нагрузки — бэкапы, личное хранилище, тестовый стенд:

СценарийRAMvCPUДиск
Тест/PoC, 1 узел512 МБ - 1 ГБ110-20 ГБ SSD
Личный проект, до 100 ГБ данных1-2 ГБ1-2по объёму данных + 20%
Малый прод, 3 узла, до 500 ГБ на узел2-4 ГБ на узел2SSD, RAID не обязателен

На практике Garage стабильно запускается и на 512 МБ, но это грань — если запускать рядом с ним ещё что-то (Nginx как reverse proxy, systemd, обычный набор фоновых процессов Ubuntu), лучше сразу брать 1 ГБ. Официальная документация проекта прямо называет 1-2 ГБ комфортным минимумом для продакшена малого масштаба, а на слабом железе (Raspberry Pi, старые мини-ПК) Garage действительно работает — это одна из заявленных целей проекта, в отличие от того же MinIO, где на маломощных ARM-нодах уже начинаются нюансы с erasure coding.

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

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

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

Расчёт для геораспределённого кластера

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

  • Больше "зависших" в полёте запросов. При высокой латентности между репликами Garage держит в памяти больше незавершённых операций записи, пока ждёт подтверждения от удалённых узлов.
  • Больше конфликтов версий (CRDT-логика). Garage использует CRDT для разрешения конфликтов между репликами без блокировок — это надёжно, но при частой записи в геораспределённом кластере растёт объём служебных данных на разрешение этих конфликтов, и часть этого тоже кэшируется в памяти.
  • Repair/resync после разрыва связи. Если канал между дата-центрами моргнул на несколько минут (а на трансконтинентальных линках это не редкость), после восстановления связи запускается repair — и в этот момент память может вырасти в 1.5-2 раза от базового уровня, пока узлы досинхронизируют данные.

Практический расчёт для геораспределённого кластера из 3+ узлов с репликацией replication_factor = 3:

базовая память узла: 300-500 МБ
+ кэш метаданных: ~1 ГБ на каждые 10-20 млн объектов
+ буфер на параллельные операции: 200-400 МБ на каждые 50 одновременных upload/download
+ запас на resync после разрыва связи: x1.5-2 от суммы выше

Для конкретики: кластер из 3 узлов, по 2-5 млн объектов на узел, умеренная нагрузка (десятки одновременных клиентов) — закладывайте 2-4 ГБ RAM на узел. Если ожидаете нестабильные каналы между локациями (что для геораспределённых кластеров скорее норма, чем исключение), накидывайте ещё гигабайт запаса на пиковый resync, чтобы не поймать OOM-killer в самый неподходящий момент — обычно сразу после восстановления сети, когда узлы одновременно бросаются наверстывать пропущенное.

Конфигурация узла: что реально влияет на память

В garage.toml есть несколько параметров, которые напрямую управляют аппетитом Garage к памяти:

[s3_api]
s3_region = "garage-eu"
api_bind_addr = "[::]:3900"

# Размер блока, на которые режутся объекты.
# Меньше блок — больше метаданных на объект, но точнее resync после сбоя.
# Больше блок — меньше метаданных, но грубее гранулярность при восстановлении.
block_size = "1MiB"

[block_manager]
# Сколько блоков разрешено держать в памяти одновременно
# при параллельных операциях. Прямой рычаг для RAM на нагруженном узле.
compression_level = 1

Уменьшение compression_level снижает нагрузку на CPU за счёт диска, но не сильно влияет на RAM. А вот число одновременных клиентских соединений, которое вы разрешаете на reverse proxy перед Garage (Nginx/Caddy), — это как раз тот рычаг, которым проще всего ограничить пиковое потребление памяти, чем крутить настройки самого Garage.

Дополнительно на потребление влияет режим хранения метаданных: LMDB (Lightning Memory-Mapped Database) быстрее и по умолчанию рекомендуется для новых кластеров, но активно использует mmap — часть "виртуальной" памяти процесса будет казаться в htop больше, чем реально резидентная (RSS). Не пугайтесь, если VSZ у процесса Garage выглядит внушительно — смотрите именно на RSS и на реальное давление на своп.

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

Garage отдаёт метрики в формате Prometheus (эндпоинт /metrics на административном порту), и это самый надёжный способ не гадать, а видеть реальную картину:

curl -s http://127.0.0.1:3903/metrics | grep -E 'garage_|process_resident'

Ключевые сигналы, что узлу тесно по памяти:

  • растущий process_resident_memory_bytes без выхода на плато при стабильной нагрузке;
  • рост числа page faults (видно через node_vmstat_pgmajfault в связке с node_exporter) — значит, ядро уже подкидывает страницы в своп;
  • увеличение latency на S3-операциях именно на "тяжёлых" узлах кластера — часто первый симптом нехватки RAM для кэша метаданных, а не проблема с диском.

Если у вас уже поднят Prometheus + Grafana для остальной инфраструктуры, добавить сюда Garage — вопрос одного job в конфиге scrape. Если стека мониторинга пока нет, проще стартовать с готового решения — на сервере это разворачивается за один проход, без ручной сборки exporter'ов и дашбордов с нуля.

Garage vs MinIO: разница в требованиях к памяти

Раз тема близка к MinIO, стоит явно проговорить разницу, потому что запросы "сколько RAM нужно для..." у обоих решений похожи, а ответы — нет.

GarageMinIO
Минимум для теста512 МБ1-2 ГБ
Комфортный минимум для прод-узла1-2 ГБ4 ГБ+
Геораспределённый кластер, разная латентность узловШтатный сценарийНе рекомендуется официально
Erasure coding между удалёнными узламиНе требуется (репликация проще)Требует низкой латентности
Расход на слабом железе (ARM, старые VPS)Хорошо переноситОщутимо тяжелее

Если у вас однородный кластер в одном дата-центре с быстрой сетью между нодами и нужна максимальная производительность на больших объёмах — MinIO по-прежнему сильный вариант, и мы разбирали, как его установить на VPS и сколько памяти он потребует. Но если узлы разнесены географически, каналы между ними нестабильны, а железо разнородное — Garage экономнее по памяти и устойчивее по архитектуре именно в этом сценарии. Разбор, что выгоднее в схожей задаче резервного копирования, есть в статье MinIO или UrBackup: что выгоднее и когда.

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

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

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

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

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

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

Хватит ли 1 ГБ RAM для продакшен-узла Garage?

Для небольшой нагрузки — да, Garage на этом объёме работает стабильно. Но это без запаса на resync после сбоя сети и без учёта других процессов на сервере (Nginx, systemd, логи). Для реального продакшена, даже маленького, разумнее закладывать 2 ГБ.

Растёт ли потребление RAM линейно с объёмом хранимых данных?

Нет, напрямую — нет. Память в первую очередь зависит от количества объектов (метаданные) и от числа параллельных операций, а не от суммарного объёма данных на диске. Хранилище на 10 ТБ из тысячи крупных файлов съест меньше RAM, чем хранилище на 100 ГБ из десяти миллионов мелких.

Что будет, если памяти не хватит во время resync?

OOM-killer убьёт процесс Garage, узел выпадет из кластера, при возврате online resync начнётся заново. Данные не теряются благодаря репликации на другие узлы, но лучше не доводить до этого — настройте алерт на память заранее.

Нужен ли своп (swap) на узлах Garage?

Небольшой своп (1-2 ГБ) как страховка на случай кратковременного пика — разумная практика, особенно на VPS с фиксированным лимитом RAM. Как правильную заложить своп с нуля, мы разбирали в статье про настройку swap и производительности на Debian 12. Но полагаться на своп как на постоянное решение нехватки памяти не стоит — это подстраховка, а не архитектура.

Влияет ли выбор metadata_db (LMDB vs Sled) на объём RAM?

Да, но не напрямую в сторону "больше/меньше" — LMDB использует mmap и активнее задействует файловый кэш ОС (что в htop может выглядеть как высокое потребление памяти, хотя это кэшируемые страницы, которые ядро отдаст при необходимости). Sled управляет памятью сам и обычно даёт более предсказуемый, но чуть более высокий базовый RSS.

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

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

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