Современные технологии баз данных переживают значительный сдвиг в архитектуре, подразумевающий разделение хранения данных и вычислительных ресурсов. Такое разделение даёт возможность добиться высокой эластичности, масштабируемости и снижения общих затрат на инфраструктуру. При этом традиционно считалось, что подобный подход неизбежно приводит к замедлению операций чтения из-за возникновения дополнительных сетевых переходов между вычислительными узлами и хранилищем. Однако современные технические решения показывают, что разделение хранения и вычислительной мощности вовсе не означает жертву производительностью, особенно когда речь идёт о крупных и нагруженных системах. Разделение хранения и вычислений позволяет облачным платформам обеспечивать серверам базы данных доступ к огромным объёмам данных без необходимости локально хранить весь объём.
Вместо жестко привязанного дискового пространства или конкретного сервера с ограниченными ресурсами, архитектура разделения обеспечивает возможность мгновенного масштабирования вычислительных мощностей или пространства хранения независимо друг от друга. Это крайне важно при обработке разнообразных нагрузок, например, когда требуется быстро увеличить мощность вычислительных узлов без изменения ёмкости хранилища или наоборот. Классическим примером такой архитектуры является сервис Neon — облачная система, использующая Postgres в вычислительном слое и специализированное распределённое хранилище, которое представляет собой многоарендный ключ-значение сервис, оптимизированный под страницы Postgres. За счёт этого достигается нужный баланс между производительностью и масштабируемостью. Основная сложность, с которой сталкиваются подобные системы, заключается в задержках при буферных промахах — когда необходимая страница данных отсутствует в памяти вычислительного узла, и требуется получить её через сеть из удалённого хранилища.
Чтобы победить этот недостаток, Neon внедрил инновационный компонент — Local File Cache (LFC), работу которого можно сравнить с дополнительным уровнем кэширования между традиционным кэшем Postgres (shared buffers) и удалённым хранилищем. LFC располагается локально в вычислительном узле, реализуя кэширование страниц базы данных на высокоскоростном NVMe-накопителе с возможностью гибкой настройки объёма. Это решение меняет правила игры. Вместо того чтобы платить за дорогостоящие и фиксированные объёмы локального хранилища — и, соответственно, рисковать перерасходом ресурсов — пользователи получают возможность динамически масштабировать кеш, исходя из объёма актуальной рабочей нагрузки и размера рабочего набора данных. Кэшируются именно те страницы, с которыми система работает чаще всего, что существенно уменьшает количество сетевых запросов к удалённому хранилищу и обеспечивает производительность, сопоставимую с локальным дисковым хранилищем.
При этом локальный файл-кэш реализует эффективное использование системного Linux page cache, благодаря чему чтение данных из кеша достигает латентности, сравнимой с оперативной памятью. Если же объём кеша превосходит размер доступной оперативной памяти, избыточные данные аккуратно сливаются на NVMe-диск, сохраняя высокую скорость доступа. Такая архитектура даёт не только низкий уровень задержек при чтении данных, но и высокую гибкость при администрировании и масштабировании системы. Важно понимать, что такие технологии меняют традиционные ограничения фиксированных виртуальных машин с локальным дисковым пространством. В классических реализациях при выборе диска приходится заранее планировать объём хранилища и вычислительных ресурсов, что ведёт либо к переплатам, либо к риску быстрого исчерпания выделенного пространства.
В отличие от этого в системах с разделённым хранением и вычислением клиент платит ровно за используемые ресурсы и может мгновенно увеличить вычислительную мощность без необходимости сложных миграций и долгих простоев. Для иллюстрации эффективности подобного подхода служит тестирование на базе TPCC-подобного бенчмарка, которое показывает, что при использовании большого локального кэша производительность Neon сравнима с производительностью классических систем с полностью локальным NVMe-диском, но при использовании гораздо меньшего объёма локального быстрого хранилища. Например, Neon с 8 вычислительными ядрами и 500ГБ кэша демонстрирует результаты, близкие к локальному дисковому решению, при этом экономя почти половину требуемого высокопроизводительного дискового объёма. Более того, такой локальный кэш не обязательно должен совпадать с общим размером базы данных. Благодаря анализу рабочих наборов данных и прогнозированию объёма кэша, Neon может эффективно работать с меньшим по размеру хранилищем, сохраняя при этом только наиболее востребованные страницы на локальном диске.
Это даёт ещё большую экономию ресурсов без существенных потерь в производительности. Конечно, производительность — это динамический показатель, требующий постоянного мониторинга и развития решений. Neon уже активно работает над будущими версиями своего локального файла кеша с целью реализации более тонкого кэширования и улучшенного управления памятью. Такие улучшения позволят ещё более эффективно использовать ресурсы и обеспечить стабильную высокую производительность в самых разнообразных сценариях использования. Важно выделить, что архитектура разделения хранения и вычислений с локальным кэшем — это не просто временное решение, а долговременный тренд в построении облачных баз данных.