title |
---|
Хранение данных |
На этой странице описано то, как приложение хранит свои данные и какие алгоритмы для этого использует.
Состояние приложения хранится в файлах:
- Лог команд (WAL)
- Снапшот
- Метаданные
Лог команд хранит последовательность команд, которые должны быть применены для получения актуального состояния. Для его поддержания и создания используется алгоритм консенсуса Рафт.
Для хранения лога используется сегментированный лог: весь огромный лог разбивается на несколько меньших сегментов. Каждый сегмент содержит команды, начиная с определенного индекса, и вместе они образуют непрерывную последовательность команд. Похожая стратегия хранения лога есть в Postgres.
Размер каждого сегмента определяется 2 параметрами: мягкий и жесткий пределы (softLimit
и hardLimit
).
Новый файл сегмента будет создан при условии:
- Либо все записи из лога закоммичены и превышен мягкий предел;
- Либо превышен жесткий предел.
Таким образом:
softLimit
- минимальный размер сегментаhardLimit
- максимальный размер сегмента
Это не строгие параметры - размер файла может быть больше каждого из указанных параметров. Можно их интерпретировать как подсказки.
Весь лог делится на 2 части:
- Закрытые сегменты - сегменты, запись в которые были завершены
- Активный - последний сегмент, в который ведется запись
Снапшот хранит в себе состояние приложения, к которому были применены команды до определенного индекса. Это необходимо для того, чтобы время старта приложения не было слишком большим.
В отличие от остальных файлов, после создания этого файла он не изменяется. Может только быть удален, после создания нового снапшота.
Для работы приложения в кластере используется алгоритм Raft. Этот алгоритм требует хранения определенных параметров, которые позволяют управлять поведением узла.
Когда приложение обрабатывает запрос пользователя, то команда, которая модифицирует состояние приложения должно быть
сохранено прежде ее применения.
Команда сохраняется в очередной сегмент лога.
Изначально, создается первый сегмент с индексом 0
.
Когда активный сегмент становится слишком большим, то будет создан очередной. В процессе работы, лог растет и постепенно он может стать слишком огромным. В результате будет занято слишком много места на диске и время старта возрастет.
Для избежания этого время от времени будут создаваться новые снапшоты состояния. Он создается когда количество закрытых сегментов между сегментом, котором находится индекс снапшота, и сегментом, в котором находится закоммиченная запись, превышает определенное количество.
Например, в сегментах 0 | 1 | 2 - Сегмент с индексом из снапшота | 3 | 4 | 5 | 6 - Тут индекс коммита | 7
(числами
указаны индексы сегментов) этими сегментами являются 3, 4, 5 и 6 и,
если этот параметр выставлен в 3, то тогда будет создан новый снапшот, а если 5, то нет.
Этот параметр можно указать в конфигурации.
После создания снапшота, все сегменты, которые имеют уже неактуальное состояние (содержат команды, все индексы которых меньше индекса снапшота), будут удалены.
На данный момент, при создании снапшота, все приложение останавливается (Stop The World). В будущем, это поведение можем поменять на неблокирующее.