Привет, Хабр! Меня зовут Алексей Быков, я занимаюсь развитием cloud-native-платформы для обработки данных Arenadata One (AD.ONE). В этой статье мы поговорим о neon-kubernetes-реализации PostgreSQL, её устройстве, особенностях и о том, почему классический подход к Postgres в Kubernetes не позволяет в полной мере использовать преимущества гибкой облачной инфраструктуры.

Тема не новая и активно развивается: уже давно существуют операторы (Zalando, Crunchy Data, CloudNativePG) для автоматизации развёртывания Postgres в Kubernetes. Однако они сохраняют монолитность базы, когда данные по-прежнему жёстко связаны с узлами, а горизонтальное или вертикальное масштабирование требует ручной настройки и остаётся непростым процессом. Подход Neon основан на полном разделении вычислений (compute) и хранилища (storage), что даёт нам возможность взглянуть на использование PostgreSQL в облаке по-новому, как на сервис с возможностью динамического масштабирования, мгновенного запуска инстансов, изолированных веток (branching) и других возможностей без необходимости в сложной инфраструктурной обвязке.

Изолированная ветка (branching) —

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

Классическая монолитная архитектура в Kubernetes: где узкие места?

В традиционных сценариях развёртывания PostgreSQL (даже если мы «заворачиваем» её в kubernetes-оператор) сохраняется архитектура, в которой вычисления и данные сплетены между собой и находятся на одном уровне. При переносе такого подхода в K8s картина мало меняется: как правило, требуется Primary Postgres, одна или несколько реплик, а также HAProxy (или другой балансировщик) и пуллер, сервисы бэкапирования, мониторинга, механизмы failover и других служебных задач. Такая конфигурация остаётся комплексной и требует постоянного управления, даже несмотря на автоматизацию части процессов за счёт операторов.

NhBiATq18p4CppKKlJ8d8o9FUSBXeS4rffaRw3KWFlLNGkVutavxyBb44HFVDLuKELrHwUeu510IdcPEdpUHmqylY2oF9QusakJVY7oyzjFE3A8t6bMdXBIactOfEmbc

Что при этом усложняет жизнь в Kubernetes?

  • Stateful-архитектура vs stateless-платформа
    Kubernetes изначально заточен под stateless-приложения: его ключевые механизмы (репликация, autoscaling, rolling updates) хорошо работают с контейнерами, у которых нет состояния. А Postgres — stateful: её хранилище должно быть сохранено между перезапусками, что делает развёртывание и обслуживание более хрупким.

  • Сложная работа с persistent storage в K8s
    Одним из нюансов при запуске Postgres в Kubernetes остаётся работа с persistent storage. Хотя большинство облачных провайдеров предоставляют надёжные CSI-драйверы с динамическим созданием томов, в реальности могут возникать сложности, например ограничения по доступности PVC только в пределах одной availability zone или необходимость вручную следить за тем, чтобы под и том оказались на одном узле или в нужной зоне. Это особенно критично в on-prem-установках, где нет managed-решений и приходится полагаться на локальные provision-решения. В результате масштабирование или миграция подов может потребовать дополнительной инфраструктурной логики и настройки.

  • Сетевая сложность
    PostgreSQL может быть чувствительна к сетевым задержкам и нестабильности, особенно в сценариях высокой нагрузки или репликации. В Kubernetes используется overlay-сеть, которая в больших кластерах со множеством узлов может вносить дополнительную задержку. Однако благодаря StatefulSet и Headless Service можно обеспечить стабильные DNS-имена и предсказуемое сетевое поведение подов. Эти механизмы позволяют минимизировать влияние сетевых изменений, таких как пересоздание пода, и поддерживать устойчивую коммуникацию между инстансами, однако требуют более сложной настройки и сопровождения.

  • Общий операционный overhead
    Сама инфраструктура Kubernetes требует значительно больше навыков и времени на настройку и поддержку — настройку кластеров, управление сетью, безопасностью и обновлением компонентов. В то время как VM-инсталляции — более привычный и понятный процесс.

