Initialize
Continous integration / Tests (push) Canceled after 0s
Testing clients / Build beanstalkd (push) Canceled after 0s
Continous integration / Docker build (push) Canceled after 0s
Testing clients / Test Pheanstalk PHP (push) Canceled after 0s
Testing clients / Test Greenstalk Python (3.9) (push) Canceled after 0s
Testing clients / Test Pystalk Python (3.10) (push) Canceled after 0s
Continous integration / Tests (push) Canceled after 0s
Testing clients / Build beanstalkd (push) Canceled after 0s
Continous integration / Docker build (push) Canceled after 0s
Testing clients / Test Pheanstalk PHP (push) Canceled after 0s
Testing clients / Test Greenstalk Python (3.9) (push) Canceled after 0s
Testing clients / Test Pystalk Python (3.10) (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
# Многопроцессный Beanstalkd
|
||||
|
||||
Статус: постановка на реализацию, код не реализован.
|
||||
Дата фиксации: 2026-10-15.
|
||||
База: исходники Beanstalkd 1.13 в этом каталоге.
|
||||
|
||||
## Цель
|
||||
|
||||
Позволить одному логическому серверу использовать несколько CPU-ядер для обработки независимых tubes, сохранив модель заданий Beanstalkd и динамический жизненный цикл очередей.
|
||||
|
||||
Принятое решение: процессы-владельцы групп tubes. У каждого владельца собственный event loop, задания, очереди, таймеры и WAL; сетевые frontend-процессы направляют операции владельцам через IPC. Supervisor обеспечивает эксклюзивность owner slots и управление жизненным циклом процессов.
|
||||
|
||||
```text
|
||||
+-- owner slot 0: tubes, jobs, WAL
|
||||
clients --> frontend(s) --IPC--+-- owner slot 1: tubes, jobs, WAL
|
||||
+-- owner slot N: tubes, jobs, WAL
|
||||
|
||||
supervisor: topology, process generations, startup, shutdown, restart
|
||||
```
|
||||
|
||||
## Границы Первого Этапа
|
||||
|
||||
- Один хост, статическая карта распределения, отдельный WAL каждого владельца.
|
||||
- Каждый `reserve` / `reserve-with-timeout` работает с одной наблюдаемой tube. Настройка `watch target`, `ignore default` допускается.
|
||||
- Связь tube с владельцем определяется по имени через фиксированные логические разделы. Постоянного каталога дескрипторов всех tubes нет.
|
||||
- Consumer может держать несколько заданий. Его `use`, текущий watch list и ранее полученные резервации не обязаны относиться к одной tube или одному владельцу.
|
||||
- Политика перехода от существующего однопроцессного сервера определяется в эпике 01. Рекомендуется opt-in с сохранением legacy, но обязательная поддержка двух режимов пока не утверждена.
|
||||
- Полный end-to-end путь команд, восстановление, диагностика и проверки отказов входят в результат, а не откладываются после демонстрации `put`/`reserve`.
|
||||
|
||||
## Вне Объёма
|
||||
|
||||
- Межшардовый выбор задания из нескольких наблюдаемых tubes.
|
||||
- Распараллеливание одной tube, глобальный FIFO между tubes.
|
||||
- Динамическая миграция, автоматическая балансировка и изменение карты при работе сервера.
|
||||
- Кластер между хостами, репликация и автоматическое назначение данных упавшего владельца другому slot.
|
||||
- Shared-memory allocator, zero-copy и io_uring как предварительное условие реализации.
|
||||
- Exactly-once выполнение пользовательского кода.
|
||||
|
||||
## Основные Инварианты
|
||||
|
||||
1. Имя tube всегда имеет одного владельца в пределах версии топологии, даже когда объект tube не существует.
|
||||
2. Объект создаётся только владельцем и только по операции, которая предполагает создание по протоколу.
|
||||
3. Два процесса не изменяют данные одного owner slot одновременно.
|
||||
4. Переходы состояний job последовательны у владельца; права на reserved job принадлежат логической клиентской сессии.
|
||||
5. Один reserve имеет не более одного результата; job имеет не более одной действующей резервации.
|
||||
6. Очерёдность команд и ответов одного TCP-соединения сохраняется.
|
||||
7. Сбой, недоступность и неизвестный результат не маскируются под успешную операцию или отсутствие задания.
|
||||
8. Накопление IPC-запросов, ответов и тел ограничено памятью; медленный клиент не блокирует чужие очереди неограниченно.
|
||||
9. Перезапуск с WAL использует ту же топологию и корректное пространство ID; несовпадение конфигурации обнаруживается до записи данных.
|
||||
|
||||
## Эпики И Зависимости
|
||||
|
||||
| ID | Постановка | Зависимости | Результат |
|
||||
| --- | --- | --- | --- |
|
||||
| 01 | [Контракты и baseline](01-contract.md) | Нет | Решения по внешнему поведению, отказам, ID и конфигурации |
|
||||
| 02 | [Владение tubes](02-ownership.md) | 01 | Детерминированная маршрутизация и локальное создание |
|
||||
| 03 | [IPC и сессии](03-ipc-sessions.md) | 01; интерфейсы 02 | Межпроцессный транспорт и безопасный жизненный цикл сессий |
|
||||
| 04 | [Queue engine и протокол](04-queue-engine.md) | 02, 03 | Все операции над очередями через владельцев |
|
||||
| 05 | [WAL и ID](05-persistence.md) | 01, 02; интеграция 03, 04 | Восстановление, уникальные ID, изоляция журналов |
|
||||
| 06 | [Supervisor и эксплуатация](06-supervisor.md) | 02, 03; интеграция 04, 05 | Управляемый запуск, отказ и остановка процессов |
|
||||
| 07 | [Приёмка и производительность](07-validation.md) | Baseline после 01; итог после 02-06 | Воспроизводимые функциональные и нагрузочные доказательства |
|
||||
|
||||
Порядок не запрещает совместную разработку согласованных интерфейсов. Минимальный запуск дочернего процесса для тестов можно сделать раньше эпика 06; это не означает готовность supervisor. Тесты пишутся в каждом эпике, а не только в конце.
|
||||
|
||||
## Общая Приёмка
|
||||
|
||||
- Все обязательные решения эпика 01 закрыты и документированы до реализации зависящего от них контракта.
|
||||
- Исходные тесты используются как регрессионная база; отклонения допустимы только по согласованной матрице совместимости. Если выбран отдельный legacy-режим, он проходит прежний набор без ограничения multi-watch.
|
||||
- Успешно проверены минимум два owner slots и несколько frontend-процессов, в том числе гонка создания одной tube через разные frontend.
|
||||
- Протестированы job lifecycle, права сессий, таймеры, slow clients, аварии и WAL при одинаковых с baseline настройках durability.
|
||||
- На независимых tubes подтверждён рост пропускной способности и реальная работа нескольких owner CPU; точный порог фиксируется после baseline, до финальных замеров.
|
||||
- Для одной горячей tube ограничение последовательности явно показано в отчёте, а не скрыто агрегированной нагрузкой.
|
||||
- Обновлены `README.md`, `doc/protocol.txt`, исходник руководства и эксплуатационные инструкции при реализации. Внешние ограничения и совместимость старых данных описаны явно.
|
||||
|
||||
## Основание
|
||||
|
||||
Текущий сервер последовательно выполняет `prottick`, `socknext` и callback в `serv.c:srvserve`. Реестры jobs/tubes и генератор ID глобальны. `process_queue` связывает job с `Conn*`, а WAL защищён от второго владельца. Поэтому разделение только listening socket или вызов `fork()` не дают корректного общего сервера.
|
||||
|
||||
Критический краткий контекст для последующей работы: [../AGENTS.md](../AGENTS.md).
|
||||
Reference in New Issue
Block a user