futriix-Легковесная, распределённая использующая алгоритмы неблокирующей синхронизации (wait-free и lock-free) in-memory СУБД,
реализованная на Go с поддержкой плагинов на lua для операционных систем на базе ядра Illumos (Solaris-подобных)
Краткая документация проекта futriix
- О проекте
- Лицензия
- Глоссарий
- Архитектурные примечания
- Системные требования
- Подготовка и компиляция
- Логирование
- Тестирование
- CRUD операции
- Индексы
- Транзакции
- Кластеризация и шардинг
- Ограничения
- Импорт-Экспорт
- Lua-плагины
- Контроль доступа
- HTTP API
- Триггеры
- Сжатие данных
- Графический интерфейс
- Дорожная карта
- Контакты
О проекте
Caution
ALPHA VERSION
Категорически не использовать в продакшене, так как это экспериментальная версия!!!
futriix - это легковесная, распределённая, использующая алгоритмы неблокирующей синхронизации - wait-free и lock-free in-memory СУБД, реализованная на языке Go с поддержкой плагинов на языке lua использующая алгоритм консенсуса Raft.
Данная субд была разработана, в первую очередь для эксплуатации в операционных системах на базе ядра Illumos и операционной системы Solaris: OpenIndiana Hipster, Oracle Solaris в замкнутых программных средах.
Но также она совместима с популярными Linux-дистрибутивами (Debian,Ubuntu,Fedora), т.е. операционными системами построенными на базе ядра Linux.
(К началу)
Лицензия
Проект распространяется под лицензией CDDL 1.0. Подробнсти в файлах LICENSE.
Эта лицензия позволяет вам производить копирование, модификацию, распространение, включение в другие проекты, получение патентных прав, распространение бинарных файлов с доступом к их исходному коду. Она запрещает вам добавление новых ограничений, скрытие изменений, удаление оригинальных уведомлений, несоблюдение условий CDDL 1.0 при перераспределении, неправильное связывание с другими лицензиями.
Все дополнительное программное обеспечение (включая скрипт компиляции проекта build.sh) предоставляются "как есть", без гарантий и обязательств со стороны разработчиков. Разработчики не несут ответственности за прямой или косвенный ущерб, вызванный использованием открытого кода Futriix и futriix или технических решений, использующих этот код.
(К началу)
Глоссарий
- База Данных(БД) - это структурированное, организованное хранилище данных, которое позволяет удобно собирать, хранить, управлять и извлекать информацию.
- Система Управления Базами Данных(СУБД) - это программное обеспечение, которое позволяет создавать, управлять и взаимодействовать с базами данных
- Таппл (Tapple) - аналог базы данных в РСУБД
- Слайс (Slice) - аналог таблицы
- Кортеж (Tuple) - аналог записи в таблице
- Мультимодельная СУБД - это СУБД, которая объединяет в себе поддержку нескольких моделей данных (реляционной, документной, графовой, ключ-значение и др.) в рамках единого интегрированного ядра.
- Резидентная СУБД - это СУБД, которая работает непрерывно в оперативной памяти (RAM).
- Инстанс - это запущенный экземляр базы данных.
- Узел (хост,нода,шард) - это отдельный сервер (физический или виртуальный), который является частью кластера или распределенной системы и выполняет часть общей работы.
- Слайс (от англ. "slice"-слой) - это логический и физически изолированный фрагмент коллекции документов, полученный в результате горизонтального партиционирования (шардирования) и размещенный на определенном узле кластера с целью масштабирования производительности и объема данных.
- Репликасет - это группа серверов СУБД, объединенных в отказоустойчивую конфигурацию, где один узел выполняет роль первичного (принимающего операции записи), а один или несколько других - роль вторичных (синхронизирующих свои данные с первичным и обслуживающих чтение), с автоматическим переизбранием первичного узла в случае его сбоя.
- Временные ряды (time series) - это это упорядоченная во времени последовательность данных, собранная в регулярные промежутки времени из какого-либо источниика (цены на акции, данные температуры, объёмы продаж и.т.д.).
- OLTP (Online Transactional Processing-Онлайн обработка транзакций)- это технология обработки транзакций в режиме реального времени. Её основная задача заключается в обеспечении быстрого и надёжного выполнения операций, которые происходят ежесекундно в бизнесе. Они обеспечивают быстрое выполнение операций вставки, обновления и удаления данных, поддерживая целостность и надежность транзакций.
- OLAP (Online Analytical Processing - Оперативная аналитическая обработка) — это технология, которая работает с историческими массивами информации, извлекая из них закономерности и производя анализ больших объемов данных, поддерживает многоразмерные запросы и сложные аналитические операции. Данная технология оптимизирована для выполнения сложных запросов и предоставления сводной информации для принятия управленческих решений.
- HTAP (Hybrid Transactional and Analytical Processing - Гибридная транзакционно-аналитическая обработка)- это технология, которая заключаются в эффективном совмещении операционных и аналитических запросов, т.е. классов OLTP и OLAP.
- Кластер - это группа компьютеров, объединённых высокоскоростными каналами связи для решения сложных вычислительных задач и представляющая с точки зрения пользователя группу серверов, объединенных для работы как единая система.
- WUI (от англ. Web-User-Interface "веб интерфейс пользователя") - это термин проекта futriix, означающий веб-интерфейс (интерфейс работающий в веб-браузере)
- workflow (англ. workflow — «поток работы») — это принцип организации рабочих процессов, в соответствии с которым повторяющиеся задачи представлены как последовательность стандартных шагов.
- wait-free (дословно с англ. wait-free — «свободный от ожидания»)-класс неблокирующих алгоритмов, в которых каждая операция должна завершаться за конечное число шагов независимо от активности других потоков.
- Lock‑free алгоритмы — это алгоритмы, гарантирующие, что хотя бы один из потоков выполнения продвигается вперёд (завершает операцию) за конечное число шагов, даже если другие потоки задержаны или прерваны. При этом отдельные потоки могут испытывать задержки, но система в целом продолжает прогрессировать.
- Wait‑free алгоритмы — это алгоритмы, гарантирующие, что каждый поток завершит свою операцию за заранее ограниченное (конечное) число шагов, независимо от состояния и поведения остальных потоков. Это обеспечивает отсутствие задержек и голода для любого из участников параллельного выполнения.
- ЗПС (Замкнутая Программная Среда) - Это локальная сеть предприятия или организации как правило без доступа к сети "Интернет", своего рода "фильтр" содержащий в себе перечень программного обеспечения (ПО), которому разрешено работать на компьютере, в то время как ПО, которого нет в этом списке, будет запрещено к исполнению.
- Команды, выполняемые с привилегиями суперпользователя (root), отмечены символом приглашения «#»
- Команды, выполняемые с правами обычного пользователя(user), отмечены символом приглашения «$»
(К началу)
Архитектурные примечания
Important
Архитектурные примечания
Futriix изначально разрабатывался как монолит, внутреннее ядро которого, включающее фрейморк, для реализации WUI носило кодовое имя «Futriis». С переходом к финальному названию «Futriix»- внешние интерфейсы были переименованы, но внутренние переменные сохранили исходное имя в целях минимизации изменений. А также фрейморк, для реализации WUI сохранил своё прежнее название "Futriis" и был интегрирован в ядро субд. Считайте
futriisвнутренним псевдонимомfutriixИ помните, что в настоящий момент «Futriis — это историческое название ядра Futriix»
(К началу)
Системные требования
Caution
Важно: Операционные системы семейства Windows и MacOS X не поддерживаются!
Warning
- Процессор: Intel или AMD
- Оперативная память: 4ГБ (Для Linux) 8ГБ (Для Illumos sytems)
- Операционная система: только Unix-подобная ОС (Solaris, OpenIndiana, Linux)
- Утилиты: curl или wget, zip и unzip
- Язык программирования (для разработчиков): Go 1.25.6 или выше
(К началу)
Подготовка и компиляция
- Клонируйте репозиторий:
$ git clone https://github.com/futriix/futriix
$ cd futriix
Important
Важно: Шаги с 1.1 по 1.3(включительно) необходимы тогда и только тогда, когда вы используете ЗПС Данный шаг позволит скачать вам все зависимости в архиве "vendor.zip"
1.1 Скачайте локальные зависимости в архиве "vendor.zip"
$ wget https://futriix.ru:8083/fm/?r=/download&path=L3dlYi9mdXRyaWl4LnJ1L3B1YmxpY19odG1sL2Rvd25sb2Fkcy92ZW5kb3Iuemlw
1.2 Поместите архив vendor.zip в один каталог с проектом и распакуйте его командой:
$ unzip vendor.zip
1.3 Скомпилируйте проект с помощью специального скрипта для ЗПС build_vendor.sh
$ ./build_vendor.sh
- Скомпилируйте и запустите:
# Стандартная сборка для ОС на базе Linux
$ ./build.sh
# Сборка для операционных систем на базе Illumos
$ cd scripts/
$ ./build_illumos.sh
# Показать справку
$./build.sh --help
$ ./futriix
(К началу)
Логирование
В субд "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
- Перед запуском тестов убедитесь, что СУБД запущена и HTTP API доступен на порту 8080
- Load test может занять несколько минут при больших объёмах данных
# Установка зависимостей для 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
echo "=== Running $test ==="
lua "$test"
echo ""
done
(К началу)
Примеры команд субд
# Создание новой базы данных
futriix:~> create database company
✓ Database 'company' created
futriix:~> create database shop
✓ Database 'shop' created
# Переключение на базу данных
futriix:~> use company
✓ Switched to database 'company'
futriix:~> use shop
✓ Switched to database 'shop'
# Просмотр всех баз данных
futriix:~> show databases
Databases:
company
* shop
test
# Удаление базы данных
futriix:~> drop database test
✓ Database 'test' dropped
(К началу)
CRUD операции
Tip
Совместимость с MongoDB СУБД futriiX полностью совместима по синтаксису запросов с NOSQL-субд MongoDB. Вы можете использовать знакомые NoSQL-конструкции и драйверы, легко мигрируя с существующей инфраструктуры.
В субд futriix поддерживаются MongoDB-подобный синтаксис для команд, являющийся основными в любой субд из класса CRUD (Create,Read, Update, Delete- Создание, Чтение, Обновление, Удаление) работы с документами: db.collection.insert(), find(), update(), delete(). Операции выполняются wait-free с использованием атомарных sync.Map, поддерживают автоматическую генерацию _id и валидацию схемы.
# Создание новой базы данных
futriix:~> create database company
✓ Database 'company' created
futriix:~> create database shop
✓ Database 'shop' created
# Переключение на базу данных
futriix:~> use company
✓ Switched to database 'company'
futriix:~> use shop
✓ Switched to database 'shop'
# Просмотр всех баз данных
futriix:~> show databases
Databases:
company
* shop
test
# Удаление базы данных
futriix:~> drop database test
✓ Database 'test' dropped
# Создание коллекции
futriix:~> use company
✓ Switched to database 'company'
futriix:~> create collection employees
✓ Collection 'employees' created in database 'company'
futriix:~> create collection departments
✓ Collection 'departments' created in database 'company'
futriix:~> create collection projects
✓ Collection 'projects' created in database 'company'
# Просмотр всех коллекций
futriix:~> show collections
Collections in database 'company':
- employees
- departments
- projects
# Удаление коллекции
futriix:~> drop collection projects
✓ Collection 'projects' dropped from database 'company'
# Вставка документа (простой формат key=value)
futriix:~> insert employees name=John Doe,position=Developer,age=30,department=IT
✓ Document inserted with ID: 550e8400-e29b-41d4-a716-446655440000
futriix:~> insert employees name=Jane Smith,position=Manager,age=35,department=HR
✓ Document inserted with ID: 550e8400-e29b-41d4-a716-446655440001
futriix:~> insert employees name=Bob Johnson,position=Designer,age=28,department=Design
✓ Document inserted with ID: 550e8400-e29b-41d4-a716-446655440002
# Поиск документа по ID
futriix:~> find employees 550e8400-e29b-41d4-a716-446655440000
Document found:
{
"name": "John Doe",
"position": "Developer",
"age": 30,
"department": "IT"
}
# Поиск по индексу
futriix:~> findbyindex employees name_idx "John Doe"
Found 1 document(s):
[1] ID: 550e8400-e29b-41d4-a716-446655440000
{
"name": "John Doe",
"position": "Developer",
"age": 30,
"department": "IT"
}
# Обновление документа
futriix:~> update employees 550e8400-e29b-41d4-a716-446655440000 age=31,position=Senior Developer
✓ Document '550e8400-e29b-41d4-a716-446655440000' updated
# Подсчёт количества документов
futriix:~> count employees
Collection 'employees' has 3 document(s)
# Удаление документа
futriix:~> delete employees 550e8400-e29b-41d4-a716-446655440002
✓ Document '550e8400-e29b-41d4-a716-446655440002' deleted
futriix:~> count employees
Collection 'employees' has 2 document(s)
(К началу)
Индексы
Futriix поддерживает первичные (по _id) и вторичные индексы, хранящиеся отдельно от документов. Также в нём присутствуют уникальные и составные индексы, поиск по точному значению и префиксу, а кроме того автоматическое обновление индексов при изменениях документов.
# Создание обычного индекса
futriix:~> create index employees name_idx name
✓ Index 'name_idx' created on collection 'employees'
# Создание уникального индекса
futriix:~> create index employees email_idx email unique
✓ Index 'email_idx' created on collection 'employees'
# Создание составного индекса
futriix:~> create index employees dept_age_idx department,age
✓ Index 'dept_age_idx' created on collection 'employees'
# Просмотр всех индексов
futriix:~> show indexes employees
Indexes on collection 'employees':
- _id_
- name_idx
- email_idx
- dept_age_idx
# Удаление индекса
futriix:~> drop index employees dept_age_idx
✓ Index 'dept_age_idx' dropped from collection 'employees'
(К началу)
Транзакции
В субд futriix для обеспечения надёжности (durability) и быстрого восстановления бд из резевной копии, реализована полноценная поддержка WAL (Write-Ahead Logging). Журнал WAL по умолчанию хранится в файле futriix.wal, находящимся в каталоге futriix, а также поддержка ACID-транзакций с MVCC (Multi-Version Concurrency Control). Доступны команды startSession(), startTransaction(), commitTransaction(), abortTransaction() с восстановлением после сбоев через журнал предзаписи.
Tip
WAL- это журнал предзаписи транзакций, который в субд futriix выполняет следующие действия:
- Хранит все операции транзакций до их фиксации (INSERT, UPDATE, DELETE)
- Записывает каждое изменение последовательно с LSN (Log Sequence Number)
- Используется для восстановления после сбоя через recoverFromWAL()
- Формат: бинарный с CRC-контролем, размером записи и типом (Transaction/Checkpoint)
- Расположение: /futriix/futriix.wal (один файл)
Tip
Кроме того существуют так называемые Периодические снимки состояния журнала предзаписи, которые выполняют следующие функции:
- Фиксируют состояние всех активных транзакций на момент создания
- Создаются автоматически каждые 5 минут (300 секунд)
- Именуются по маске: futriis.wal.checkpoint.{timestamp}
- Хранят сжатое состояние: последний LSN + активные транзакции
- Автоматически очищаются: остаётся только 5 последних чекпоинтов
- Расположение: /futriix/wal.checkpoint.wal (несколько файлов файл) Подводя итог, хочется отметить следующее: журнал предзаписи транзакций и периодические снимки состояния работают следующим образом:
- Штатная работа: WAL пишет каждую транзакцию
- Периодически: создаётся checkpoint (снимок активных транзакций)
- При сбое: восстанавливаемся с последнего checkpoint + доигрываем операции из WAL
# Начало сессии
futriix:~> db.startSession()
✓ Session started: session_12345
# Начало транзакции в рамках сессии
futriix:~> session.startTransaction()
✓ Transaction started: TX_67890
# Выполнение операций в транзакции
futriix:~> insert employees name=New User,position=Trainee,age=22
✓ Document inserted with ID: 550e8400-e29b-41d4-a716-446655440005
futriix:~> update employees 550e8400-e29b-41d4-a716-446655440005 status=active
✓ Document '550e8400-e29b-41d4-a716-446655440005' updated
# Подтверждение транзакции
futriix:~> session.commitTransaction()
✓ Transaction committed successfully
# Откат транзакции (при ошибке)
futriix:~> session.startTransaction()
✓ Transaction started: TX_67891
futriix:~> insert employees name=Test User,position=Test,age=25
✓ Document inserted with ID: 550e8400-e29b-41d4-a716-446655440006
futriix:~> session.abortTransaction()
✓ Transaction aborted, changes rolled back
(К началу)
Кластеризация и шардинг
Субд futriix является распределённой субд. Распределённый кластер реализован на основе Raft-консенсуса с автоматическими выборами лидера. Поддерживаются одноузловой и многокластерный режимы, репликация данных (синхронная/асинхронная), мастер-мастер репликация и health-мониторинг узлов.
# Просмотр статуса кластера
futriix:~> status
=== Cluster Status ===
✓ Role: LEADER
Cluster Name: production
Node: 192.168.1.100:8080
Raft Port: 7000
# В режиме follower
futriix:~> status
=== Cluster Status ===
⚠ Role: FOLLOWER
Cluster Name: production
Node: 192.168.1.101:8080
Raft Port: 7000
# Просмотр всех узлов кластера
futriix:~> nodes
=== Cluster Nodes ===
* 192.168.1.100:8080
192.168.1.101:8080
192.168.1.102:8080
(К началу)
Ограничения
В субд futriix также как и в традиционных субд, есть механизм Ограничений (Constraints). Ограничения на уровне коллекции поддерживаются: обязательные поля (required), уникальность (unique), минимальные/максимальные значения (min/max), regex-паттерны и enum-списки допустимых значений. Все ограничения проверяются автоматически при вставке и обновлении документов.
# Добавление обязательного поля
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)
# Добавление enum-ограничения (допустимые значения)
futriix:~> add enum employees status active,inactive,on_leave
✓ Enum constraint added for field 'status' on collection 'employees' (allowed: [active inactive on_leave])
(К началу)
Импорт-Экспорт
Для создания бекапов, в субд существуют команды export и import, позволяющие выгружать/загружать целые базы данных в формате MessagePack. Экспорт сохраняет документы с метаданными (версии, временные метки), импорт поддерживает пропуск существующих документов и детальную статистику.
# Экспорт базы данных в файл MessagePack
futriix:~> export "company" "company_backup.msgpack"
✓ Database 'company' exported to company_backup.msgpack
# Экспорт с автоматическим добавлением расширения
futriix:~> export "shop" "shop_backup"
✓ Database 'shop' exported to shop_backup.msgpack
# Импорт базы данных из файла
futriix:~> import "company" "company_backup.msgpack"
Importing data from company_backup.msgpack to database 'company'...
✓ Database 'company' imported successfully from company_backup.msgpack
Collections imported: 2
Documents imported: 150
Documents skipped (already exist): 0
Documents failed: 0
# Импорт в новую базу данных
futriix:~> import "company_restore" "company_backup.msgpack"
Created database 'company_restore'
✓ Database 'company_restore' imported successfully from company_backup.msgpack
Collections imported: 2
Documents imported: 150
(К началу)
Lua-плагины
Для расширения функциональных возможностей субд без изменения её исходного кода, в futriix была реализована система расширения функциональности через Lua-скрипты с изолированным окружением. Плагины имеют доступ к БД, транзакциям, триггерам, могут логировать события и взаимодействовать через событийную шину, а также они доступны в веб-интерфейсе.
# Просмотр информации о системе плагинов
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
Status: RUNNING
# Загрузка плагина из файла
futriix:~> plugin load email_notifier ./plugins/email_notifier.lua
✓ Plugin 'email_notifier' loaded successfully
Version: 1.0.0
Author: admin
Description: Send email notifications on database events
# Запуск/остановка плагина
futriix:~> plugin start email_notifier
✓ Plugin 'email_notifier' started
futriix:~> plugin stop email_notifier
✓ Plugin 'email_notifier' stopped
# Выгрузка плагина
futriix:~> plugin unload email_notifier
✓ Plugin 'email_notifier' unloaded
Пример плагина валидации документов
**В директорию plugins добавляем файл validation.lua, следдующего содержания:
-- Метаданные плагина
version = "1.0.0"
author = "admin"
description = "Document validation rules for employees collection"
-- Функция инициализации
function on_load()
plugin_log("info", "Validation plugin loaded")
return true
end
-- Функция запуска
function on_start()
plugin_log("info", "Validation plugin started")
return true
end
-- Функция остановки
function on_stop()
plugin_log("info", "Validation plugin stopped")
return true
end
-- Функция выгрузки
function on_unload()
plugin_log("info", "Validation plugin unloaded")
return true
end
-- Обработчик событий
function on_event(event)
plugin_log("debug", "Received event: " .. event.type)
if event.type == "BEFORE_INSERT" then
return validate_document(event.data)
end
return true
end
-- Функция валидации документа
function validate_document(doc)
-- Проверка обязательных полей
if doc.name == nil or doc.name == "" then
plugin_log("error", "Document missing required field: name")
return false, "Field 'name' is required"
end
-- Проверка возраста
if doc.age ~= nil then
if doc.age < 18 then
plugin_log("warn", "Age validation failed: " .. doc.age)
return false, "Employee must be at least 18 years old"
end
if doc.age > 65 then
plugin_log("warn", "Age validation failed: " .. doc.age)
return false, "Employee cannot be older than 65 years"
end
end
-- Проверка email
if doc.email ~= nil then
if string.match(doc.email, "^[%w._-]+@[%w._-]+%.[%w]+$") == nil then
plugin_log("error", "Invalid email format: " .. doc.email)
return false, "Invalid email format"
end
end
-- Проверка зарплаты
if doc.salary ~= nil then
if doc.salary < 30000 then
plugin_log("warn", "Salary below minimum: " .. doc.salary)
return false, "Salary must be at least 30000"
end
end
plugin_log("info", "Document validation passed for: " .. doc.name)
return true
end
-- Пользовательская функция для массовой валидации
function validate_collection(collection_name)
local coll = get_collection("company", collection_name)
if coll == nil then
plugin_log("error", "Collection not found: " .. collection_name)
return 0
end
-- Здесь можно реализовать массовую валидацию
plugin_log("info", "Validating collection: " .. collection_name)
return 0
end
ИСпользование плагина валидации документов
# Создание базы данных и коллекции
futriix:~> create database company
✓ Database 'company' created
futriix:~> use company
✓ Switched to database 'company'
futriix:~> create collection employees
✓ Collection 'employees' created in database 'company'
# Загрузка и запуск плагина валидации
futriix:~> plugin load validation ./plugins/validation.lua
✓ Plugin 'validation' loaded successfully
Version: 1.0.0
Author: admin
Description: Document validation rules for employees collection
futriix:~> plugin start validation
✓ Plugin 'validation' started
# Вставка валидного документа
futriix:~> insert employees name=John Doe,age=25,email=john@company.com,salary=45000
✓ Document inserted with ID: emp_001
# Вставка невалидного документа (возраст < 18)
futriix:~> insert employees name=Jane Smith,age=16,email=jane@company.com,salary=20000
Error: Employee must be at least 18 years old
# Вставка невалидного документа (некорректный email)
futriix:~> insert employees name=Bob Johnson,age=30,email=invalid-email,salary=50000
Error: Invalid email format
# Выполнение пользовательской функции плагина
futriix:~> plugin call validation validate_collection employees
✓ Function returned: 0
Управление плагинами через HTTP API
# Получение списка плагинов через API
curl -X GET "http://localhost:8080/api/plugin/list" \
-H "X-Session-ID: abc123"
# Загрузка плагина через API
curl -X POST http://localhost:8080/api/plugin/load \
-H "Content-Type: application/json" \
-H "X-Session-ID: abc123" \
-d '{"name":"validation","path":"./plugins/validation.lua"}'
# Запуск плагина через API
curl -X POST "http://localhost:8080/api/plugin/start/validation" \
-H "X-Session-ID: abc123"
# Выполнение функции плагина через API
curl -X POST http://localhost:8080/api/plugin/call \
-H "Content-Type: application/json" \
-H "X-Session-ID: abc123" \
-d '{"plugin":"validation","function":"validate_collection","args":["employees"]}'
(К началу)
Контроль доступа
В futriix реализована многоуровневая система контроля доступа, основанная на ACL (Access Contol Lists -Списки контроля доступа) с аутентификацией по сессиям. В ней поддерживаются следующие роли (read, write, delete, admin) с гранулярным контролем на уровне базы данных и коллекции.
# Вход в систему
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'
# Пример использования разных прав:
# r - read (чтение)
# w - write (запись)
# d - delete (удаление)
# a - admin (администратор)
(К началу)
HTTP API
В субд futriix для взаимодействия субд с веб-прилоджениями по сети, реализован интерфейс RESTful API для всех операций с поддержкой CORS и аутентификации через X-Session-ID. Доступны endpoints: CRUD (/api/db/{db}/{collection}), управление индексами (/api/index/), ACL (/api/acl/), ограничениями (/api/constraint/) и кластером (/api/cluster/).
# Аутентификация
curl -X POST http://localhost:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin"}'
# Response: {"success":true,"data":{"session_id":"abc123"}}
# Вставка документа
curl -X POST http://localhost:8080/api/db/company/employees \
-H "Content-Type: application/json" \
-H "X-Session-ID: abc123" \
-d '{"name":"API User","position":"Integrator","age":28}'
# Response: {"success":true,"data":{"status":"inserted"}}
# Получение документа по ID
curl -X GET "http://localhost:8080/api/db/company/employees/550e8400-e29b-41d4-a716-446655440000" \
-H "X-Session-ID: abc123"
# Response: {"success":true,"data":{"_id":"550e8400-...","fields":{...}}}
# Получение всех документов с пагинацией
curl -X GET "http://localhost:8080/api/db/company/employees?limit=10&offset=0" \
-H "X-Session-ID: abc123"
# Поиск по индексу
curl -X GET "http://localhost:8080/api/db/company/employees?index=name_idx&value=John%20Doe" \
-H "X-Session-ID: abc123"
# Обновление документа
curl -X PUT http://localhost:8080/api/db/company/employees/550e8400-e29b-41d4-a716-446655440000 \
-H "Content-Type: application/json" \
-H "X-Session-ID: abc123" \
-d '{"age":31,"position":"Senior Developer"}'
# Response: {"success":true,"data":{"status":"updated"}}
# Удаление документа
curl -X DELETE "http://localhost:8080/api/db/company/employees/550e8400-e29b-41d4-a716-446655440000" \
-H "X-Session-ID: abc123"
# Response: {"success":true,"data":{"status":"deleted"}}
# Создание индекса через API
curl -X POST http://localhost:8080/api/index/company/employees/create \
-H "Content-Type: application/json" \
-H "X-Session-ID: abc123" \
-d '{"name":"email_idx","fields":["email"],"unique":true}'
# Просмотр индексов
curl -X GET "http://localhost:8080/api/index/company/employees/list" \
-H "X-Session-ID: abc123"
# Статус кластера через API
curl -X GET "http://localhost:8080/api/cluster/status" \
-H "X-Session-ID: abc123"
# Создание пользователя через API
curl -X POST http://localhost:8080/api/acl/user/newuser \
-H "Content-Type: application/json" \
-H "X-Session-ID: abc123" \
-d '{"password":"secret","roles":["reader"]}'
# Назначение прав через API
curl -X POST "http://localhost:8080/api/acl/grant/reader/rw" \
-H "X-Session-ID: abc123"
# Создание триггера через API
curl -X POST http://localhost:8080/api/trigger/company/employees/create \
-H "Content-Type: application/json" \
-H "X-Session-ID: abc123" \
-d '{"name":"audit","event":"AFTER_INSERT","action":"log"}'
(К началу)
Триггеры
Триггер— это действие в базе данных, автоматически запускаемое при добавлении, изменении или удалении записи. Чаще всего триггеры нужны для математических вычислений, а также проведения аудита (для автоматической записи в лог или базу данных действий, которые необходимо отслеживать в рамках проведения аудита.)
В субд futriix реализация триггеров выполнена в стиле MongoDB с событиями BEFORE/AFTER INSERT/UPDATE/DELETE/REPLACE. Поддерживаются условия (eq, gt, regex, in, exists) и действия (abort, modify, skip, log, notify) с возможностью модификации документа.
# Создание триггера для логирования вставок
futriix:~> create trigger employees audit_log AFTER_INSERT log
✓ Trigger 'audit_log' created on collection 'employees' for event AFTER_INSERT
# Создание триггера с автоматической установкой timestamp
futriix:~> create trigger employees set_timestamp BEFORE_INSERT modify --set updated_at $$NOW
✓ Trigger 'set_timestamp' created on collection 'employees' for event BEFORE_INSERT
# Создание триггера с условием (запрет удаления активных пользователей)
futriix:~> create trigger employees protect_active BEFORE_DELETE abort --condition status eq active
✓ Trigger 'protect_active' created on collection 'employees' for event BEFORE_DELETE
# Создание триггера с обновлением аудита
futriix:~> create trigger employees audit BEFORE_UPDATE modify --set modified_by $$USER --set modified_at $$NOW
✓ Trigger 'audit' created on collection 'employees' for event BEFORE_UPDATE
# Просмотр всех триггеров коллекции
futriix:~> show triggers employees
=== Triggers on collection 'employees': ===
audit_log (AFTER_INSERT) - enabled [log]
Operations:
- log: =
set_timestamp (BEFORE_INSERT) - enabled [modify]
Operations:
- set: updated_at = $$NOW
protect_active (BEFORE_DELETE) - enabled [abort]
Condition: status eq active
audit (BEFORE_UPDATE) - enabled [modify]
Operations:
- set: modified_by = $$USER
- set: modified_at = $$NOW
# Включение/отключение триггера
futriix:~> disable trigger employees BEFORE_INSERT set_timestamp
✓ Trigger 'set_timestamp' disabled
futriix:~> enable trigger employees BEFORE_INSERT set_timestamp
✓ Trigger 'set_timestamp' enabled
# Просмотр лога выполнения триггеров
futriix:~> trigger log
=== Trigger Execution Log ===
[1] 2026-04-12 10:30:45 - Trigger: audit_log, Event: AFTER_INSERT, Collection: employees, Document: 550e8400-...
[2] 2026-04-12 10:31:20 - Trigger: protect_active, Event: BEFORE_DELETE, Collection: employees, Document: 550e8400-...
# Удаление триггера
futriix:~> drop trigger employees BEFORE_INSERT set_timestamp
✓ Trigger 'set_timestamp' dropped from collection 'employees'
(К началу)
Сжатие данных
Сжатие данных в СУБД futriix предназначено для уменьшения объёма хранимых документов в оперативной памяти и на диске, что позволяет эффективнее использовать доступные ресурсы при работе с большими объёмами информации.
Алгоритм Brotli, разработанный компанией Google, обеспечивает сжатие с коэффициентом, на 20–26% лучшим по сравнению с классическим Gzip при сопоставимой скорости распаковки, что делает его оптимальным выбором для систем с интенсивными операциями чтения.
Основные преимущества Brotli включают: использование предопределённого словаря часто встречающихся последовательностей байт, адаптивное кодирование с переменной длиной кода, поддержку 11 уровней сжатия (от быстрого до максимально плотного) и высокую скорость распаковки, критически важную для быстрого доступа к документам. В futriix сжатие применяется автоматически при превышении порогового размера документа (настраивается через compression.MinSize), при этом каждый документ хранит флаг Compressed и оригинальный размер для последующего контроля эффективности.
# Просмотр конфигурации сжатия
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:~> doc compression employees 550e8400-e29b-41d4-a716-446655440000
=== Compression Info for Document: 550e8400-e29b-41d4-a716-446655440000 ===
Compressed: true
Ratio: 35.20%
Original Size: 2.5 KB
Current Size: 1.6 KB
(К началу)
Графический интерфейс
В субд futriix для упрощения администрирования реализован WUI (Web User Inerface) Веб-интерфейс, с помощью которого через веб-браузер можно управлять субд, быстро просто и удобно. На фото ниже, приведён пример загруженного веб-интерфейса субд по умолчанию.
(К началу)
Дорожная карта
- Реализовать поддержку хранимых процедур
- Реализовать поддержку триггеров (обратных вызовов)
- Реализовать поддержку многопоточности
- Реализовать неблокирующие чтение/запись
- Реализовать неблокирующие транзакции
- Реализовать constraints (Ограничения)
- Реализовать мульти-мастер асинхронную репликацию через файл конфигурации
- Реализовать логирование для субд
- Реализовать поддержку синхронной мастер-мастер репликации
- Реализовать базовую поддержку протокола Raft
- Реализовать поддержку индексов (первичные индексы, вторичные индексы)
- Реализовать поддержку протокола MessagePack
- Написать базовые тесты (интеграционный, функциональный, регрессионный, нагрузочный, smoke-тест для ядра субд "futriix")
- Добавить механизм плагинов на языке lua, загружаемых в субд при её запуске, расширяющих её базовый функционал, не изменяя исходный код субд
- Реализовать поддержку HTTP-restfull API
- Реализовать сжатия данных в субд на основании протокола "Brotli"
- Реализовать импорт и экспорт дампа субд в формате "MessagePack"
- Исправить ошибки записи журнала логов (в журнал лога кроме текущего времени добавить текущий год)
- Реализовать веб-интерфейс (WUI),на основе самописного движка "futriis", с помощью которого пользователь сможет управлять субд через веб-браузер
- В веб-интерфейсе, слева от надписи "admin" в левой нижней части экрана, реализовать возможность добавлять фото (маленького размера)
- В веб-интерфейсе удалить "вшитые в исходный код" логин и пароль (admin; admin)
- В веб-интерфейсе, реализовать возможность смены логина и пароля для авторизации в нём, при этом логин и пароль (по умолчанию admin; admin) храни в скрытом файле ".credentials", расположенном в каталоге "futriix"
- В веб-интерфейс добавить возможность читать файл логов "futriix.log", в котором отображаются все операции, выполненные в веб-интерфейсе за сеанс (например, создана база данных, или удалена коллекция), включая те операции, которые не были выполнены в виду какой-либо ошибки
- В веб-интерфейсе, добавить возможность добавления нового пользователя администратора, данные которого (логин и пароль) будут хранится в скрытом файле ".credentionals", расположенном в каталоге "futriix".
- В веб-интерфейсе, добавить возможность управлять плагинами (включать, отключать)
- Скрипты сборки "build.sh" и "vendor_build.sh" переписаны таким образом, чтобы проект не зависел от компилятора "gcc", т.е. напиши реализацию так чтобы его не нужно было устанавливать отдельно в операционной системе "OpenIndiana Hipster"
- Библиотека "raft-boltdb" заменить на встроенное файловое хранилище
- Реализовать уникальные и составные индексы
- Реализовать полноценный графический веб-интерфейс для управления кластером
- Реализовать автоматический шардинг с консистентным хэшированием
- Реализовать полноценную поддержку алгоритма Raft (с автоматическим перевывыбором лидера, с доменом отказа)
- Реализовать полноценную поддержку кластеризации (с обработкой состояний "split-brain", автоматической ребалансировкой кластера)
- Интеграцию с мониторинговыми системами (Prometheus, Grafana)
- Реализовать полноценную систему бекапирования с возможностью определения корректности созданного бекапа и кроссдацентровых решений по автоматическому копироваю бекапа в другой дацентр
- Реализовать полноценную систему авторизации на основе RBAC-модели
- Реализовать коннекторы к современным языкам программирования (C, C++, Java, Python, Go)
- Реализовать утилиту тестирования сервера на количество запросов на чтение/запись
См. Открытые проблемы полный список предлагаемых функций (и известных проблем).
(К началу)
Контакты
Григорий Сафронов - E-mail
(К началу)