Kubernetes-операторы действительно упрощают жизнь: они автоматизируют деплой кластеров, следят за состоянием реплик, перезапускают их при сбоях, но не переворачивают концепцию монолитного PostgreSQL. Мы всё так же имеем patroni-кластер, клонируем целые базы ради реплик, рискуем упереться в ограничения вертикального масштабирования. Именно поэтому появилась идея архитектурного разделения compute и storage, чтобы управлять ими независимо и использовать ресурсы более гибко. 

Новый подход с Neon: разделяем compute и storage

Главная идея Neon — разделить хранение и вычисления, чтобы PostgreSQL стала действительно cloud-native. Если в традиционных инсталляциях база хранит данные локально, а реплики полностью копируют весь объём данных с Primary, то в Neon между Postgres и хранилищем появляется слой микросервисов, где:

  • Compute Layer: сами инстансы PostgreSQL, которые работают с данными, но не хранят их локально.

  • Storage Layer: Safekeeper, PageServer и объектное хранилище S3.

В результате Postgres видит ту же логику (чтения/записи, WAL, страницы), но теперь:

  1. WAL (write-ahead log, журнал изменений) больше не пишется на локальный диск, а отправляется в Safekeeper.

  2. Данные в формате pages загружаются из PageServer, который при необходимости подтягивает их из S3.

  3. Всё долговременное хранение вынесено в объектное хранилище, где у нас почти безграничный объём.

Такой подход устраняет зависимость данных от конкретного экземпляра Postgres. Compute можно спокойно пересоздавать, останавливать, наращивать ресурсы: данные сохраняются снаружи, и Postgres просто восстанавливает состояние при старте. Это упрощает управление нагрузкой, ускоряет отклик на сбои и снижает требования к железу.

Кроме того, архитектура Neon предоставляет ощутимые преимущества в сценариях разработки и тестирования. Вместо клонирования терабайтных баз данных можно создавать лёгкие виртуальные копии — ветки (branches), которые на уровне PageServer и S3 используют одни и те же страницы с оригиналом. Это позволяет быстро запускать параллельные окружения без затрат на дублирование данных.

Что это даёт на практике?

  • Гибкое масштабирование
    Stateless-реализация Postgres позволяет масштабировать compute-инстансы без потери данных. При необходимости Neon автоматически увеличивает количество CPU или RAM, а вся storage-часть кластера остаётся доступной через Safekeeper, PageServer и S3.

  • Мультитенантность
    На одной платформе можно запускать тысячи изолированных postgreSQL-инстансов. Данные хранятся централизованно и распределяются между PageServer. Такой консолидированный вариант экономит ресурсы и сильно упрощает обслуживание, ведь не нужно создавать десяток обособленных patroni-кластеров с полным комплектом балансировки и бэкапов.

  • Упрощённое HA
    При сбое compute-инстанса новый экземпляр можно запустить мгновенно: WAL сохраняется в Safekeeper, pages продолжают храниться в PageServers и S3. По нашему мнению, это надёжнее и быстрее классического failover, где требуется синхронизация с репликами и контроль состояния кластера.

Как устроен Storage Layer в Neon и зачем нужны Safekeeper и PageServer

Neon не просто разделяет хранение и вычисления — он вводит специальный слой хранения, в котором есть два ключевых типа компонента: Safekeeper и PageServer. Такой подход изменяет пути чтения и записи и позволяет хранить всё за пределами Compute, устраняя зависимость от локальных дисков и упрощая масштабирование, ведь теперь это можно делать по компонентам.

Safekeeper — приёмник WAL

Safekeeper — это группа микросервисов, которые принимают поток WAL от postgreSQL-инстансов. Они не хранят данные постоянно, а действуют как надёжный буфер: собирают WAL, подтверждают фиксацию данных и обеспечивают согласованность. Для этого Neon использует протокол, похожий на смесь Paxos и Raft, — он позволяет достичь консенсуса между несколькими Safekeeper и гарантирует, что транзакции действительно зафиксированы. У разработчиков Neon есть отличная статья на тему выбора протокола, поэтому в рамках этой статьи мы не будем детальнее рассматривать реализацию консенсуса, но оставим ссылку.

