futriix - это легковесная, распределённая NOSQL, использующая алгоритмы неблокирующей синхронизации - `wait-free` и `lock-free` in-memory СУБД, реализованная на языке Go с поддержкой плагинов на языке lua использующая алгоритм консенсуса Raft. <br>
По своей сути, Futriis является лёгкой HTAP-СУБД с уклоном в OLTP благодаря wait-free структурам и ACID-транзакциям, а также мощными OLAP-возможностями через индексы, триггеры, Lua-плагины и аналитические функции. Это позволяет обрабатывать и анализировать данные в режиме, близком к реальному времени, в первую очередь для эксплуатации в замкнутых программных средах под управлением ОС на базе ядра Illumos и Solaris (OpenIndiana Hipster, Oracle Solaris). Архитектурное решение использовать отдельные индексы от данных, атомарные операции и версионирование позволяет эффективно обрабатывать смешанную нагрузку без необходимости применять отдельные системы для OLTP и OLAP.<br>
В futriix реализован WUI-интерфейс для удобства её администрирования и эксплуатации.
Но она также совместима с популярными Linux-дистрибутивами (Debian,Ubuntu,Fedora), т.е. операционными системами построенными на базе ядра Linux.
Проект распространяется под лицензией **`CDDL 1.0`**. Подробнсти в файлах `LICENSE`.
Эта лицензия позволяет вам производить копирование, модификацию, распространение, включение в другие проекты, получение патентных прав, распространение бинарных файлов с доступом к их исходному коду. Она запрещает вам добавление новых ограничений, скрытие изменений, удаление оригинальных уведомлений, несоблюдение условий CDDL 1.0 при перераспределении, неправильное связывание с другими лицензиями.
Все дополнительное программное обеспечение (включая скрипт компиляции проекта `build.sh`) предоставляются "как есть", без гарантий и обязательств со стороны разработчиков. Разработчики не несут ответственности за прямой или косвенный ущерб, вызванный использованием открытого кода Futriix и futriix или технических решений, использующих этот код.
* **База Данных(БД)** - это структурированное, организованное хранилище данных, которое позволяет удобно собирать, хранить, управлять и извлекать информацию.
* **Система Управления Базами Данных(СУБД)** - это программное обеспечение, которое позволяет создавать, управлять и взаимодействовать с базами данных
* **Таппл (Tapple)** - аналог базы данных в РСУБД
* **Слайс (Slice)** - аналог таблицы
* **Кортеж (Tuple)** - аналог записи в таблице
* **Мультимодельная СУБД** - это СУБД, которая объединяет в себе поддержку нескольких моделей данных (реляционной, документной, графовой, ключ-значение и др.) в рамках единого интегрированного ядра.
* **Резидентная СУБД** - это СУБД, которая работает непрерывно в оперативной памяти (RAM).
* **Инстанс** - это запущенный экземляр базы данных.
* **Узел (хост,нода,шард)** - это отдельный сервер (физический или виртуальный), который является частью кластера или распределенной системы и выполняет часть общей работы.
* **Слайс (от англ. "slice"-слой)** - это логический и физически изолированный фрагмент коллекции документов, полученный в результате горизонтального партиционирования (шардирования) и размещенный на определенном узле кластера с целью масштабирования производительности и объема данных.
* **Репликасет** - это группа серверов СУБД, объединенных в отказоустойчивую конфигурацию, где один узел выполняет роль первичного (принимающего операции записи), а один или несколько других - роль вторичных (синхронизирующих свои данные с первичным и обслуживающих чтение), с автоматическим переизбранием первичного узла в случае его сбоя.
* **Временная метка (time stamp)** - это автоматически фиксируемое значение времени создания, изменения или удаления объекта в СУБД, представленное в формате Unix-миллисекунд (количество миллисекунд, прошедших с 1 января 1970 года) с возможностью отображения в человекочитаемом виде YYYY-MM-DD HH:MM:SS.mmm. Необходима для понимание последовательности операций при сбоях, выявления аномалий в поведении системы,архивация старых записей, отслеживание несанкционированных изменений, автоматический выход из сессий с ограниченным временем действия, Статистика активности за период)
* **OLTP (Online Transactional Processing-Онлайн обработка транзакций)**- это технология обработки транзакций в режиме реального времени. Её основная задача заключается в обеспечении быстрого и надёжного выполнения операций, которые происходят ежесекундно в бизнесе. Они обеспечивают быстрое выполнение операций вставки, обновления и удаления данных, поддерживая целостность и надежность транзакций.
* **OLAP (Online Analytical Processing - Оперативная аналитическая обработка)** — это технология, которая работает с историческими массивами информации, извлекая из них закономерности и производя анализ больших объемов данных, поддерживает многоразмерные запросы и сложные аналитические операции. Данная технология оптимизирована для выполнения сложных запросов и предоставления сводной информации для принятия управленческих решений.
* **HTAP (Hybrid Transactional and Analytical Processing - Гибридная транзакционно-аналитическая обработка)**- это технология, которая заключаются в эффективном совмещении операционных и аналитических запросов, т.е. классов OLTP и OLAP.
* **Кластер** - это группа компьютеров, объединённых высокоскоростными каналами связи для решения сложных вычислительных задач и представляющая с точки зрения пользователя группу серверов, объединенных для работы как единая система.
* **WUI (от англ. Web-User-Interface "веб интерфейс пользователя")** - это термин проекта futriix, означающий веб-интерфейс (интерфейс работающий в веб-браузере)
* **workflow (англ. workflow — «поток работы»)** — это принцип организации рабочих процессов, в соответствии с которым повторяющиеся задачи представлены как последовательность стандартных шагов.
* **Lock‑free алгоритмы** — это алгоритмы, гарантирующие, что хотя бы один из потоков выполнения продвигается вперёд (завершает операцию) за конечное число шагов, даже если другие потоки задержаны или прерваны. При этом отдельные потоки могут испытывать задержки, но система в целом продолжает прогрессировать.
* **Wait‑free алгоритмы** — это алгоритмы, гарантирующие, что каждый поток завершит свою операцию за заранее ограниченное (конечное) число шагов, независимо от состояния и поведения остальных потоков. Это обеспечивает отсутствие задержек и голода для любого из участников параллельного выполнения.
* **ЗПС (Замкнутая Программная Среда)** - Это локальная сеть предприятия или организации как правило без доступа к сети "Интернет", своего рода "фильтр" содержащий в себе перечень программного обеспечения (ПО), которому разрешено работать на компьютере, в то время как ПО, которого нет в этом списке, будет запрещено к исполнению.
* Символом приглашения **«#»**, в документации отмечены команды, выполняемые с привилегиями суперпользователя (**root**)
* Символом приглашения **«$»**, в документации отмечены команды, выполняемые с правами обычного пользователя (**user**)
> Futriix изначально разрабатывался как монолит, внутреннее ядро которого, включающее фрейморк, для реализации WUI носило кодовое имя
> «Futriis».
> С переходом к финальному названию «Futriix»- внешние интерфейсы были переименованы,
> но внутренние переменные сохранили исходное имя в целях минимизации изменений. А также фрейморк, для реализации WUI сохранил своё прежнее название "Futriis" и был интегрирован в ядро субд.
> Считайте `futriis` внутренним псевдонимом `futriix`
> И помните, что в настоящий момент «Futriis — это историческое название ядра Futriix»
> Поскольку `Futriix` эксплуатируется преимущественно в ЗПС, где организационные и сетевые меры исключают перехват трафика и подбор учётных данных, реализованный механизм аутентификации является достаточным в рамках принятой модели угроз.
| 1 | **Wait-free операции доступа** | • Чтение: `sync.Map.Load()` — атомарная операция без блокировок<br>• Запись: `sync.Map.Store()` — атомарная замена значения<br>• Удаление: `sync.Map.Delete()` — атомарное удаление | **O(1) амортизированное** | *Амортизированная сложность — средняя стоимость операции в серии операций, даже если отдельные операции могут быть дорогими* |
| 2 | **Поиск по индексу** | **Уникальный индекс:**<br>1. `index.data.Load(value)` → получение ID документа<br>2. `docs.Load(ID)` → возврат документа<br><br>**Неуникальный индекс:**<br>1. `index.data.Range()` → сканирование всех записей<br>2. Сравнение значений с учётом типов (`compareValues`)<br>3. Сбор всех подходящих ID | **Уникальный: O(1)**<br><br>**Неуникальный: O(n)** | `n` — размер индекса |
| 3 | **Оптимистичная блокировка транзакций** | 1. `BeginTransaction()` → фиксация текущих версий документа<br>2. Выполнение операций в локальном кэше<br>3. `Prepare()` → проверка версий всех затронутых документов<br>4. `Commit()` → применение изменений, инкремент версий<br>5. При конфликте → `Abort()` и повтор | **E[T] = (1 / (1 - P_conflict)) × [O(M) + O(M × (V + K)) + O(WAL)]** | `𝔼[T]` — мат. ожидание времени выполнения<br>`1 - P_conflict` — вероятность успешного коммита<br>`M` — количество документов в транзакции<br>`V` — количество полей в документе<br>`K` — количество индексов<br>`WAL` — размер журнала |
| 4 | **Валидация ограничений (Constraints)** | Последовательная проверка документа:<br>1. Обязательные поля → проверка наличия<br>2. Минимальные значения (`MinValues`) → сравнение чисел<br>3. Максимальные значения (`MaxValues`) → сравнение чисел<br>4. Regex паттерны → сопоставление строк<br>5. Enum значения → поиск в разрешённом списке | **O(k + m)** | `k` — количество полей в документе<br>`m` — количество ограничений |
| 5 | **Выполнение триггеров** | Для каждого триггера события:<br>1. Проверка `Enabled`<br>2. Оценка условия (`TriggerCondition`)<br>3. Сопоставление оператора с полем документа<br>4. Выполнение действия (`abort`/`skip`/`modify`/`log`)<br>5. Логирование с временной меткой и длительностью | **O(T × (C + O))** | `T` — количество триггеров на событие<br>`C` — количество условий в триггере<br>`O` — количество операций в триггере |
| 6 | **Мягкое удаление** | **SoftDelete:**<br>1. `doc.DeletedAt = now`<br>2. `doc.Version++`<br>3. `docs.Store(id, doc)` — сохранение, не удаление<br>4. `removeFromIndexes(doc)` — исключение из поиска<br><br>**Restore:**<br>1. `doc.DeletedAt = 0`<br>2. `doc.Version++`<br>3. `docs.Store(id, doc)`<br>4. `addToIndexes(doc)` — возврат в индексы | **O(1) + O(K)** | `K` — количество индексов в коллекции |
| 7 | **TTL-очистка** | Фоновый цикл с интервалом `TTL/2` секунды:<br>1. `Scan` всех документов коллекции<br>2. Проверка: `now - doc.CreatedAt > TTL × 1000`<br>3. Добавление просроченных ID в буфер<br>4. Пакетное удаление (с учётом SoftDelete) | **O(N × (1 + K)) + O(D × (1 + K))** | `N` — общее количество документов<br>`K` — количество индексов<br>`D` — количество просроченных документов (`D ≤ N`) |
| 8 | **Сериализация MessagePack** | **Экспорт:**<br>1. Обход всех коллекций БД<br>2. Сбор документов, метаданных, индексов, ограничений<br>3. Добавление экспортных метаданных (время, версия)<br>4. `Marshal` в бинарный формат<br><br>**Импорт:**<br>1. `Unmarshal` из бинарного формата<br>2. Восстановление структуры БД и коллекций<br>3. Сохранение исходных временных меток<br>4. Фиксация метаданных импорта | **O(N × F) + O(C × I)** | `N` — общее количество документов<br>`F` — среднее количество полей в документе<br>`C` — количество коллекций<br>`I` — среднее количество индексов на коллекцию |
| 9 | **Распределённый консенсус (Raft)** | **Кластерные операции:**<br>1. Лидер принимает запрос на запись<br>2. Репликация лога на followers<br>3. Подтверждение от большинства (quorum)<br>4. Коммит и применение к state machine<br>5. Ответ клиенту<br><br>**Выбор лидера:**<br>1. Heartbeat-таймаут<br>2. Переход в состояние candidate<br>3. Запрос голосов (`RequestVote`)<br>4. Получение голосов большинства<br>5. Становление лидером | **Операция записи:**<br>**O(L) + O(R) + O(Commit)**<br><br>**Выбор лидера:**<br>**В среднем: O(R × log N)**<br>**В худшем: O(R × N)** | `L` — размер лога операции<br>`R` — RTT до followers (сетевая задержка)<br>`Commit` — время применения к state machine<br>`N` — количество узлов в кластере |
| 10 | **Работа Lua-плагинов** | **Загрузка:**<br>1. Чтение `.lua` файла<br>2. Создание изолированного Lua-состояния<br>3. Регистрация функций доступа к СУБД<br>4. Выполнение скрипта в защищённом режиме<br>5. Сохранение указателя на состояние<br><br>**Выполнение функции:**<br>1. Поиск функции в глобальном пространстве Lua<br>2. Конвертация Go → Lua значений<br>3. Вызов с защитой от паники<br>4. Измерение времени выполнения<br>5. Конвертация результата Lua → Go<br>6. Логирование события | **Загрузка:**<br>**O(P + C)**<br><br>**Выполнение функции:**<br>**O(convert_args + execution + convert_result)** | `P` — размер файла плагина (байт)<br>`C` — сложность компиляции Lua (обычно O(P))<br>`convert_args = O(N_args × V)`<br>`execution = O(L)` — время выполнения скрипта<br>`convert_result = O(V)`<br>`V` — сложность конвертации значения (зависит от глубины вложенности) |
<br>
<br>
<br>
**Ключевые особенности реализации**
| Особенность | Реализация | Преимущество |
|-----------|------------|--------------|
| Wait‑free чтение | sync.Map + атомарные операции | Нет блокировок при чтении |
| Отдельные индексы | Индексы в sync.Map, отдельно от документов | Параллельный доступ к данным и индексам |
| Версионирование | uint64 в каждом документе | Оптимистичные блокировки |
| Гибкая схема | map[string]interface{} | Динамическое изменение структуры |
| Мягкое удаление | Флаг deleted_at + удаление из индексов | Возможность восстановления |
| Асинхронные триггеры | Буферизированный канал | Не блокируют основную операцию |
| Плагины в песочнице | Изолированное Lua‑состояние | Безопасное расширение |
В субд **"futriix"** используется два журнала для ведение логов: `"futriix.log"`-основной журнал, в котором ведутся логи при работе в субд через терминал, и `"webui.log"`-основной журнал, в котором ведутся логи при работе в субд через веб-интрефейс.
**futriix.log** — основной системный журнал, фиксирующий все события жизненного цикла СУБД: запуск/остановку сервера, инициализацию компонентов (транзакции, Raft-координатор, ACL), состояние кластера и критические ошибки выполнения запросов.
**webui.log** — специализированный журнал веб-интерфейса, регистрирующий только действия пользователей через Web UI: успешные и неудачные попытки входа, управление аватарами, создание/удаление триггеров и индексов, а также операции импорта/экспорта данных.
Оба журнала используют структурированный JSON-формат (для webui.log) и текстовый формат с временными метками (для futriis.log), что обеспечивает удобный парсинг и интеграцию с системами мониторинга.
Журналы автоматически ротируются и ограничены по размеру (по умолчанию 10000 записей для webui.log), предотвращая неконтролируемый рост дискового пространства при длительной работе сервера.
Разработанный набор из пяти тестов (регрессионный, smoke-тест, функциональный, интеграционный и нагрузочный) на языке Lua обеспечивает комплексную проверку всех ключевых компонентов СУБД: CRUD-операций, индексов, транзакций, ограничений целостности, ACL, триггеров, MVCC-версионирования, а также взаимодействия API с хранилищем и кластерной координации.
Регрессионный тест гарантирует, что изменения кода не нарушили существующую функциональность, smoke-тест выполняет быструю проверку доступности и базовой работоспособности системы.
Функциональный и интеграционный тесты проверяют корректность реализации бизнес-требований и взаимодействие между компонентами, а нагрузочный тест оценивает производительность (латентность, пропускную способность) под различными сценариями использования.
Команды для запуска тестов приведены ниже:
> [!IMPORTANT]
> 1. Перед запуском тестов убедитесь, что СУБД запущена и HTTP API доступен на порту 8080
> 2. Load test может занять несколько минут при больших объёмах данных
```bash
# Установка зависимостей для Lua-тестирования
sudo apt install lua5.3 lua-socket
# Запуск регрессионного теста
lua test_regression.lua
# Запуск smoke-теста
lua test_smoke.lua
# Запуск функционального теста
lua test_functional.lua
# Запуск интеграционного теста
lua test_integration.lua
# Запуск нагрузочного теста
lua test_performance.lua
# Запуск всех тестов последовательно
for test in test_regression.lua test_smoke.lua test_functional.lua test_integration.lua test_performance.lua; do
> СУБД futriiX полностью совместима по синтаксису запросов с NOSQL-субд MongoDB.
> Вы можете использовать знакомые NoSQL-конструкции и драйверы, легко мигрируя с существующей инфраструктуры.
В субд futriix поддерживаются MongoDB-подобный синтаксис для команд, являющийся основными в любой субд из класса **CRUD (Create,Read, Update, Delete- Создание, Чтение, Обновление, Удаление**) работы с документами: db.collection.insert(), find(), update(), delete(). Операции выполняются wait-free с использованием атомарных sync.Map, поддерживают автоматическую генерацию _id и валидацию схемы. Кроме того, каждый объект субд будь то таппл или поле, содержат в себе автоматически создаваемую временную метку, обладающей следующими свойствами:
* Автоматические — не требуют ручного указания
* Атомарные — фиксируются на уровне каждой операции
* Высокоточные — до миллисекунды
* Неизменяемые — created_at никогда не меняется
* Аудируемые — все изменения протоколируются в audit log
```sh
# Создание новой базы данных
futriix:~> create database company
✓ Database 'company' created at 2026-01-15 10:30:45.123
futriix:~> create database shop
✓ Database 'shop' created at 2026-01-15 10:30:46.456
# Переключение на базу данных
futriix:~> use company
✓ Switched to database 'company'
futriix:~> use shop
✓ Switched to database 'shop'
# Просмотр всех баз данных
futriix:~> show databases
Databases:
company (created: 2026-01-15 10:30:45.123)
* shop (created: 2026-01-15 10:30:46.456)
test (created: 2026-01-14 09:15:22.789)
# Удаление базы данных
futriix:~> drop database test
✓ Database 'test' dropped at 2026-01-15 10:31:12.789
# Создание коллекции
futriix:~> use company
✓ Switched to database 'company'
futriix:~> create collection employees
✓ Collection 'employees' created in database 'company' at 2026-01-15 10:32:15.234
futriix:~> create collection departments
✓ Collection 'departments' created in database 'company' at 2026-01-15 10:32:18.567
futriix:~> create collection projects
✓ Collection 'projects' created in database 'company' at 2026-01-15 10:32:21.890
# Просмотр всех коллекций
futriix:~> show collections
Collections in database 'company':
- employees (created: 2026-01-15 10:32:15.234)
- departments (created: 2026-01-15 10:32:18.567)
- projects (created: 2026-01-15 10:32:21.890)
# Удаление коллекции
futriix:~> drop collection projects
✓ Collection 'projects' dropped from database 'company' at 2026-01-15 10:33:05.123
Futriix поддерживает первичные (по _id) и вторичные индексы, хранящиеся отдельно от документов. Также в нём присутствуют уникальные и составные индексы, поиск по точному значению и префиксу, а кроме того автоматическое обновление индексов при изменениях документов.
```sh
# Создание обычного индекса
futriix:~> create index employees name_idx name
✓ Index 'name_idx' created on collection 'employees' at 2026-01-15 10:50:15.123
# Создание уникального индекса
futriix:~> create index employees email_idx email unique
✓ Index 'email_idx' created on collection 'employees' at 2026-01-15 10:50:18.456
# Создание составного индекса
futriix:~> create index employees dept_age_idx department,age
✓ Index 'dept_age_idx' created on collection 'employees' at 2026-01-15 10:50:21.789
В субд **futriix** для обеспечения надёжности (durability) и быстрого восстановления бд из резевной копии, реализована полноценная поддержка WAL (Write-Ahead Logging). Журнал WAL по умолчанию хранится в файле **futriix.wal**, находящимся в каталоге **futriix**, а также поддержка ACID-транзакций с MVCC (Multi-Version Concurrency Control).
Доступны команды startSession(), startTransaction(), commitTransaction(), abortTransaction() с восстановлением после сбоев через журнал предзаписи.
> [!TIP]
> WAL- это журнал предзаписи транзакций, который в субд **futriix** выполняет следующие действия:
> 1. Хранит все операции транзакций до их фиксации (INSERT, UPDATE, DELETE)
> 2. Записывает каждое изменение последовательно с LSN (Log Sequence Number)
> 3. Используется для восстановления после сбоя через recoverFromWAL()
> 4. Формат: бинарный с CRC-контролем, размером записи и типом (Transaction/Checkpoint)
Субд `futriix` является распределённой субд. Согласованность узлов в распределённом кластере определяется на основе протокола **Raft**с автоматическими выборами лидера. Поддерживаются одноузловой (для запуска на одном узле, без организации кластера) и многокластерный режимы, репликация данных (синхронная/асинхронная), мастер-мастер репликация и health-мониторинг узлов.
Протокол Raft в субд был реализован для отказоустойчивости. Безопасность каналов и аутентификация узлов возложены на инфраструктуру ЗПС (изоляция сети, статическая маршрутизация, контроль администратора). Модель угроз ЗПС не предполагает наличие атакующего внутри кластерной сети.
Шифрование Raft-трафика не реализовано, так как при развёртывании в ЗПС все межсерверные соединения находятся в пределах одного физически изолированного сегмента. В случае требования шифрования на уровне приложения, администратор ЗПС может использовать туннелирование (IPsec, WireGuard) средствами нижележащей сетевой инфраструктуры.
Автомасштабирование реализовано на основе комбинированного алгоритма **PHA (Predictive Horizontal Autoscaler)- Горизонтальный автомасштабировщик с прогнозированием нагрузки**
В субд `futriix` также как и в традиционных субд, есть механизм **Ограничений (Constraints)**. Ограничения на уровне коллекции поддерживаются: обязательные поля (required), уникальность (unique), минимальные/максимальные значения (min/max), regex-паттерны и enum-списки допустимых значений. Все ограничения проверяются автоматически при вставке и обновлении документов.
```sh
# Добавление обязательного поля
futriix:~> add required employees email
✓ Required field 'email' added to collection 'employees'
# Добавление ограничения уникальности
futriix:~> add unique employees phone
✓ Unique constraint added for field 'phone' on collection 'employees'
# Добавление минимального значения
futriix:~> add min employees age 18
✓ Min constraint added for field 'age' on collection 'employees' (min: 18.00)
# Добавление максимального значения
futriix:~> add max employees age 65
✓ Max constraint added for field 'age' on collection 'employees' (max: 65.00)
Для создания бекапов, в субд существуют команды `export` и `import`, позволяющие выгружать/загружать целые базы данных в формате **MessagePack**. Экспорт сохраняет документы с метаданными (версии, временные метки), импорт поддерживает пропуск существующих документов и детальную статистику.
Для расширения функциональных возможностей субд **без изменения её исходного кода**, в futriix была реализована система расширения функциональности через Lua-скрипты с изолированным окружением. Плагины имеют доступ к БД, транзакциям, триггерам, могут логировать события и взаимодействовать через событийную шину, а также они доступны в веб-интерфейсе.
```sh
# Просмотр информации о системе плагинов
futriix:~> plugin status
=== Plugin System Status ===
Enabled: true
Plugins Directory: ./plugins
Loaded Plugins: 3
Total Executions: 125
# Список загруженных плагинов
futriix:~> plugin list
=== Loaded Plugins ===
validation (v1.0.0) by admin - Document validation rules
Status: RUNNING
audit (v2.1.0) by security - Audit trail logger
Status: RUNNING
notify (v1.2.0) by devops - Email and webhook notifications
В futriix реализована многоуровневая система контроля доступа, основанная на **ACL (Access Contol Lists -Списки контроля доступа**) с аутентификацией по сессиям. В ней поддерживаются следующие роли (read, write, delete, admin) с гранулярным контролем на уровне базы данных и коллекции.
```sh
# Вход в систему
futriix:~> acl login admin admin
✓ Logged in as 'admin' with role 'admin'
# Выход из системы
futriix:~> acl logout
✓ Logged out
# Назначение прав доступа (после входа как admin)
futriix:~> acl login admin admin
✓ Logged in as 'admin' with role 'admin'
futriix:~> use company
✓ Switched to database 'company'
# Назначение прав на чтение
futriix:~> acl grant employees reader r
✓ Permissions 'r' granted to role 'reader' on collection 'employees'
# Назначение прав на чтение и запись
futriix:~> acl grant employees editor rw
✓ Permissions 'rw' granted to role 'editor' on collection 'employees'
# Назначение полных прав (администратор коллекции)
futriix:~> acl grant employees admin rwda
✓ Permissions 'rwda' granted to role 'admin' on collection 'employees'
В субд futriix для взаимодействия субд с веб-прилоджениями по сети, реализован интерфейс RESTful API для всех операций с поддержкой CORS и аутентификации через X-Session-ID. Доступны endpoints: CRUD (/api/db/{db}/{collection}), управление индексами (/api/index/), ACL (/api/acl/), ограничениями (/api/constraint/) и кластером (/api/cluster/).
```sh
# Аутентификация
curl -X POST http://localhost:8080/api/auth/login \
**Триггер**— это действие в базе данных, автоматически запускаемое при добавлении, изменении или удалении записи. Чаще всего триггеры нужны для математических вычислений, а также проведения аудита (для автоматической записи в лог или базу данных действий, которые необходимо отслеживать в рамках проведения аудита.) <br>
В субд `futriix` реализация триггеров выполнена в стиле MongoDB с событиями BEFORE/AFTER INSERT/UPDATE/DELETE/REPLACE. Поддерживаются условия (eq, gt, regex, in, exists) и действия (abort, modify, skip, log, notify) с возможностью модификации документа.
Сжатие данных в СУБД futriix предназначено для уменьшения объёма хранимых документов в оперативной памяти и на диске, что позволяет эффективнее использовать доступные ресурсы при работе с большими объёмами информации.
Алгоритм Brotli, разработанный компанией Google, обеспечивает сжатие с коэффициентом, на 20–26% лучшим по сравнению с классическим Gzip при сопоставимой скорости распаковки, что делает его оптимальным выбором для систем с интенсивными операциями чтения.
Основные преимущества Brotli включают: использование предопределённого словаря часто встречающихся последовательностей байт, адаптивное кодирование с переменной длиной кода, поддержку 11 уровней сжатия (от быстрого до максимально плотного) и высокую скорость распаковки, критически важную для быстрого доступа к документам. В futriix сжатие применяется автоматически при превышении порогового размера документа (настраивается через compression.MinSize), при этом каждый документ хранит флаг Compressed и оригинальный размер для последующего контроля эффективности.
```sh
# Просмотр конфигурации сжатия
futriix:~> compression config
=== Compression Configuration ===
Enabled: true
Algorithm: snappy
Level: 3
Min Size: 1 KB
Available Algorithms:
snappy - Fast compression/decompression, good balance (default)
lz4 - Extremely fast, lower compression ratio
zstd - High compression ratio, slower
# Просмотр статистики сжатия
futriix:~> compression stats
=== Compression Statistics ===
Total Documents: 1250
Compressed Documents: 890
Compression Rate: 71.20%
Size Reduction: 45.30%
Original Size: 15.2 MB
Compressed Size: 8.3 MB
Algorithm: snappy
Compression Level: 3
Min Size Threshold: 1 KB
# Ручное сжатие коллекции
futriix:~> compress collection employees
Compressing collection 'employees'...
✓ Compressed 45 documents in collection 'employees'
В субд futriix для упрощения администрирования реализован **WUI (Web User Inerface) Веб-интерфейс**, с помощью которого через веб-браузер можно управлять субд, быстро просто и удобно. На фото ниже, приведён пример загруженного веб-интерфейса субд по умолчанию.
- [x] Реализовать поддержку триггеров (обратных вызовов)
- [x] Реализовать поддержку многопоточности
- [x] Реализовать неблокирующие чтение/запись
- [x] Реализовать неблокирующие транзакции
- [x] Реализовать constraints (Ограничения)
- [x] Реализовать мульти-мастер асинхронную репликацию через файл конфигурации
- [x] Реализовать логирование для субд
- [x] Реализовать поддержку синхронной мастер-мастер репликации
- [x] Реализовать базовую поддержку протокола Raft
- [x] Реализовать поддержку индексов (первичные индексы, вторичные индексы)
- [x] Реализовать поддержку протокола MessagePack
- [x] Написать базовые тесты (интеграционный, функциональный, регрессионный, нагрузочный, smoke-тест для ядра субд "futriix")
- [x] Добавить механизм плагинов на языке lua, загружаемых в субд при её запуске, расширяющих её базовый функционал, не изменяя исходный код субд
- [x] Реализовать поддержку HTTP-restfull API
- [x] Реализовать сжатия данных в субд на основании протокола "Brotli"
- [x] Реализовать импорт и экспорт дампа субд в формате "MessagePack"
- [x] Исправить ошибки записи журнала логов (в журнал лога кроме текущего времени добавить текущий год)
- [x] Реализовать веб-интерфейс (WUI),на основе самописного движка "futriis", с помощью которого пользователь сможет управлять субд через веб-браузер
- [x]В веб-интерфейсе, слева от надписи "admin" в левой нижней части экрана, реализовать возможность добавлять фото (маленького размера)
- [x]В веб-интерфейсе удалить "вшитые в исходный код" логин и пароль (admin; admin)
- [x]В веб-интерфейсе, реализовать возможность смены логина и пароля для авторизации в нём, при этом логин и пароль (по умолчанию admin; admin) храни в скрытом файле ".credentials", расположенном в каталоге "futriix"
- [x]В веб-интерфейс добавить возможность читать файл логов "futriix.log", в котором отображаются все операции, выполненные в веб-интерфейсе за сеанс (например, создана база данных, или удалена коллекция), включая те операции, которые не были выполнены в виду какой-либо ошибки
- [x]В веб-интерфейсе, добавить возможность добавления нового пользователя администратора, данные которого (логин и пароль) будут хранится в скрытом файле ".credentionals", расположенном в каталоге "futriix".
- [x]В веб-интерфейсе, добавить возможность управлять плагинами (включать, отключать)
- [x] Скрипты сборки "build.sh" и "vendor_build.sh" переписаны таким образом, чтобы проект не зависел от компилятора "gcc", т.е. напиши реализацию так чтобы его не нужно было устанавливать отдельно в операционной системе "OpenIndiana Hipster"
- [x] Библиотека "raft-boltdb" заменить на встроенное файловое хранилище
- [x] Реализовать уникальные и составные индексы
- [x] Реализовать временные метки для основных объектов субд (таппл, коллекция, документ, поле, индекс, транзакция, ACL, узел кластера)
- [x] Оптимизировать транзакции под высокие нагрузки (Реализовать: Пакетную запись WAL - вместо синхронной записи каждой операции, используется асинхронная запись пакетами по 100 записей, Буферизацию записей - 64KB буфер для WAL записей, Периодическую синхронизацию - синхронизация с диском каждые 5 секунд вместо каждой записи, Чекпоинты - периодическое создание контрольных точек состояния, Атомарные операции - использование atomic.Value и sync.Map для wait-free доступа)
- [x] Реализовать MVCC версионирование - поддержка множественных версий документов
- [x] Реализовать временные метки для объектов субд (Ограничений, Импорта-Экспорта, Триггеров, Lua-плагинов)
- [x] Голосование узлов перед коммитом в протоколе Raft
- [ ] Реализовать скрипт установки Golang в операционных системах на базе Illumos
- [ ] Реализовать Multi-Raft (Несколько независимых Raft групп для разных шардов)
- [ ] Реализовать (Linearizable чтения) чтения через лидера с кворумом для строгой консистентности в кластере
- [ ] Реализовать Learner узлы узлы для репликации без права голоса (для бэкапов)
- [ ] Реализовать Raft as a Service (Raft как сервис, т.е.отдельный процесс Raft для управления шардами (Raft-as-a-Service))
- [ ] Реализовать автоматический шардинг с консистентным хэшированием
- [ ] Реализовать полноценную поддержку алгоритма Raft (с автоматическим перевывыбором лидера, с доменом отказа)
- [ ] Реализовать геораспределённую кластеризацию (Региональные зоны Поддержка нескольких availability zones с приоритетом выбора,Чтение из ближайшей реплики Маршрутизация запросов к географически ближайшему узлу,Асинхронная межрегиональная репликация Снижение задержек для глобальных кластеров)
- [ ] Реализовать Read-only лидер (Оптимизация запросов на чтение через локальные индексы)
- [ ] Реализовать Snapshot streaming (Передача снапшотов через отдельный канал без блокировки)
- [ ] Интеграцию с мониторинговыми системами (Prometheus, Grafana)
- [ ] Реализовать полноценную систему бекапирования с возможностью определения корректности созданного бекапа и кроссдацентровых решений по автоматическому копироваю бекапа в другой дацентр
- [ ] Реализовать полноценную систему авторизации на основе RBAC-модели
- [ ] Реализовать коннекторы к современным языкам программирования (C, C++, Java, Python, Go)
- [ ] Реализовать утилиту тестирования сервера на количество запросов на чтение/запись
См. [Открытые проблемы](https://source.futriix.ru/gvsafronov/futriixw/issues) полный список предлагаемых функций (и известных проблем).