From b75dffab84deae3925b10bec6af30b781ba35cdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=93=D1=80=D0=B8=D0=B3=D0=BE=D1=80=D0=B8=D0=B9=20=D0=A1?= =?UTF-8?q?=D0=B0=D1=84=D1=80=D0=BE=D0=BD=D0=BE=D0=B2?= Date: Tue, 6 Oct 2026 21:35:16 +0000 Subject: [PATCH] Update README.md --- README.md | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index b95b1aa..ffab1a1 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,8 @@ futriix — это лёгкая распределённая NoSQL‑СУБД н Ключевые механизмы надёжности и масштабируемости: * WAL — устойчивость к сбоям -* SAGA- для внешних batch +* Batch — атомарные группы операций +* SAGA — для внешних batch * Горизонтальное масштабирование @@ -227,7 +228,7 @@ futriix — это лёгкая распределённая NoSQL‑СУБД н | **Документ (Document)** | `map[string]interface{}` | Динамическая схема полей | | | Версия (`uint64`) | Для оптимистичных блокировок | | | Временные метки | Создание, обновление, удаление (Unix‑миллисекунды) | -| **Транзакция (Transaction)** | WAL (`Write‑Ahead Log`) | Журнал упреждающей записи для durability | +| **Batch (Batch)** | WAL (`Write‑Ahead Log`) | Журнал упреждающей записи для durability | | | Кэш операций | Локальное хранение изменений до коммита | | | Список блокировок | Отслеживание затронутых документов | | **Триггер (Trigger)** | `sync.Map` с составным ключом | `collection|event|name` для быстрого поиска | @@ -246,7 +247,7 @@ futriix — это лёгкая распределённая NoSQL‑СУБД н |:-:|----------|-------------------|-----------|-----------| | 1 | **Wait-free операции доступа** | • Чтение: `sync.Map.Load()` — атомарная операция без блокировок
• Запись: `sync.Map.Store()` — атомарная замена значения
• Удаление: `sync.Map.Delete()` — атомарное удаление | **O(1) амортизированное** | *Амортизированная сложность — средняя стоимость операции в серии операций, даже если отдельные операции могут быть дорогими* | | 2 | **Поиск по индексу** | **Уникальный индекс:**
1. `index.data.Load(value)` → получение ID документа
2. `docs.Load(ID)` → возврат документа

**Неуникальный индекс:**
1. `index.data.Range()` → сканирование всех записей
2. Сравнение значений с учётом типов (`compareValues`)
3. Сбор всех подходящих ID | **Уникальный: O(1)**

**Неуникальный: O(n)** | `n` — размер индекса | -| 3 | **Оптимистичная блокировка транзакций** | 1. `BeginTransaction()` → фиксация текущих версий документа
2. Выполнение операций в локальном кэше
3. `Prepare()` → проверка версий всех затронутых документов
4. `Commit()` → применение изменений, инкремент версий
5. При конфликте → `Abort()` и повтор | **E[T] = (1 / (1 - P_conflict)) × [O(M) + O(M × (V + K)) + O(WAL)]** | `𝔼[T]` — мат. ожидание времени выполнения
`1 - P_conflict` — вероятность успешного коммита
`M` — количество документов в транзакции
`V` — количество полей в документе
`K` — количество индексов
`WAL` — размер журнала | +| 3 | **Batch (атомарная группа операций)** | 1. `NewBatch()` → создание batch
2. Добавление операций (`AddInsert`, `AddUpdate`, `AddDelete`, `AddRestore`)
3. `Commit()` → запись всего batch в WAL с fsync
4. Применение операций к in-memory структурам
5. При ошибке — откат (best-effort) | **E[T] = O(M) + O(WAL)** | `M` — количество операций в batch
`WAL` — размер журнала | | 4 | **Валидация ограничений (Constraints)** | Последовательная проверка документа:
1. Обязательные поля → проверка наличия
2. Минимальные значения (`MinValues`) → сравнение чисел
3. Максимальные значения (`MaxValues`) → сравнение чисел
4. Regex паттерны → сопоставление строк
5. Enum значения → поиск в разрешённом списке | **O(k + m)** | `k` — количество полей в документе
`m` — количество ограничений | | 5 | **Выполнение триггеров** | Для каждого триггера события:
1. Проверка `Enabled`
2. Оценка условия (`TriggerCondition`)
3. Сопоставление оператора с полем документа
4. Выполнение действия (`abort`/`skip`/`modify`/`log`)
5. Логирование с временной меткой и длительностью | **O(T × (C + O))** | `T` — количество триггеров на событие
`C` — количество условий в триггере
`O` — количество операций в триггере | | 6 | **Мягкое удаление** | **SoftDelete:**
1. `doc.DeletedAt = now`
2. `doc.Version++`
3. `docs.Store(id, doc)` — сохранение, не удаление
4. `removeFromIndexes(doc)` — исключение из поиска