PageServer — поставщик страниц

Это центральный компонент Storage Layer, который отвечает за формирование и предоставление postgreSQL-страниц (pages) на основе WAL. У PageServer есть две задачи: превратить поток изменений, поступающих от Safekeeper, в конкретные версии данных и отдать сформированные pages, когда Postgres пришлёт запрос для чтения. Актуальные страницы PageServer отдаёт напрямую, а устаревшие или нечасто используемые подтягивает из объектного хранилища S3. Несмотря на сетевые задержки, PageServer частично их сглаживает, выступая кэширующим слоем между S3 и PostgreSQL.

Потоки данных в Neon: как работают чтение и запись

Разделение compute и storage в Neon устроено так, чтобы обеспечить надёжную фиксацию изменений и быструю доставку данных при чтении. Рассмотрим подробнее оба пути: write path (запись) и read path (чтение).

Когда в postgreSQL-инстансах (compute) генерируется транзакция (вставка, обновление или удаление), она сначала фиксируется в WAL. В традиционном Postgres WAL записывается на носитель данных, расположенный с экземпляром базы данных. В Neon вместо этого: 

  1. WAL-поток отправляется по сети в Safekeeper. 

  2. После подтверждения клиенту возвращается ACK — операция считается завершённой.

  3. Safekeeper сохраняет WAL временно и передаёт его в PageServer. 

  4. PageServer использует WAL для реконструкции логических страниц PostgreSQL (обычно 8 Кб) и сохраняет их в свой кэш и объектное хранилище.

Write path
Write path

Когда compute выполняет запрос на чтение, он работает по цепочке:

  1. Кэш в compute: сначала проверяется внутренний буфер кэша Postgres. Если нужная страница уже использовалась, она возвращается сразу.

  2. PageServer: если данных нет в кэше, compute отправляет запрос в PageServer — это основной источник актуальных страниц.

  3. S3: если PageServer не хранит нужную страницу (например, она давно не использовалась или была выгружена для экономии места), он скачивает её из S3, восстанавливает и отдаёт compute-инстансу.

Read path
Read path

Важно: такая цепочка работает прозрачно для PostgreSQL. С её точки зрения, это просто немного замедляет доступ к данным, но без необходимости знать, где именно физически лежит страница. При этом PageServer может держать «горячий» слой часто используемых данных.

Дополнительные микросервисы и почему open source — это лишь половина пути

Несмотря на то что open source версия Neon позволяет убедиться в работоспособности концепта, на практике этого недостаточно для полноценной работы под нагрузкой. Open source имеет набор микросервисов, необходимых для локального или ручного развёртывания, и при желании специалист со знанием Rust и K8s сможет развернуть кластер, чтобы посмотреть, как отрабатывают основные фичи продукта. Как говорят разработчики, часть микросервисов, не выложенных в open source, слишком сильно ориентирована на специфику бизнеса DBaaS Neon и, как следствие, на AWS и Azure, поэтому, когда в Arenadata приняли решение внедрять технологию на базе Neon в новую платформу Arenadata One, перед командой встал ряд вызовов: 

Neon cluster
Neon cluster

Во-первых, поскольку Neon в нашем случае является частью платформы Arenadata One, мы хотим автоматизировать развёртывание кластеров — для этого необходим оператор. Поскольку готовых решений с открытым исходным кодом не существует (доступен только Docker Compose для локального развёртывания), мы разработали собственный оператор. Он автоматически разворачивает все необходимые компоненты и проверяет корректность развёртывания кластера.

Во-вторых, необходим сервис, который умеет управлять инстансами PostgreSQL по запросу. Compute в Neon — это, по сути, запущенные в Kubernetes виртуальные машины с модифицированным Postgres внутри. Open source реализация предполагает ручное управление подами и их содержимым, что удобно для тестов, но не подходит даже для пилотирования, потому что не позволяет оценить одно из основных преимуществ Neon, а именно упрощение выделения новых инстансов Postgres бизнесу.

