Спиллинг
Спиллинг в общем
Спиллинг — это механизм управления памятью, при котором промежуточные данные, возникающие в результате выполнения запросов и превышающие доступный объём оперативной памяти узла, временно выгружаются во внешнее хранилище. В YDB для спиллинга в настоящее время используется диск. Спиллинг обеспечивает выполнение пользовательских запросов, которые требуют обработки больших объёмов данных, превышающих доступную память узла.
В системах обработки данных, включая YDB, спиллинг важен для:
- обработки запросов с большими объёмами данных, когда промежуточные результаты не помещаются в оперативную память;
- выполнения сложных аналитических операций (агрегации, соединения таблиц) над большими наборами данных;
- оптимизации производительности запросов за счет промежуточной материализации части данных во внешней памяти, что в определенных сценариях может ускорить общее время выполнения.
Спиллинг функционирует на основе принципа иерархии памяти:
- Оперативная память (RAM) — быстрый, но ограниченный ресурс.
- Внешняя память — медленнее, но более ёмкая.
Когда использование памяти приближается к лимиту, система:
- сериализует часть данных;
- сохраняет их во внешней памяти;
- освобождает соответствующую память;
- продолжает обработку запроса, используя данные, находящиеся в памяти;
- при необходимости загружает данные обратно в память для продолжения вычислений.
Спиллинг в YDB
YDB реализует механизм спиллинга через Spilling Service — акторный сервис, который предоставляет временное хранилище для блобов данных. Спиллинг осуществляется только на узлах базы данных. Подробная техническая информация о Spilling Service доступна в разделе Spilling Service.
Типы спиллинга в YDB
YDB реализует два основных типа спиллинга, функционирующие на различных уровнях вычислительного процесса:
Эти типы работают независимо друг от друга и могут активироваться одновременно в рамках одного запроса, обеспечивая комплексное управление памятью.
Спиллинг в вычислениях
Вычислительные ядра YDB автоматически выгружают промежуточные данные на диск при выполнении операций, требующих значительного объема памяти. Данный тип спиллинга реализован на уровне отдельных вычислительных операций и активируется при достижении лимитов памяти.
Основные сценарии использования:
-
Агрегации — при группировке больших объемов данных система выгружает промежуточные хеш-таблицы на диск
-
Join операции — при объединении таблиц большого размера используется алгоритм Grace Hash Join с разделением данных на партиции и их выгрузкой на диск
Механизм функционирования
Вычислительные узлы содержат специализированные объекты для мониторинга использования памяти. При приближении объема данных к установленному лимиту:
- Система переключается в режим спиллинга
- Данные сериализуются и разделяются на блоки (бакеты)
- Часть блоков передается в Spilling Service для сохранения на диске
- В памяти сохраняется метаинформация о расположении данных
- Система продолжает обработку данных, оставшихся в памяти, что позволяет освободить дополнительное место
- При необходимости данные загружаются обратно и обрабатываются
Спиллинг в транспорте
Данный тип спиллинга функционирует на уровне передачи данных между различными этапами выполнения запроса. Подсистема передачи данных автоматически буферизует и выгружает данные при переполнении буферов. Это помогает не блокировать операции, генерирующие данные, даже в ситуациях, когда принимающая сторона временно не готова принять данные.
Механизм функционирования
Подсистема передачи данных осуществляет постоянный мониторинг своего состояния:
- Буферизация: Входящие данные накапливаются во внутренних буферах подсистемы
- Контроль заполнения: Система отслеживает уровень заполнения буферов
- Автоматический спиллинг: При достижении лимитов данные автоматически сериализуются и передаются в Spilling Service
- Продолжение функционирования: Подсистема продолжает прием новых данных после освобождения места в памяти
- Восстановление: При готовности следующего этапа данные читаются из внешнего хранилища и передаются далее
Взаимодействие с контроллером памяти
При выполнении запросов YDB старается умещаться в заданный лимит памяти, который устанавливается контроллером памяти. Чтобы продолжать помещаться в этот лимит даже при росте промежуточных вычислений, используется спиллинг. Подробнее см. раздел Управление памятью.