**Restore:**
1. `doc.DeletedAt = 0`
2. `doc.Version++`
3. `docs.Store(id, doc)`
4. `addToIndexes(doc)` — возврат в индексы | **O(1) + O(K)** | `K` — количество индексов в коллекции | @@ -271,6 +272,7 @@ futriix — это лёгкая распределённая NoSQL‑СУБД н | Мягкое удаление | Флаг deleted_at + удаление из индексов | Возможность восстановления | | Асинхронные триггеры | Буферизированный канал | Не блокируют основную операцию | | Плагины в песочнице | Изолированное Lua‑состояние | Безопасное расширение | +| Batch | WAL + локальный кэш | Атомарность без ACID |

@@ -287,7 +289,7 @@ futriix — это лёгкая распределённая NoSQL‑СУБД н | Поиск по неуникальному индексу | $O(n)$ | $n$ — размер индекса | | Обновление документа | $O(1) + O(k)$ | + проверка версий | | Удаление документа | $O(1) + O(k)$ | + возможная очистка индексов | -| Транзакция (commit) | $O(m) + \text{Raft}$ | $m$ — количество операций | +| Batch (commit) | $O(m) + \text{Raft}$ | $m$ — количество операций | | Валидация ограничений | $O(f + c)$ | $f$ — поля, $c$ — ограничения | | Экспорт базы данных | $O(N)$ | $N$ — общее количество документов | @@ -314,12 +316,12 @@ futriix — это лёгкая распределённая NoSQL‑СУБД н - **Процессор:** 64‑битный Intel или AMD (x86‑64) - **Оперативная память:** - - Linux: минимум 6 ГБ - - Illumos: минимум 8 ГБ (из‑за особенностей управления памятью и ZFS по умолчанию) + - Linux: минимум 6 ГБ + - Illumos: минимум 8 ГБ (из‑за особенностей управления памятью и ZFS по умолчанию) > [!IMPORTANT] > **Важно!!!** -> Для нагрузочного тестирования, шардинга и одновременной работы множества узлов(от 5 и выше) рекомендуется не менее 16 ГБ оперативной памяти на узел +> Для нагрузочного тестирования, шардинга и одновременной работы множества узлов(от 5 и выше) рекомендуется не менее 16 ГБ оперативной памяти на узел
@@ -357,7 +359,7 @@ unzip -v > * Дисковая подсистема: SSD/NVMe; HDD допустим только для тестов > * Файловая система: предпочтительно ZFS (особенно на Illumos) или XFS/ext4 на Linux > * Сеть: стабильное соединение между узлами, желательно 1 Gbps+; для Raft‑кластеров важна низкая задержка (latency) -> * Время: синхронизация времени между узлами (NTP/Chrony) обязательна для корректной работы MVCC, WAL и транзакций +> * Время: синхронизация времени между узлами (NTP/Chrony) обязательна для корректной работы WAL и batch-операций
@@ -392,7 +394,7 @@ go version * **[wal]** — журнал предзаписи (сегменты, синхронизация) -* **[mvcc]** — многоверсионность (версии, TTL) +* **[batch]** — настройки batch-операций (размер, таймауты) * **[saga]** — распределённые транзакции @@ -544,8 +546,8 @@ curl -X POST http://localhost:8080/api/v1/config \ "replication.sync_replication": true, "wal.segment_size_mb": 128, "wal.sync_interval_sec": 3, - "mvcc.max_versions_per_doc": 20, - "mvcc.retention_days": 14, + "batch.max_size": 1000, + "batch.timeout_ms": 5000, "saga.enabled": true, "saga.coordinator_count": 5, "backpressure.enabled": true, @@ -629,8 +631,8 @@ $ ./futriix ### Тестирование -Для проверки корректности функционирования субд на уровне исходного кода, был разработа набор из пяти тестов: (регрессионный, smoke-тест, функциональный, интеграционный и нагрузочный). -Разработанный набор из пяти вышеупомянутых тестов на языке Lua обеспечивает комплексную проверку всех ключевых компонентов СУБД: CRUD-операций, индексов, транзакций, ограничений целостности, ACL, триггеров, MVCC-версионирования, а также взаимодействия API с хранилищем и кластерной координации. +Для проверки корректности функционирования субд на уровне исходного кода, был разработан набор из пяти тестов: (регрессионный, smoke-тест, функциональный, интеграционный и нагрузочный). +Разработанный набор из пяти вышеупомянутых тестов на языке Lua обеспечивает комплексную проверку всех ключевых компонентов СУБД: CRUD-операций, индексов, batch-операций, ограничений целостности, ACL, триггеров, версионирования через WAL, а также взаимодействия API с хранилищем и кластерной координации. Регрессионный тест гарантирует, что изменения кода не нарушили существующую функциональность, smoke-тест выполняет быструю проверку доступности и базовой работоспособности системы. Функциональный и интеграционный тесты проверяют корректность реализации бизнес-требований и взаимодействие между компонентами, а нагрузочный тест оценивает производительность (латентность, пропускную способность) под различными сценариями использования. @@ -690,7 +692,7 @@ Futriix поддерживает привычный MongoDB‑синтаксис > [!NOTE] >**Выполнение операций**
-> Операции выполняются в рамках гарантий изоляции, обеспечиваемых MVCC и протоколом консенсуса Raft. +> Операции выполняются в рамках гарантий изоляции, обеспечиваемых WAL и протоколом консенсуса Raft. > Для распределённых транзакций применяется протокол Saga. @@ -1041,6 +1043,7 @@ saga.AddStep("reserve_payment", nil) sagaManager.Execute(saga) +```

(К началу)

@@ -1846,7 +1849,7 @@ Idle → Preparing → Migrating → Delta Sync → Validating → Completed В субд `futriix` также как и в традиционных субд, есть механизм **Ограничений (Constraints)**. **Ограничения (Constraints)**-это декларативные гарантии целостности (правила), действующие локально на каждом узле и согласующиеся через оркестратор SAGA. Они обеспечивают, что каждый шаг распределённого сценария сохраняет инварианты данных; конфликты и нарушения фиксируются до фиксации шага, а при необходимости компенсируются в рамках eventual consistency. -Ограничения на уровне коллекции поддерживают: `обязательные поля (required)`, `уникальность (unique)`, `минимальные/максимальные значения (min/max)`, `regex-паттерны` и `enum-списки`(фиксированные наборы допустимых значений, которые жёстко задают «разрешённые состояния» поля. Они работают как "строгая шпаргалка" для данных: нельзя сохранить ничего лишнего, а движок сразу фиксирует несоответствия — ещё **до попадания в WAL** и **до участия в MVCC‑снапшотах**.) допустимых значений. Все ограничения проверяются автоматически при вставке и обновлении документов. +Ограничения на уровне коллекции поддерживают: `обязательные поля (required)`, `уникальность (unique)`, `минимальные/максимальные значения (min/max)`, `regex-паттерны` и `enum-списки`(фиксированные наборы допустимых значений, которые жёстко задают «разрешённые состояния» поля. Они работают как "строгая шпаргалка" для данных: нельзя сохранить ничего лишнего, а движок сразу фиксирует несоответствия — ещё **до попадания в WAL** и **до участия в batch-снапшотах**.) допустимых значений. Все ограничения проверяются автоматически при вставке и обновлении документов. ```sh # Добавление обязательного поля @@ -2757,8 +2760,8 @@ futriix:~> doc compression employees 550e8400-e29b-41d4-a716-446655440000 **Вопрос: Почему версия обозначена как «Futriix 2 i²», а не просто «2.0»?**