В-третьих, важным элементом стал Control Plane — центральный сервис, который позволяет управлять тенантами, бранчами и созданными инстансами Postgres. Он даёт возможность видеть весь пул баз, переключаться на нужные ветки, делать PITR и прочие операции. Без такого централизованного контроллера пользоваться Neon в крупных инсталляциях невозможно.

Так как мы разработали свой Control Plane, возникла необходимость в удобном инструменте для взаимодействия с ним — CLI (Command Line Interface). Мы реализовали консольную утилиту, которая позволяет администраторам и разработчикам управлять всеми объектами Control Plane: создавать и удалять инстансы, переключаться между ветками, выполнять PITR, управлять правами доступа и многое другое. CLI стал незаменимым инструментом как для автоматизации, так и для ручных операций, особенно на этапе тестирования и внедрения.

Все эти компоненты позволили приблизить Neon к состоянию, готовому к продакшену в Kubernetes: теперь тысячи баз могут работать в одном большом кластере, а запуск дополнительных Postgres-инстансов сводится к простому API-вызову. Это особенно выгодно, когда у разных команд возникают временные потребности в базе, ведь её можно быстро «пробудить» и так же быстро «усыпить», если в данный момент она не используется.

Разработчики Neon подчёркивают, что этот подход оказывается выгодным при большом числе баз или переменных нагрузках, ведь нет необходимости плодить полноценные инстансы для каждой задачи. Вместо этого появляется возможность подключать новые compute-инстансы и расти по горизонтали за счёт отдельных микросервисов, которые общаются друг с другом в Kubernetes. 

Ограничения и риски Neon в Kubernetes

Преимущества архитектуры уже разобраны, но для полноты картины важно указать, что может усложнить её эксплуатацию.


Во-первых, scale-to-zero неизбежно добавляет задержку. «Пробуждение» compute из idle-состояния занимает сотни миллисекунд, среднее значение сегодня — около 500 миллисекунд, что заметно для интерактивных OLTP-систем.


Во-вторых, лишний сетевой прыжок. Даже с локальным SSD-кэшем PageServer при обращении к «холодным» страницам запрос проходит по цепочке Compute → PageServer → S3, и в P95 время ответа способно вырасти, особенно если объектное хранилище вынесено в другую зону.

В-третьих, расширяемость. В serverless-среде нельзя просто поставить любой C-extension — поддерживаются лишь те, что встроены в образ или прошли проверку, а суперправа урезаны. Это ограничивает сценарии, где критичны, скажем, pg_cron или file_fdw.

В-четвёртых, зрелость open source версии. Без готового Control Plane и stateless-прокси придётся писать обвязку самому, иначе рискуете скатиться в «ручной режим». Наконец трассировка запросов через четыре слоя добавляет нагрузку на observability-стек и усложняет отладку — традиционная Postgres здесь проще.

Для кого это подходит

Neon раскрывается там, где баз много, а нагрузка скачет: мультиарендные SaaS-платформы, CI/CD-окружения с ветками-песочницами, event-driven-сервисы, которые «спят» большую часть времени. Критерий успеха прост: idle-время значимо, а бизнес доволен, когда платит только за активные минуты.

Если же приложение держит коннект 24/7, требования к P95 ниже 10 миллисекунд, база полна собственного C-кода или находится в среде с жёсткими регуляторными запретами на внешнее object storage, классический монолит остаётся безопаснее.

Понимание этих границ позволяет оценить Neon трезво: сильная идея для динамичных распределённых сценариев, но не универсальная таблетка. В следующем разделе мы вернёмся к техническим деталям Storage Layer и посмотрим, как Safekeeper и PageServer справляются с нагрузкой при реальных пиковых данных.

Заключение

Архитектура Neon с разделением вычислений и хранения представляет собой прогрессивный подход к развёртыванию PostgreSQL в облачных средах и Kubernetes. Отказ от монолитности позволяет добиться гибкости в масштабировании вычислительных ресурсов, упрощает задачи высокой доступности и эффективно поддерживает мультитенантность за счёт общего слоя данных. Это открывает двери для создания по-настоящему cloud-native-решений на базе PostgreSQL, где управление базой данных становится гибким, как и управление любым другим stateless-сервисом.

