Как избежать проблем с доступом к базе данных другого сервиса при запросах аналитики
Что проверяют
Понимаете ли вы, что прямое чтение чужой базы превращает её схему в ваш контракт, а тяжёлые аналитические запросы бьют по чужому продакшену. Следом обычно спрашивают: «А если данные нужны почти в реальном времени?»
Как отвечать
Начните с принципа: у каждого сервиса своя база, и снаружи в неё не ходят. Дальше варианты по возрастанию зрелости:
- API владельца данных: сервис отдаёт агрегаты или выгрузку через отдельный эндпоинт, сам решает, как их считать, и может менять схему без оглядки на вас;
- реплика для чтения: если без SQL никак, то только к реплике, отдельным пользователем с правами на чтение и с
statement_timeout, чтобы долгий запрос не держал ресурсы; - CDC: изменения читаются из журнала базы (например, Debezium поверх WAL), летят в Kafka и складываются в ваше собственное аналитическое хранилище, чаще всего ClickHouse. Задержка в пределах секунд, нагрузки на исходную базу почти нет;
- периодическая выгрузка (ETL): подходит, когда аналитике хватает данных за вчера.
В Go-коде защищайтесь независимо от выбранного способа. Ограничьте пул: db.SetMaxOpenConns в database/sql или MaxConns у pgxpool, иначе всплеск отчётов займёт все соединения. Каждый запрос выполняйте через QueryContext с context.WithTimeout. Большие выборки читайте постранично по ключу (WHERE id > $1 ORDER BY id LIMIT 1000), а не через OFFSET, и не забывайте defer rows.Close(), иначе соединение не вернётся в пул.
Отдельно проговорите договорённость с командой владельца: какие поля стабильны и кто предупреждает об изменениях схемы.
Где спотыкаются
Предлагают «просто закешировать в Redis». Кеш уменьшает число повторных запросов, но первый тяжёлый запрос всё равно идёт в чужую базу, а связанность схем кеш не лечит вовсе.
Пишут аналитику прямо по основной базе соседа, потому что «так быстрее». Первая же миграция у соседей ломает отчёты, и виноватого ищут долго.
Забывают про таймауты и лимиты пула. Запрос без контекста висит, пока его не прибьёт база, а горутины копятся и держат соединения.