-**Ответ: «2» — номер версии: здесь собраны ключевые компоненты (шардинг, WAL, MVCC и др.).** -**i2i2 — математическая метафора: хотя ii — мнимая единица, её квадрат даёт абсолютно точный результат (i2=−1i2=−1). Так и Futriix: даже в сложной распределённой среде с параллельными операциями (wait‑free, lock‑free) система выдаёт строго предсказуемые результаты — за счёт Raft, ACID и MVCC. Это близко философии OpenIndiana/Illumos: детерминизм и контроль над ресурсами.** +**Ответ: «2» — номер версии: здесь собраны ключевые компоненты (шардинг, WAL, Batch и др.).** +**i2i2 — математическая метафора: хотя ii — мнимая единица, её квадрат даёт абсолютно точный результат (i2=−1i2=−1). Так и Futriix: даже в сложной распределённой среде с параллельными операциями (wait‑free, lock‑free) система выдаёт строго предсказуемые результаты — за счёт Raft, Batch и WAL. Это близко философии OpenIndiana/Illumos: детерминизм и контроль над ресурсами.**

(К началу)

@@ -2789,7 +2792,7 @@ futriix:~> doc compression employees 550e8400-e29b-41d4-a716-446655440000 - [x] Библиотека "raft-boltdb" заменить на встроенное файловое хранилище - [x] Реализовать уникальные и составные индексы - [x] Реализовать временные метки для основных объектов субд (таппл, коллекция, документ, поле, индекс, транзакция, ACL, узел кластера) -- [x] Реализовать MVCC версионирование - поддержка множественных версий документов +- [x] Реализовать Batch-версионирование - поддержка множественных версий документов через WAL - [x] Реализовать временные метки для объектов субд (Ограничений, Импорта-Экспорта, Триггеров, Lua-плагинов) - [x] Реализовать обработку состояний "split-brain" - [x] Реализовать Pipeline репликации-группировку нескольких команд в один Raft лог для уменьшения сети @@ -2808,7 +2811,7 @@ futriix:~> doc compression employees 550e8400-e29b-41d4-a716-446655440000 - [x] Реализовать Distributed Transactions - двухфазный коммит для распределённых транзакций - [x] Реализовать Deadlock Detection - циклический детектор дедлоков с таймаутами (DFS по графу ожидания) - [x] Реализовать Transaction Timeout - настраиваемый таймаут для долгих транзакций -- [x] Вынести настройи настройки MVCC,WAL и настройки плагинов из исходного кода проекта в файл конфигурации "config.toml" +- [x] Вынести настройи настройки Batch, WAL и настройки плагинов из исходного кода проекта в файл конфигурации "config.toml" - [x] Реализовать выделение жирным шифтом все информационные сообщения в скриптах сборки - [x] Реализовать ограничения на количество создаваемых Lua-состояний в плагинах - [x] Реализовать WAL recovery сделать асинхронным для ускорения скорости работы субд @@ -2879,4 +2882,4 @@ futriix:~> doc compression employees 550e8400-e29b-41d4-a716-446655440000 **Григорий Сафронов** - [E-mail](gvsafronov@yandex.ru)
**Сообщество** - [Сообщество Futriix](https://source.futriix.ru/gvsafronov/futriix/issues/new/choose) -

(К началу)

+

(К началу)

\ No newline at end of file