Однако внедрение open source версии Neon в продакшен требует внимательного подхода и дополнительных усилий. Для достижения необходимой надёжности и управляемости на уровне зрелой платформы критически важна интеграция с complementary-микросервисами, обеспечивающими оркестрацию вычислительных НОД, централизованный контроль доступа, мониторинг и так далее. Также важно учитывать специфические требования Neon к среде выполнения Kubernetes, включая поддержку виртуализации, при планировании инфраструктуры и тестировании. В следующей статье мы углубимся в практические аспекты применения Neon, рассмотрим реальные вызовы, с которыми можно столкнуться при его внедрении.

Комментарии (6)


  1. olku
    16.07.2025 17:47

    Много воды, мало цифр. Во сколько "немного замедляет доступ к данным"? У вас наверняка есть бенчмарки раз продукт появился. Брокер сообщений это не то что обычно ожидают от реляционной базы данных. Не поделитесь хотя бы синтетикой?


    1. de-potato Автор
      16.07.2025 17:47

      Привет, спасибо за вопрос! Мы пишем серию статей про Neon, детальные бенчмарки по производительности и работе под разными профилями нагрузки мы представим в следующей статье. По поводу брокеров, для распределенных систем подобная реализация скорее необходимость которую можно встретить в том или ином виде и в других реляционных базах (пр. AWS Aurora, CockroachDB, YugabyteDB)


  1. Foster111111666
    16.07.2025 17:47

    Хороший структурированный материал. Интересно узнать про ограничения. Если у меня сейчас работает 'классический' Postgres в K8s, насколько сложно и рискованно будет мигрировать на Neon? Какие самые большие подводные камни?


    1. de-potato Автор
      16.07.2025 17:47

      Привет, очень рад, что статья оказалась полезной. Сложность и риски миграции с классического PostgreSQL на Neon зависят от выбранной версии. Если речь идет об Open Source Neon, то придется преисполниться и потратить время на разработку недостающих компонентов (там правда не хватает многих сервисов, а некоторые os приходится патчить). В остальном миграцию можно осуществлять любыми стандартными инструментами Postgres.


  1. yoda317
    16.07.2025 17:47

    Kubernetes используется overlay-сеть, которая в больших кластерах со множеством узлов может вносить дополнительную задержку

    Во-первых, это не так. Можно (и нужно для таких случаев) блоки адресов аннонсировать прямо с ноды, тогда поды будут доступны по сети напрямую, что минимизирует задержки. И из всех перечисленных проблем это имхо наименьшая.

    Другая большая проблема постгреса в кубере, это жирные поды с огромными реквестами и лимитами, что в принципе затрудняет равномерное использование капаситета на нодах.

    А почему s3 а не RBD? RBD точно быстрее.


    1. de-potato Автор
      16.07.2025 17:47

      Добрый день. По сетям, дополнительно изучил вопрос и если мы говорим про on-prem инсталляции и некоторые облака (не все дают установить свой CNI) ваше уточнение верно, спасибо.

      По жирным POD:

      Да, при очень жирных POD-ах возможна фрагментация ресурсов, но в случае с Neon это частично нивелируется:

      • Подходом к вертикальному масштабированию - через CU, все ресурсы в линейной зависимости от CPU;

      • Возможностью шардирования на уровне Storage;

      • Наличием Autoscaler с собственным планировщиком;

      • В целом за счёт разделения Compute/Storage фрагментация ресурсов в Neon не такая уж проблема по сравнению с классическим PostgreSQL в k8s;

      По S3 vs RBD:

      • Продукту  важно быть  универсальным (on-prem и облака) и чаще в инфраструктуре клиента есть S3, а не блочные устройства;

      • RBD сложнее использовать в сценариях с Multi-RW доступом - потребуется использовать какую-то параллельную ФС отдельным слоем, что вносит существенную сложность в поддержке;