Почему мы пробуем Postgres вместо ClickHouse для FM-аварий

В системе Fault Management события приходят потоком: новое / подтвержденное / закрытое, часто не по порядку и с дублями. Раньше мы выстраивали сложную цепочку для приёма данных: gRPC → RabbitMQ → Обработчик → clickhouse-bulk → CH (входящие) → MV → CH (состояния)

На бумаге всё логично: clickhouse-bulk собирает мелкие INSERT’ы, а Materialized Views сами раскладывают состояние. На практике запись стала узким местом.

Что болит в текущей схеме? - Тяжёлые MV на каждый INSERT. Одна входящая строка превращается в тяжёлую обработку на стороне ClickHouse с JOIN, ORDER BY и обращению к словарям. - Умножение записи. Одно событие размножалось в несколько таблиц. - Построчный текстовый SQL. Построчная сборка текста даже с буферизацией — это дорого. - Оверхед на стороне приложения. Сериализация и HTTP-прокладки между сервисами.

В результате, узкое место — в первую очередь MV + кратная запись.

Что сделали в MVP 💡 Для MVP решили проверить простую гипотезу: «А что, если убрать всё лишнее и попробовать Postgres?» Новый поток стал прозрачным: gRPC → Конвертация → ACL (Redis) → in-memory batch → Postgres

Мы отказались от MV в пользу одной партиционированной таблицы с дедупликацией через ON CONFLICT DO NOTHING. Вставка теперь асинхронная, батчами по 1000 строк.

Цифры говорят сами за себя: 📊 Нагрузочное тестирование (ghz) выдало ~4382 RPS при p99 = 79 мс.

При этом нашли неочевидный бонус: замена MessageToDict на прямой маппер отрезала лишние 10 мс задержки.

Вывод: 📌 Для нашего сценария Postgres отлично закрывает роль «горячего пути». Сейчас будем смотреть на деградацию при росте объёмов, но первые результаты очень обнадёживают.