У нас всем потребителям нужна полная копия данных для расчета доступности. Систему без pg мы в принципе не рассматривали - это был готовый компонент с уже агрегированным состоянием по всем сущностям, он исторически сложился в архитектуре.
Если всё же представить, что PostgreSQL нет, то сразу появляются проблемы:
исчезает готовый агрегат, который можно быстро вычитать одним запросом;
под каждую полную копию пришлось бы создавать отдельную consumer group (на 500+ подов), что создаёт ту самую избыточную нагрузку на брокер;
создание первого снапшота превращается в сложную задачу - нужно выгрузить данные из всех систем, потому что полного слепка нигде нет.
Да, внешне похоже, но главное различие - у нас версии выдаются строго по порядку коммитов, благодаря блокировке счётчика в транзакции. rowversion и sequence не дают таких гарантий, номер выдаётся до коммита, поэтому порядок видимости не гарантируется.
То есть у нас не может быть ситуации, что версия, например, 100500 уже закомитилась, а версия 100400 еще нет. При использовании sequence или rowversion такая ситуация возможна и обновление потеряется.
Но в нашем случае он потребовал бы реализации push-механизма доставки данных, а текущие характеристики pull-модели нас полностью устраивают. Мы стараемся не усложнять систему там, где этого не требуется.
Гибридная схема pull + push это классический подход для случаев, когда критична задержка доставки изменений. Мы её рассматривали, но там сразу появляются сложности, описанные в разделе про push на основе gRPC-стриминга. Задержки в одну‑две секунды нас полностью устраивали, всё уже работало на чистом pull, поэтому мы не стали усложнять систему без явной потребности. Если в будущем понадобится мгновенная актуализация, то вполне возможно, что как раз и придём к гибриду.
В финальной схеме посредник действительно мог бы быть исключён, но мы осознанно его оставили. Во-первых, он инкапсулирует всю логику работы с этой БД и S3 (наполнение, версионирование, создание снапшотов). Клиентам не нужно знать ни SQL, ни структуру таблиц, только gRPC-контракт моделей. Во-вторых, у нас уже была готовая интеграция с ним, и нам оставалось лишь подменить вызовы ручек.
Репликация БД это прекрасный механизм, и в наших базах он используется. Но увеличение числа реплик не решает главной проблемы: нам нужно за минимальное время получить данные о тысячах складов. Даже батчевые ручки других наших сервисов, отдающие данные по ключу, работают в пределах 30–50 мс с пачками по сто элементов. Если мы будем тратить столько времени только на получение данных, то сильно превысим SLO (и это ещё для сотни элементов, а у нас в запросе их тысячи). Поэтому мы держим данные прямо в памяти пода, обрабатывающего запрос.
Да, идея интересная, спасибо. Попробуем внедрить в будущем
У нас всем потребителям нужна полная копия данных для расчета доступности. Систему без pg мы в принципе не рассматривали - это был готовый компонент с уже агрегированным состоянием по всем сущностям, он исторически сложился в архитектуре.
Если всё же представить, что PostgreSQL нет, то сразу появляются проблемы:
исчезает готовый агрегат, который можно быстро вычитать одним запросом;
под каждую полную копию пришлось бы создавать отдельную consumer group (на 500+ подов), что создаёт ту самую избыточную нагрузку на брокер;
создание первого снапшота превращается в сложную задачу - нужно выгрузить данные из всех систем, потому что полного слепка нигде нет.
Да, внешне похоже, но главное различие - у нас версии выдаются строго по порядку коммитов, благодаря блокировке счётчика в транзакции.
rowversionиsequenceне дают таких гарантий, номер выдаётся до коммита, поэтому порядок видимости не гарантируется.То есть у нас не может быть ситуации, что версия, например, 100500 уже закомитилась, а версия 100400 еще нет. При использовании
sequenceилиrowversionтакая ситуация возможна и обновление потеряется.Но в нашем случае он потребовал бы реализации push-механизма доставки данных, а текущие характеристики pull-модели нас полностью устраивают. Мы стараемся не усложнять систему там, где этого не требуется.
Гибридная схема pull + push это классический подход для случаев, когда критична задержка доставки изменений. Мы её рассматривали, но там сразу появляются сложности, описанные в разделе про push на основе gRPC-стриминга. Задержки в одну‑две секунды нас полностью устраивали, всё уже работало на чистом pull, поэтому мы не стали усложнять систему без явной потребности. Если в будущем понадобится мгновенная актуализация, то вполне возможно, что как раз и придём к гибриду.
В финальной схеме посредник действительно мог бы быть исключён, но мы осознанно его оставили. Во-первых, он инкапсулирует всю логику работы с этой БД и S3 (наполнение, версионирование, создание снапшотов). Клиентам не нужно знать ни SQL, ни структуру таблиц, только gRPC-контракт моделей. Во-вторых, у нас уже была готовая интеграция с ним, и нам оставалось лишь подменить вызовы ручек.
Репликация БД это прекрасный механизм, и в наших базах он используется. Но увеличение числа реплик не решает главной проблемы: нам нужно за минимальное время получить данные о тысячах складов. Даже батчевые ручки других наших сервисов, отдающие данные по ключу, работают в пределах 30–50 мс с пачками по сто элементов. Если мы будем тратить столько времени только на получение данных, то сильно превысим SLO (и это ещё для сотни элементов, а у нас в запросе их тысячи). Поэтому мы держим данные прямо в памяти пода, обрабатывающего запрос.