Pull to refresh

Comments 8

Автор здесь, буду в комментариях ближайшие часы — с радостью отвечу на вопросы по архитектуре. Особенно на такие: почему именно PostgreSQL + ClickHouse, а не одна база; где проходит граница, за которой --mode=all перестаёт справляться и пора разносить процессы; что оказалось самым неприятным при реализации приёма Sentry-протокола.

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

Справедливо было бы спросить "а где цифры" - статья без них действительно неполная. Снял с рабочего стенда, привожу как есть, с оговорками.

Потребление в покое. Инстанс поднят 20 часов, --mode=all, три контейнера:

- сам бинарник gotcha: 6.3 МБ RAM, ~0% CPU

- PostgreSQL: 25 МБ, 3.7% CPU

- ClickHouse: 731 МБ, 3.5% CPU

Итого около 760 МБ. Львиную долю занимает ClickHouse - это его обычный базовый аппетит, и под нагрузкой он будет расти. Сам Go-бинарник в покое держится в пределах 6-7 МБ.

Сколько занимают данные. За 14 дней на стенде накопилось (строк / на диске / сжатие):

- спаны трейсов: 108 280 / 3.96 МиБ / 3.7x

- транзакции: 22 620 / 2.22 МиБ / 1.9x

- события (ошибки): 1 578 / 69 КиБ / 14x

- точки метрик: 3 840 / 44 КиБ / 10.6x

- сэмплы профилей: 1 620 / 29 КиБ / 6.9x

В пересчёте на запись: спан - около 38 байт на диске, точка метрики - около 12, событие - около 45. PostgreSQL со всей реляционкой (организации, проекты, пользователи, правила алертов, инциденты) - 10 МБ.

Важная оговорка. Стенд не продакшен: событий всего полторы тысячи, и сжатие 14x на таком маленьком однородном наборе почти наверняка оптимистичное. Цифре по спанам (108 тысяч строк) я доверяю заметно больше. Считайте это порядком величины, а не обещанием.

Чего я не мерил - пропускную способность. Нагрузочного теста не делал, поэтому называть события в секунду не буду. Если интересно - соберу и опубликую отдельно, уже с методикой.

Задокументированные требования, из которых я исхожу: минимум 2 vCPU / 2 ГБ RAM / 20 ГБ SSD, рекомендуемо 4 vCPU / 4 ГБ / 40 ГБ. Диск обязательно SSD — обе базы чувствительны к латентности.

https://victoriametrics.com/products/

Почему не подошёл данный стек? Если брать не кластерную версию, как раз 3 бинарника + grafana и модули к ней

Согласен, в некластерном виде он действительно компактный, по ресурсам тут спорить не с чем.

Разница для меня была не в весе, а в задаче.

Насколько я понимаю их продукты, это прежде всего хранилища телеметрии плюс Grafana как слой визуализации. Мне же нужен был в первую очередь воркфлоу по ошибкам: исключения, сгруппированные в проблемы по сигнатуре, со стектрейсом и дедупликацией, со статусами (unresolved / ignored / resolved), назначением ответственного и историей по каждой проблеме. Это ближе к трекеру задач над потоком исключений, чем к дашборду, и на графане такое собирается плохо.

Второе, и для меня решающее: приём по протоколу Sentry. В проектах уже стояли официальные Sentry SDK, и условие было - не трогать инструментацию вообще. Перенос свёлся к смене DSN в конфиге. Ради этого пункта всё, собственно, и затевалось.

Третье - свой интерфейс из коробки, без отдельного слоя визуализации, который нужно конфигурировать. Это осознанный размен: меньше гибкости в обмен на отсутствие настройки.

Если задача - метрики и логи, ваш вариант её закрывает, и городить своё смысла нет. У меня отправной точкой были ошибки с уже подключённых Sentry SDK - отсюда и другой выбор.

Очень похоже на то, что вы из стека Sentry community self hosted сделали его же версию но на минималках. Как вариант для себя вполне пойдет, как вариант не для себя - нет.

свой интерфейс из коробки, без отдельного слоя визуализации, который нужно конфигурировать

Это вы просто будете пепеписывать несколько раз для себя, если не считать как конфигурирование, то да, возможно так и есть. Вам стоило взглянуть на perses.dev, он более гибок и можно так же навайбкодить свой плагин/панель под ваши нужды.

Тут важно поправить фактическую часть: Gotcha - не "версия Sentry на минималках" и вообще не их стек. В кодовой базе нет ни строчки из Sentry: их сервер написан на Python (+TypeScript в интерфейсе), приём - Relay на Rust, слой над ClickHouse - Snuba на Python. Gotcha целиком написана на Go, с нуля. Общее между нами - только wire-протокол SDK, и он реализован заново именно для того, чтобы не трогать инструментацию в приложениях (в статье честно написано, что это и было самым неприятным куском работы).

Разница и в целевом классе. Официальная документация self-hosted Sentry называет минимум 4 CPU и 16 ГБ RAM (+16 своп) - для их масштаба и функциональности это оправданная архитектура. Gotcha документирует минимум 2 vCPU / 2 ГБ и реально живёт на таком VPS (замеры - в комментарии выше). Это не "то же самое, ужатое", а другой инженерный компромисс под другой класс задач: маленькие и средние инсталляции, где выделять отдельную машину под мониторинг не хочется.

Про "переписывать интерфейс несколько раз" - риск честный, я его понимаю. Пока панели узкие и их немного (issues, трейсы, метрики, профили, аптайм), и они привязаны к нашим же данным, так что конструктор дашбордов строить не планирую.

За наводку на Perses спасибо, посмотрел: это CNCF-проект дашбордов поверх Prometheus/Tempo/Loki/Pyroscope - слой визуализации над чужими бэкендами. Gotcha же в первую очередь сам бэкенд: приём по Sentry-протоколу и OTLP, хранение, алерты; UI - тонкий слой над этим. Так что напрямую он наш интерфейс не заменит, но embeddable-панели у них любопытные - для метрик-дашбордов идея интересная.

А зачем Postgres, разве SQLite недостаточно? По описанию кажется, там записей очень мало, справится с запасом. Минус один контейнер, но по памяти конечно небольшая экономия рядом с ClickHouse.

По объёмам - вы правы, и с запасом: на стенде весь PostgreSQL со всей реляционкой (организации, проекты, пользователи, правила алертов, инциденты) занимает 10 МБ данных и ~25 МБ памяти в покое. SQLite бы это унёс не заметив.

Причина не в объёмах, а в режимной модели. Тот же бинарник флагом --mode разносится на отдельные процессы - ingestwebuptime - и вся их координация сознательно живёт в базах: сессии, правила, инциденты, вычисление алертов - в PostgreSQL. Процессы могут стоять на разных машинах, и тогда им нужна одна сетевая база с нормальной конкурентной записью: ingest пишет инциденты, web правит правила, uptime обновляет статусы - одновременно. SQLite - встраиваемый однофайловый движок: по сети он не работает, а с несколькими пишущими процессами живёт плохо даже локально. Выбросить его пришлось бы ровно в тот момент, когда single-node перестаёт хватать - то есть в самый неудобный.

Но для строго одноузлового режима мысль здравая, признаю: embedded-вариант без контейнера Postgres сделал бы --mode=all ещё легче. В бэклоге такое есть, обещать сроки не буду. А экономия по памяти — да, вы сами это отметили: рядом с ClickHouse (~730 МБ в покое) эти 25 МБ погоды не делают.

Sign up to leave a comment.

Articles