diff --git a/Logo.jpg b/Logo.jpg new file mode 100644 index 0000000..8f5c02f Binary files /dev/null and b/Logo.jpg differ diff --git a/README.md b/README.md new file mode 100644 index 0000000..59d836c --- /dev/null +++ b/README.md @@ -0,0 +1,1774 @@ + + + + + + +
+
+ +Logo.jpg + + +

falcot && futriix

+ +

+ Futriix-встроенная распределённая субд в сервер-приложений (falcot) с поддержкой модулей на языке lua, написанная на языке Rust
+
+
+ +

+
+ + ## Краткая документация проекта Futriix + + +
+ + Содержание
+
    +
  1. + О проекте +
  2. Лицензия
  3. +
  4. Глоссарий
  5. +
  6. Подготовка
  7. +
  8. Компиляция
  9. +
  10. Тестирование
  11. +
  12. Примеры команд субд
  13. +
  14. Обработка статических страниц
  15. +
  16. HTTP API
  17. +
  18. Аутентификация
  19. +
  20. HTTPS
  21. +
  22. Репликация
  23. +
  24. Резервное копирование
  25. +
  26. ACL
  27. +
  28. Индексы
  29. +
  30. Constraints (Ограничения)
  31. +
  32. Хранимые процедуры
  33. +
  34. Триггеры
  35. +
  36. Транзакции
  37. +
  38. Шардинг
  39. +
  40. Lua-скрипты
  41. +
  42. Сферы применения
  43. +
  44. Дорожная карта
  45. +
  46. Контакты
  47. +
+ + + +## О проекте + +Falcot это http сервер-приложений со встроенной мультимодельной NOSQL субд без блокировок (которая называется **futriix**) , написанной на языке программирования Rust.
+Поддерживает следующие модели хранения данных: модель временных рядов (time series), документную, ключ-значение. +Для расширения базового функционала имеет встроенный lua-интепретатор.
+CУБД `futriix` является резидентной, **HTAP (Hybrid Transactional/Analytical Processing) с определёнными нюансами** субд, т.е. хранящей свои данные в оперативной памяти, с их периодическим сохранением на внутренний носитель: HDD (жёсткий диск) или SSD-накопитель. + +## Глоссарий + +* **База Данных(БД)** -массив информация, хранящийся, например, на флешке, в файле, на кластере +* **Система Управления Базами Данных(СУБД)** - Это программа для внесения изменений в базу данных и поиска по ней +* **Мультимодельная СУБД** - Это субд, поддерживающая одновременно несколько моделей хранения данных +* **Резидентная СУБД** - субд, хранящая все свои данные в оперативной памяти, с периодическим сохранением на HDD или SSD +* **Инстанс** - запущенный экземляр базы данных +* **Узел (хост,нода)** - физический сервер +* **Слайс (от англ. "slice"-слой)** - аналог документа в любой документно-ориентированной субд +* **Репликасет** - группа актуальных данных,хранящиеся на нескольких узлах +* **Временные ряды (time series)** - это данные, последовательно собранные в регулярные промежутки времени, полученные из какого-либо устройства (цены на акции, данные температуры, объёмы продаж и.т.д.) +* **OLTP (Online Transactional Processing-Онлайн оработка транзакций)**- технология обработки транзакций в режиме реального времени. Её основная задача заключается в обеспечении быстрого и надёжного выполнения операций, которые происходят ежесекундно в бизнесе.Они обеспечивают быстрое выполнение операций вставки, обновления и удаления данных, поддерживая целостность и надежность транзакций. +* **OLAP (Online Analytical Processing- Оперативная аналитическая обработка)** — это технология, которая работает с историческими массивами информации, извлекая из них закономерности и производя анализ больших объемов данных, поддерживает многоразмерные запросы и сложные аналитические операции. Данная технология оптимизирована для выполнения сложных запросов и предоставления сводной информации для принятия управленческих решений. +* **HTAP (Hybrid Transactional and Analytical Processing- Гибридная транзакционно-аналитическая обработка)**- это технология, которая заключаются в эффективном совмещении операционных и аналитических запросов, т.е. классов OLTP и OLAP. +* **Кластер** - группа компьютеров, объединённых высокоскоростными каналами связи и представляющая с точки зрения пользователя единый аппаратный ресурс +* Команды, выполняемые с привилегиями суперпользователя (root), отмечены символом приглашения **«#»** +* Команды, выполняемые с правами обычного пользователя(user), отмечены символом приглашения **«$»** +* **FutBot** - интеллектуальный помощник в мессенджере Телеграмм, помогающий осущесвлять быстрый поиск по документации проекта +* **Сервер-приложений (англ. application-server)**-это программное обеспечение, которое обеспечивает выполнение бизнес-логики и обработку запросов от клиентов (например, веб-браузеров или мобильных приложений). Он служит платформой для развертывания и управления приложениями, имея встроенные интепретаторы и/или компиляторы популярных языков программирования (php,go,python) обеспечивая взаимодействие между пользователями, базами данных и другими системами. +* **futriix** - сервер проекта futriix +* **Интерактивная оболочка (неофициальное название "clif")**- клиент для работы со встроенной субд +* **workflow ((англ. workflow — «поток работы»)** — принцип организации рабочих процессов, в соответствии с которым повторяющиеся задачи представлены как последовательность стандартных шагов.) +* **CA (англ. Certificate Authority)-Центры Сертификации, организации, выдающие доверенне криптографические сертификаты** +* **Резидентная субд**- Это субд, хранящая данные в оперативной памяти + +

(К началу)

+ +## +**Почему именно HTAP? Анализ характеристик falcot:** + +OLTP (Online Transactional Processing- Онлайн оработка транзакций) черты, присущие falcot: + +1. **Поддержка транзакций - есть BEGIN/COMMIT/ROLLBACK** +2. **CRUD операции - полноценные Create, Read, Update, Delete** +3. **Wait-free архитектура - оптимизирована для быстрых коротких операций** +4. **Поддержка индексов - ускоряет поиск и точки доступа** +5. **ACID-подобное поведение - на уровне отдельных операций** +
+
+ +OLAP (Online Analytical Processing- Оперативная аналитическая обработка) черты, присущие falcot: + + +1. **Документо-ориентированная модель - удобна для аналитических запросов** +2. **Поддержка сложных запросов - через Lua-скрипты** +3. **Мастер-мастер репликация - позволяет распределять аналитические нагрузки** +4. **Возможность агрегаций - через пользовательские процедуры** +
+
+ +HTAP (Hybrid Transactional Analytical Processing- Гибридная обработка транзакций) черты, присущие falcot: + + +1. **Единая платформа - обрабатывает и транзакции, и аналитику** +2. **Wait-free архитектура - подходит для mixed workload** +3. **Lua-скрипты - мост между операционными и аналитическими задачами** +4. **Реализация индексов - поддерживает оба типа нагрузок** + +
+
+ +Если посмотреть на архитектурные особенности falcot, то можно заметить следующее: + +1. **Wait-free доступ подходит для concurrent transactional workload** +2. **Document-oriented модель удобна для analytical queries** +3. **Master-master репликация позволяет разделять нагрузки** +4. **Функциональные возможности обоих классов OLTP и OLAP (См. пример ниже)** + +
+ +> [!CAUTION] +> **А поскольку falcot НЕ поддерживает:** +> * Полноценные распределённые транзакции +> * Сложные ограничения (constraints) +> * Хранилища типа "Семейство столбцов" (Columnar Storage) для аналитики +> * Сложные агрегации +> * Язык запросов SQL +> * ACID-транзакции + +
+
+ +> [!NOTE] +>**Falcot** - это lightweight HTAP система занимающая нишу прагматичного HTAP - достаточно мощная для большинства реальных задач, но без > избыточной сложности enterprise-решений, **с акцентом на:** + > * Простота использования через Lua-интерфейс + > * Гибридная модель для mixed workloads + > * Wait-free performance для concurrent access + > * Умеренную масштабируемость (достаточную для большинства задач) + +

(К началу)

+ + +## Лицензия + +Проект распространяется под 3-пунктной лицензией BSD. Подробнсти смотрите в файле `LICENSE.txt`. +Эта лицензия является одной из самых демократичных лицензий свободного программного обеспечения. Она позволяет использовать, изменять и распространять код в коммерческих целях без каких-либо ограничений, за исключением сохранения уведомления об авторских правах. + +В том числе, вы можете использовать falcot и futriix в своих коммерческих продуктах, приложениях или сервисах, не беспокоясь о каких-либо юридических ограничениях, связанных с лицензией. + +Все дополнительное программное обеспечение (включая модули на языке lua, утилиту тестирования) предоставляются "как есть", без гарантий и обязательств со стороны разработчиков. Разработчики не несут ответственности за прямой или косвенный ущерб, вызванный использованием открытого кода falcot и futriix или технических решений, использующих этот код. + +

(К началу)

+ + +## Подготовка + +**Для операционных систем семейства Debian** выполните следующие шаги: +* Устанавливаем язык программирования Rust + + ```sh + # apt update + # apt upgrade + # curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh + ``` + +**Для операционных систем семейства Red Hat (Fedora, Aurora)** выполните следующие шаги: +* Устанавливаем язык программирования Rust + + ```sh + # dnf update + # curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh + ``` + +**Для операционной системы Alpine** выполните следующие шаги: +* Устанавливаем язык программирования Rust + + ```sh + # apk update + # curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh + ``` + +
+
+ +> [!IMPORTANT] +> Для дальнейшей корректной работы приложения создаем файл `.cargo/config.toml` для подавления некоторых предупреждений, следующего содержания: + +
+
+ +```sh +#### .cargo/config.toml +[build] +rustflags = ["-A", "dead_code", "-A", "unused_variables", "-A", "unused_imports"] +``` + +

(К началу)

+ +## Компиляция + +1. Копируем репозиторий + ```sh + $ git clone https://source.futriix.ru/gvsafronov/falcot + ``` +2. Переходим в каталог с исходном кодом src + ```sh + $ cd falcot/ + ``` +3. Компилируем Futriix с помощью пакетного менеджера `Cargo` + ```sh + $ cargo build + ``` + > [!WARNING] +> **Futriix может быть скомпилирован для следующих операционных систем: `Linux`, `OSX`, `Open Indiana`, `FreeBSD`, но сборка для этих операционных систем не проводилась!!!** +
+4. Запускаем сервера futriix'а с помощью команды `./falcot` + + ```sh + $ ./falcot + ```` +Если проект был успешно скомпилирован, то при его запуске в терминале вы увидите, следующие сообщение: +
+ +```sh +Loading configuration from: config.toml +Database initialized with system collections + +Falcot Database Server +Version: 1.0.0 +Features: Wait-Free Architecture, Master-Master Replication, Lua Scripting, HTTP/HTTPS Support +HTTP server started on 127.0.0.1:8082 +Starting Lua interpreter... +Lua interpreter ready. Type 'inbox.start' to enter database mode. +Type 'exit' to quit. +lua> +``` +
+
+ + +5.**Компиляция и запуск тестов. Для запуска тестов запускаем команды:** + ```sh + $ cargo test --test integration # запуск только интеграционных тестов + $ cargo test --bench benches # запуск только бенчмарков + ``` + +**Компиляция и запуск тестов c помощью утилиты тестирования с выводом логов** + +```sh +cargo test --test integration_tests -- --nocapture +``` + +**Только компиляция утилиты тестирования без запуска** +Приведённая команда ниже только скомпилирует тесты, но не запускает их. + +```sh +$ cargo test --test integration_tests --no-run +``` + +**Компиляция утилиты тестирования с конкретным тестом** + +```sh +#### Компиляция и запуск конкретного теста +$ cargo test --test integration_tests regression_test + +#### С выводом логов +$ cargo test --test integration_tests regression_test -- --nocapture +``` + +**Компиляция утилиты тестирования для debug-режима** + +```sh +#### Обычная компиляция (debug по умолчанию) +$ cargo test --test integration_tests + +#### Компиляция в release-режиме (оптимизированная) +$ cargo test --test integration_tests --release +``` +**Проверка компиляции без запуска тестов с помощью утилиты тестирования** + +```sh +#### Проверить, что код компилируется без ошибок +$ cargo check --test integration_tests +``` + +**Компиляция утилиты тестирования с дополнительными флагами** +```sh +# С подробным выводом компиляции +$ cargo test --test integration_tests -v + +# С цветным выводом +$ cargo test --test integration_tests --color=always +``` +
+
+ +> [!TIP] +> После компиляции тестовый бинарный файл создается в следующей директории: +> `target/debug/deps/integration_tests-` +> Например, так: `target/debug/deps/integration_tests-abc123def456` + + +**Пример полного workflow по компиляции** + +```sh +# 1. Проверка компиляции +$ cargo check --test integration_tests + +# 2. Компиляция и запуск всех тестов +$ cargo test --test integration_tests -- --nocapture + +# 3. Компиляция и запуск только нагрузочного теста +$ cargo test --test integration_tests load_test -- --nocapture + +# 4. Компиляция в release-режиме +$ cargo test --test integration_tests --release -- --nocapture +``` + +

(К началу)

+ +## Тестирование + +В состав проекта, входит утилита `integration_tests.rs` **integration_tests.rs** - это интеграционный тестовый набор, который при запуске создает и выполняет сразу несколько различных типов тестов. С её помощью можно запустить как сразу все тесты, так и определённый тест. +Вышеописанная утилита - является мощным инструментом для комплексного тестирования всей системы Falcot, позволяющий быстро выявлять проблемы на разных уровнях приложения и обеспечивать высокое качество кода. + +**Falcot поддерживает пять типов тестов:** + + * **Регрессионный тест - проверяет базовую функциональность** + * **Unit-тест - тестирует конкретный модуль (индексы)** + * **Smoke-тест - проверяет запуск системы** + * **Нагрузочный тест - проверяет производительность** + * **Стресс-тест - проверяет устойчивость при высокой нагрузке** + +**Запуск всех тестов** + +Для запуска всех тестов сразу используйте команду в терминале: + +```sh +$ cargo test --test integration_tests -- --nocapture +``` + +**Запуск конкретного теста** + +```sh +#### Только регрессионный тест +$ cargo test --test integration_tests regression_test -- --nocapture + +#### Только нагрузочный тест +$ cargo test --test integration_tests load_test -- --nocapture + +``` + +**Запуск теста с фильтром** + +```sh +#### Все тесты, содержащие "test" в названии +$ cargo test --test integration_tests test -- --nocapture +``` + +**Что происходит при запуске** +> [!TIP] +> * Создается изолированная тестовая среда - каждый тест работает с чистой копией базы данных +> * Тесты выполняются параллельно (где это безопасно) +> * Каждый тест независим - результаты одного теста не влияют на другие +> * Выводятся подробные логи о ходе выполнения тестов + +
+
+ +> [!TIP] +> **Пример вывода** +> * Running 5 tests: +> * regression_test - passed in 0.2s +> * unit_test_indexes - passed in 0.1s +> * smoke_test - passed in 0.05s +> * load_test - passed in 1.8s (1000 documents) +> * stress_test - passed in 12.3s (2500 operations) +> * All 5 tests passed! + +
+
+ +> [!TIP] +> **Как интерпретировать результаты** +> * Все тесты passed - система стабильна, можно выпускать в production +> * Regression test failed - сломана базовая функциональность +> * Load test failed - проблемы с производительностью +> * Stress test failed - система не устойчива под нагрузкой +> * Unit test failed - проблемы в конкретном модуле + +
+
+ +> [!TIP] +> **Важные моменты** +> * Тесты компилируются автоматически при первом запуске `cargo test` +> * Изменения в коде требуют перекомпиляции при следующем запуске +> * Бинарник тестов временный и пересоздается при изменении кода +> * Можно запускать напрямую скомпилированный бинарник (но это сложнее) + +
+ +Таким образом, команда `cargo test --test integration_tests` одновременно компилирует и запускает все тесты из указанного файла. + + +

(К началу)

+ + + +## Примеры команд субд +```sh +./falcot config.toml + +В интерактивном режиме: + +Loading configuration from: config.toml +Database initialized with system collections + +Falcot Database Server +Version: 1.0.0 +Features: Wait-Free Architecture, Master-Master Replication, Lua Scripting, HTTP/HTTPS Support +HTTP server started on 127.0.0.1:8082 +Starting Lua interpreter... +Lua interpreter ready. Type 'inbox.start' to enter database mode. +Type 'exit' to quit. +lua> falcot_log("Добро пожаловать в Falcot!") +LUA: Добро пожаловать в Falcot! + +lua> inbox.start +Entering database mode. Type CRUD commands or 'inbox.stop' to exit. + +falcot:~> create users '{"name": "Иван", "age": 25, "city": "Москва"}' +Document created with ID: a1b2c3d4-e5f6-7890-abcd-ef1234567890 + +falcot:~> create users '{"name": "Мария", "age": 30, "city": "Санкт-Петербург"}' +Document created with ID: b2c3d4e5-f6g7-8901-bcde-f23456789012 + +falcot:~> list users +Documents in collection: [{"_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","name":"Иван","age":25,"city":"Москва"},{"_id":"b2c3d4e5-f6g7-8901-bcde-f23456789012","name":"Мария","age":30,"city":"Санкт-Петербург"}] + +falcot:~> begin trans1 +Transaction started successfully + +falcot:~> create products '{"name": "Ноутбук", "price": 50000, "category": "электроника"}' +Document created with ID: c3d4e5f6-g7h8-9012-cdef-345678901234 + +falcot:~> create products '{"name": "Телефон", "price": 25000, "category": "электроника"}' +Document created with ID: d4e5f6g7-h8i9-0123-defg-456789012345 + +falcot:~> commit trans1 +Transaction committed successfully + +falcot:~> inbox.stop +Exiting database mode. Back to Lua interpreter. + +lua> procedure create count_users ' +function count_users() + local result = falcot_db.query("users", "{}") + local count = 0 + for _ in string.gmatch(result, "\\\"name\\\":") do + count = count + 1 + end + return "Всего пользователей: " .. count +end +return count_users +' +Stored procedure created successfully + +lua> procedure call count_users +Procedure result: Всего пользователей: 2 + +lua> exit +Shutting down Falcot server... +``` + +**Параллельно запускаем в другом терминале:** + +```sh +#### Проверка HTTP API +curl http://127.0.0.1:8082/api/ +#### {"status": "ok", "message": "Falcot Server is running"} + +#### Получение списка пользователей +curl http://127.0.0.1:8082/api/query?collection=users +#### [{"_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","name":"Иван","age":25,"city":"Москва"},...] +``` +

(К началу)

+ + +## Обработка статических страниц + +Запуск статических веб-страниц, из сервера приложений falcot + +Falcot имеет встроенную поддержку статических файлов: +Настройка статических файлов: + +```sh + Создайте каталог `static` в корневой директории приложения: + + $ mkdir static + ``` + Разместите файлы в каталоге static: + ```sh + falcot/ +├── static/ +│ ├── index.html +│ ├── style.css +│ ├── script.js +│ ├── images/ +│ │ └── logo.png +│ └── api-docs.html +└── config.toml +``` + +После чего HTTP сервер автоматически будет обслуживать эти файлы: +```sh +Примеры доступа: + +# Главная страница +http://127.0.0.1:8082/ + +# Конкретный файл +http://127.0.0.1:8082/index.html +http://127.0.0.1:8082/style.css +http://127.0.0.1:8082/images/logo.png + +# API документация +http://127.0.0.1:8082/api-docs.html +``` + +**Falcot поддерживает следующие типы файлов:** + + * HTML (.html) + * CSS (.css) + * JavaScript (.js) + * Изображения (.png, .jpg, .jpeg) + * Аудио (.mp3) + * Видео (.mp4) + * JSON (.json) + * Текстовые файлы (.txt) + * Файлы в формате **pdf** (.pdf) + * Markdown (.md) + + + +

(К началу)

+ + +## Репликация + +Сервер-приложенй falcot поддерживает синхронную мастер-мастер репликацию. +За управление репликацией отвечает секция `[replication]` в конфигурационном файле `config.toml` + +```sh +# config.toml +[server] +host = "127.0.0.1" +port = 8081 +http_port = 8082 + +[replication] +enabled = true +master_nodes = [ + "127.0.0.1:8081", + "127.0.0.1:8083", + "127.0.0.1:8085" +] +sync_interval = 2000 # 2 секунды +``` + +**Запуск нескольких экземпляров сервера** + +```sh +# Терминал 1 - основной сервер на порту 8081 +$ cargo run -- config1.toml + +# Терминал 2 - реплика на порту 8083 +$ cargo run -- config2.toml + +# Терминал 3 - реплика на порту 8085 +$ cargo run -- config3.toml +``` + +**Тестирование репликации** + +```sh +-- replication_test.lua +falcot_log("Testing replication...") + +-- Добавляем данные на основном сервере +local doc1 = falcot_db.create("test_data", '{"type": "main", "value": "from_server_1"}') +local doc2 = falcot_db.create("test_data", '{"type": "main", "value": "from_server_1_again"}') + +falcot_log("Documents created on main server: " .. doc1 .. ", " .. doc2) + +-- Ждем синхронизации +falcot_log("Waiting for replication...") +os.execute("sleep 3") -- Ждем дольше интервала синхронизации + +-- Проверяем на репликах (это нужно делать с разных клиентов) +falcot_log("Checking replicated data...") +local all_data = falcot_db.query("test_data", "{}") +falcot_log("All data: " .. all_data) +``` + +**Мониторинг репликации** + +```sh +# В Lua shell можно проверять статус репликации +lua> inbox.start + +# Проверяем статус репликации +falcot:~> print(falcot.engine.replication.status()) + +# Смотрим список узлов +falcot:~> print("Nodes: " .. table.concat(falcot.engine.replication.get_nodes(), ", ")) + +# Запускаем принудительную синхронизацию +falcot:~> falcot.engine.replication.sync() +``` + +

(К началу)

+ +**Пример конфигурационных файлов репликации для узлов кластера** + +**config1.toml (основной сервер):** + +```sh +[server] +host = "127.0.0.1" +port = 8081 +http_port = 8082 + +[replication] +enabled = true +master_nodes = ["127.0.0.1:8083", "127.0.0.1:8085"] +sync_interval = 1000 + +[lua] +scripts_dir = "lua_scripts" +auto_execute = ["init.lua"] +``` + +**config2.toml (Реплика 1):** + +```sh +[server] +host = "127.0.0.1" +port = 8083 +http_port = 8084 + +[replication] +enabled = true +master_nodes = ["127.0.0.1:8081", "127.0.0.1:8085"] +sync_interval = 1000 +``` + +**config3.toml (Реплика 2):** + +```sh +[server] +host = "127.0.0.1" +port = 8085 +http_port = 8086 + +[replication] +enabled = true +master_nodes = ["127.0.0.1:8081", "127.0.0.1:8084"] +sync_interval = 1000 +``` + +**config4.toml (Реплика 3):** + +```sh +[server] +host = "127.0.0.1" +port = 8086 +http_port = 8087 + +[replication] +enabled = true +master_nodes = ["127.0.0.1:8081", "127.0.0.1:8083"]4sync_interval = 1000 +``` + +**Мониторинг и управление** + +```sh +#### Проверка статуса репликации через HTTP API +curl http://127.0.0.1:8082/api/replication/status + +#### Принудительная синхронизация +curl -X POST http://127.0.0.1:8082/api/replication/sync + +#### Просмотр статистики +curl http://127.0.0.1:8082/api/stats +``` + +**Пример lua-скрипта по обработки ошибок репликации** + +```sh +-- error_handling.lua +falcot_log("Testing replication error handling") + +-- Пытаемся добавить данные при недоступности реплик +local success, result = pcall(function() + return falcot_db.create("test_collection", '{"data": "test"}') +end) + +if success then + falcot_log("Data created successfully: " .. result) + + -- Проверяем статус репликации + local rep_status = falcot.engine.replication.status() + if rep_status ~= "active" then + falcot_log("Warning: Replication is not active. Status: " .. rep_status) + end + +else + falcot_error("Failed to create data: " .. result) + + -- Пытаемся работать в offline режиме + falcot_log("Trying offline operation...") + local offline_data = falcot_db.query("test_collection", "{}") + falcot_log("Offline data available: " .. #offline_data) +end +``` + +## Резервное копирование + +Для встроенной в сервер-приложений falcot, субд **futriix** предусмотрен механизм восстановления из резервных копий (бекапов) +Бекапы можно создавать c помощью языка lua. + +**Создание бекапа через lua** + +```sh +-- Создаем бэкап +local result = falcot.engine.backup.start() +print(result) -- "Backup created successfully: /falcot/backups/backup_20231201_143022.json" + +-- Или через прямое обращение к функции +local result = falcot_db.backup_start() +print(result) + +-- Создаем несколько тестовых документов перед бэкапом +falcot_db.create('products', '{"name": "Laptop", "price": 999.99, "category": "electronics"}') +falcot_db.create('products', '{"name": "Phone", "price": 499.99, "category": "electronics"}') +falcot_db.create('users', '{"name": "Alice", "email": "alice@example.com", "role": "admin"}') + +-- Создаем бэкап с данными +local backup_result = falcot.engine.backup.start() +``` + +**Восстановление из бекапа** + +```sh +-- Восстанавливаем из конкретного бэкапа +local restore_result = falcot.engine.backup.restore('/falcot/backups/backup_20231201_143022.json') +print(restore_result) -- "Backup restored successfully" + +-- Или через прямое обращение +local restore_result = falcot_db.backup_restore('/falcot/backups/backup_20231201_143022.json') + +-- Проверяем, что данные восстановились +local users = falcot_db.read('users', 'user123') +local products = falcot_db.query('products', '{}') +print('Users:', users) +print('Products count:', #products) + +``` +**Использование бекапов в интерактивной оболочке** + +```sh +#### Создаем бэкап +backup start +# Output: Backup created successfully: /falcot/backups/backup_20231201_143022.json + +#### Восстанавливаем из бэкапа +backup restore /falcot/backups/backup_20231201_143022.json +#### Output: Backup restored successfully + +#### Смотрим список доступных бэкапов +!ls /falcot/backups/ +#### Output: backup_20231201_143022.json backup_20231202_020001.json + +#### Создаем тестовые данные +create products '{"name": "Test Product", "price": 100}' +create users '{"name": "Test User", "email": "test@example.com"}' + +#### Создаем бэкап и сразу проверяем восстановление +backup start +delete products test_product_id +delete users test_user_id +backup restore /falcot/backups/backup_20231201_143022.json +read products test_product_id +#### Данные восстановяться +``` + +**Интеграция с триггерами для создания автоматических бекапов** + +```sh +-- Триггер для создания бэкапа при критических изменениях +falcot_db.add_trigger('auto_backup_on_change', 'after_update', 'config', [[ + local config = json.decode(document) + if config.critical_setting then + -- Создаем бэкап при изменении критических настроек + local backup_result = falcot_db.backup_start() + falcot_log('Auto-backup created due to config change: ' .. backup_result) + end +]]) + +-- Триггер для бэкапа перед массовыми операциями +falcot_db.add_trigger('backup_before_bulk_operation', 'before_delete', 'users', [[ + -- Проверяем, это одиночное удаление или массовая операция + if bulk_operation then + local backup_result = falcot_db.backup_start() + falcot_log('Backup created before bulk operation: ' .. backup_result) + end +]]) + +``` + +

(К началу)

+ + +## HTTP API + +Использование curl для работы с HTTP API: + +```sh +#### Проверка статуса сервера +curl http://127.0.0.1:8082/ + +##### Создание документа +curl -X POST http://127.0.0.1:8082/api/create \ + -H "Content-Type: application/json" \ + -d '{ + "collection": "users", + "document": {"name": "John Doe", "email": "john@example.com", "age": 30} + }' + +#### Чтение документа +curl "http://127.0.0.1:8082/api/read?collection=users&id=document_id_here" + +#### Запрос документов +curl -X POST http://127.0.0.1:8082/api/query \ + -H "Content-Type: application/json" \ + -d '{ + "collection": "users", + "filter": {"age": {"$gt": 25}} + }' + +#### Обновление документа +curl -X PUT http://127.0.0.1:8082/api/update \ + -H "Content-Type: application/json" \ + -d '{ + "collection": "users", + "id": "document_id_here", + "document": {"name": "John Updated", "age": 31} + }' + +#### Удаление документа +curl -X DELETE http://127.0.0.1:8082/api/delete \ + -H "Content-Type: application/json" \ + -d '{ + "collection": "users", + "id": "document_id_here" + }' + ``` + +

(К началу)

+ + +## Аутентификация + +Для повышения безопасности в сервере-приложений falcot используется `Аутентификация`. +За параметры авторизации отвечает секция `[security]` в конфигурационном файле `./falcot/config.toml` + +```sh +[security] +require_authentication = false +jwt_secret = "your-secret-key-here" +password_hashing_rounds = 12 +``` +
+ +Детальное описание параметров секции: + +1. **require_authentication = false** + +Назначение: Включает/выключает обязательную аутентификацию + +Допустимые значения параметра `require_authentication`: + +* false - анонимный доступ разрешен (по умолчанию) +* true - требуется аутентификация для всех операций + +При установки значения параметра `require_authentication = true` клиенты должны предоставлять JWT токен. Он содержит информацию о пользователе и правах доступа. Токен проверяется с использованием параметра `jwt_secret` и подписываются секретным ключом для предотвращения подделки. +Без валидного токена операции блокируются. Все токены имеют ограниченное время жизни (обычно несколько часов). + +Назначение: Защищает API от несанкционированного доступа +
+ +2. **jwt_secret = "your-secret-key-here"** + +Назначение: Секретный ключ для JWT (JSON Web Tokens) +Формат: Произвольная строка, рекомендуется длинная криптостойкая +
+ +3. **password_hashing_rounds = 12** + +Назначение: Количество раундов хеширования паролей. Пароли хешируются с указанным количеством раундов, и исходные пароли никогда не хранятся в чистом виде,что обеспечивает защиту от атак перебором даже при утечке базы данных. + +Значения: Обычно от 10 до 15 (чем больше - тем безопаснее, но медленнее) +Алгоритм: Вероятно bcrypt (стандарт для безопасного хеширования) +Использование: Защита паролей пользователей в базе данных + +Использование: + +* Подписание JWT токенов аутентификации +* Верификация подлинности токенов +
+
+ +> [!CAUTION] +> **Важно!!!** В продакшене нужно заменить значение параметра `jwt_secret ` на длинный (не менее 32 символов) уникальный сложный ключ. + +

(К началу)

+ +## HTTPS + +Сервер-приложенй falcot поддерживает протоколы https и http2. +Утилита `generate_certs` - Генерация сертификатов + +Назначение: Генерация самоподписанных SSL/TLS сертификатов для HTTPS. +Запуск утилиты для генерации тестовых сертификатов: `cargo run --bin generate_certs` + +По итогу работы утитилиты создаётся следующее дерево каталогов: + +```sh +certs/ +├── cert.pem # Публичный сертификат +└── key.pem # Приватный ключ +``` + +Процесс генерации сертификата: + + **1.Создается пара ключей (публичный и приватный)** + **2.Генерируется самоподписанный сертификат** + **3.Сертификат подписывается приватным ключом** + **4.Файлы сохраняются в папку `certs` ** + + +**Примеры конфигураций** + + +**Пример 1: Базовая конфигурация** + +```sh +[tls] +enabled = true +cert_path = "certs/cert.pem" +key_path = "certs/key.pem" + +[server] +https_port = 8443 +``` + +**Пример 2: Генерация сертификатов и запуск** + +```sh +# Генерируем сертификаты +cargo run --bin generate_certs + +# Запускаем сервер +cargo run + +# Тестируем подключение +curl -k https://localhost:8443/api/status +curl http://localhost:8082/api/status +``` + +> [!TIP] +> Безопасность: +> * Самоподписанные сертификаты подходят для разработки и внутреннего использования +> * Для продакшена рекомендуется использовать сертификаты от Let's Encrypt или других CA +> * ACL обеспечивает дополнительный уровень безопасности +> * HTTPS шифрует трафик между клиентом и сервером +> * ACL защищает от нежелательных подключений, а `generate_certs` позволяет быстро настроить HTTPS для безопасного соединения. + + +

(К началу)

+ + +## ACL + +**ACL** - это система управления доступом, которая позволяет разрешать или запрещать подключения к серверу на основе IP-адресов. +Как работает ACL в Falcot: + +Принцип работы: + + **1.Проверка запрещенных IP - если IP в списке denied_ips, доступ блокируется** + **2.Проверка разрешенных IP - если список allowed_ips не пустой, проверяется наличие IP в нем** + **3.Если ACL отключен - все подключения разрешены** + + +**Примеры использования в конфигурации:** + +```sh +#### Разрешить только локальные подключения +[acl] +enabled = true +allowed_ips = ["127.0.0.1", "::1"] +denied_ips = [] + +#### Заблокировать конкретные проблемные IP +[acl] +enabled = true +allowed_ips = [] # Пустой список = разрешены все +denied_ips = ["192.168.1.100", "10.0.0.25"] + +#### Разрешить только внутреннюю сеть +[acl] +enabled = true +allowed_ips = ["192.168.1.0/24", "10.0.0.0/8"] +denied_ips = [] +``` +
+ +**Пример: Запуск сервера-приложений ACL для разработки** + +```sh +[acl] +enabled = true +allowed_ips = ["127.0.0.1", "::1", "192.168.1.0/24"] +denied_ips = [] + +[tls] +enabled = true +cert_path = "certs/cert.pem" +key_path = "certs/key.pem" + +[server] +http_port = 8082 +https_port = 8443 +http2_enabled = true +``` + +**Пример: Продвинутая ACL конфигурация** +```sh +[acl] +enabled = true +# Разрешить только внутренние адреса и конкретные внешние +allowed_ips = [ + "127.0.0.1", + "::1", + "192.168.1.0/24", + "10.0.0.0/8", + "203.0.113.5" # Конкретный внешний IP +] +# Заблокировать проблемные IP +denied_ips = [ + "192.168.1.100", + "10.0.0.25", + "198.51.100.0/24" # Целая подсеть спамеров +] +``` +
+ +**Формат IP-адресов:** + + * 127.0.0.1 - конкретный IPv4 + * ::1 - IPv6 localhost + * 192.168.1.0/24 - подсеть CIDR + * 10.0.0.0/8 - большая подсеть + +

(К началу)

+ + +## Индексы + +Falcot поддерживает два стандартных типа индекса: первичные индексы и вторичные индексы + +**Различия между первичным и вторичным индексом** + +1. **Первичный индекс (Primary Index)** + +**Особенности:** + + 1. **Обязательно уникальный - не допускает дублирования значений** + 2. **Автоматически создается для поля id в каждой коллекции и не требует ручного создания** + 3. **Используется для быстрого поиска документов по их идентификатору** + 4. **Гарантирует целостность данных - предотвращает создание документов с одинаковым `ID`** + +**Пример создания** + +```sh +-- Поиск по ID (использует первичный индекс) +local document = falcot_db.read("users", "550e8400-e29b-41d4-a716-446655440000") +``` + +2. **Вторичный индекс (Secondary Index)** + +**Особенности:** + + 1. **Может быть как уникальным, так и неуникальным** + 2. **Создается вручную для любых полей документа** + 3. **Используется для оптимизации запросов по не-`ID полям`** + 4. **Поддерживает различные типы данных (строки, числа, булевы значения)** + + +**Пример создания** + +```sh +-- Неуникальный индекс по полю 'email' +falcot_db.create_index("users", "email_idx", "email", false) + +-- Уникальный индекс по полю 'username' +falcot_db.create_index("users", "username_idx", "username", true) +``` + + +**Создание и использование индексов через Lua shell** + +```sh +#### Запускаем сервер +$ cargo run + +#### Входим в режим inbox +$ lua> inbox.start + +#### Создаем коллекцию пользователей +falcot:~> create users '{"name": "Alice", "age": 30, "email": "alice@example.com"}' +falcot:~> create users '{"name": "Bob", "age": 25, "email": "bob@example.com"}' +falcot:~> create users '{"name": "Charlie", "age": 35, "email": "charlie@example.com"}' + +#### Создаем вторичный индекс по полю "name" +falcot:~> index create users name_index name + +#### Создаем уникальный индекс по полю "email" +falcot:~> index create users email_index email unique + +#### Ищем по индексу name +falcot:~> index query users name_index "Alice" + +#### Ищем по индексу email +falcot:~> index query users email_index "bob@example.com" + +#### Пытаемся создать дубликат email (должна быть ошибка) +falcot:~> create users '{"name": "Another Bob", "age": 28, "email": "bob@example.com"}' +``` +**Создание и использование индексов через Lua скрипты:** + +```sh +-- create_indexes.lua +falcot_log("Creating indexes...") + +-- Создаем индексы +falcot_db.create_index("users", "name_index", "name", false) +falcot_db.create_index("users", "email_index", "email", true) + +-- Добавляем данные +falcot_db.create("users", '{"name": "Alice", "age": 30, "email": "alice@example.com"}') +falcot_db.create("users", '{"name": "Bob", "age": 25, "email": "bob@example.com"}') + +-- Поиск по индексу +local result = falcot_db.query_by_index("users", "name_index", "Alice") +falcot_log("Search result: " .. result) + +-- Проверка уникальности (должна вызвать ошибку) +local status, err = pcall(function() + falcot_db.create("users", '{"name": "Another", "age": 28, "email": "bob@example.com"}') +end) +if not status then + falcot_error("Unique constraint violation: " .. err) +end +``` + +**Производительность индексов** + +**Первичный индекс:** + + * ** Максимальная скорость поиска по ID** + * **Всегда в памяти (кешируется)** + * **Минимальные накладные расходы** + +**Вторичный индекс:** + + * **Скорость зависит от размера индексируемых данных** + * **Может требовать дополнительной памяти** + * **Оптимизирует конкретные типы запросов** + +**Рекомендации по использованию индексов** + +Используйте первичный индекс для: + + * **Быстрого доступа к документам по их ID** + * **Операций обновления/удаления конкретных документов** + * **Гарантии уникальности идентификаторов** + +Используйте вторичный индекс для: + + * **Поиска документов по любым другим полям** + * **Оптимизации часто выполняемых запросов** + * **Обеспечения уникальности бизнес-ключей (email, username и т.д.)** + * **Ускорения сортировки и фильтрации** + + +#### Обработка ошибок индексов + +**Первичный индекс (автоматическая проверка) на языке lua: ** + +```sh +-- Попытка создать документ с существующим ID вызовет ошибку +local status, err = pcall(function() + falcot_db.create("users", '{"id": "existing_id", "name": "Duplicate"}') +end) +``` + +**Вторичный индекс (ручная проверка уникальности) на языке lua: :** + +```sh +-- При unique=true попытка дублирования вызовет ошибку +local status, err = pcall(function() + falcot_db.create("users", '{"email": "existing@example.com", "name": "Duplicate"}') + falcot_db.create("users", '{"email": "existing@example.com", "name": "Duplicate2"}') +end) +if not status then + falcot_error("Unique constraint violation: " .. err) +end +``` + +Таким образом, первичный индекс в falcot - это автоматически создаваемый уникальный индекс для поля `id`, в то время как вторичные индексы создаются вручную для оптимизации произвольных запросов и могут быть как уникальными, так и неуникальными. + +

(К началу)

+ + +## Constraints (Ограничения) + +**Ограничения (Constraints)** — это правила, применяемые к данным в таблице в реляционных субд (или её аналоге в не реляцционных субд) для поддержания их корректности и надёжности. Они играют важную роль в обеспечении целостности данных и соответствия бизнес-правилам. + +При создании таблицы или измененинии её структуры, можно определить различные ограничения,предотвращающие добавление, изменение или удаление данных, нарушающих установленные правила. Это помогает избежать нежелательных ситуаций, например таких как: + + * **Наличие нескольких пользователей с одинаковыми идентификаторами** + * **Ссылки на несуществующие записи в других таблицах** + * **Отсутствие данных обязательных для заполнения** + * **Ввод некорректных значений (например, отрицательного возраста или будущей даты рождения)** + + Ограничения реализованы на уровне встроенной субд **futriix**, ниже приведы примеры использования Ограничений: +
+**Пример уникального ограничения поля** + + ```sh +#### Гарантируем уникальность email в коллекции users +falcot:~> constraint add users unique_email unique email + +#### Где: +#### - users: коллекция +#### - unique_email: название ограничения +#### - unique: тип ограничения +#### - email: поле + ``` + + **Пример ограничения диапазона** + + ```sh +#### Ограничиваем возраст пользователей (18-120 лет) +falcot:~> constraint add users age_range range age "{\"min\":18,\"max\":120}" + +#### Где range - тип ограничения, можно передавать JSON значение + ``` + + **Пример ограничения по шаблону** + + ```sh +#### Проверяем формат email +falcot:~> constraint add users email_pattern pattern email "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$" + ``` + +**Пример Внешний ключ (foreign key)** + ```sh +#### Связываем заказы с пользователями +falcot:~> constraint add orders user_foreign_key foreign user_id "users/id" + ``` + +**Просмотр ограничений** + + ```sh +#### Список всех constraints для коллекции +falcot:~> constraint list users + +#### Пример вывода: +#### Constraints for collection 'users': +#### - unique_email (field: email, type: unique) +#### - age_range (field: age, type: range(18-120)) +#### - email_pattern (field: email, type: pattern) + ``` + +**Удаление ограничения** + +```sh +#### Удаляем ограничение +falcot:~> constraint remove users unique_email +``` + + +

(К началу)

+ + +## Хранимые процедуры + +**Хранимая процедура в falcot** – это откомпилированная во внутреннее представление сервера субд подпрограмма, хранящаяся в базе данных. Хранимые процедуры пишутся на специальном языке хранимых процедур и триггеров, в котором имеются операторы присваивания, ветвлений и циклов, и в которых можно использовать операторы SQL, такие как INSERT, DELETE, UPDATE и SELECT. + + **Создание хранимой процедуры** + + ```sh + -- Создание хранимой процедуры для расчета статистики + local procedure_code = [[ function calculate_stats(collection_name) + local documents = falcot_db.query(collection_name, "{}") + local count = 0 + local total_age = 0 + + for doc in string.gmatch(documents, '([^,]+)') do + count = count + 1 + -- Здесь можно парсить JSON и считать статистику + end + + return "Документов: " .. count .. ", Средний возраст: " .. (total_age / count) + end + return calculate_stats ]] + version = "1.0.0" + edition = "2024" + ``` + + ```sh +-- Сохраняем процедуру +falcot_db.create_procedure("calculate_stats", procedure_code) +``` + +**Работа с хранимыми процедурами в lua интерпретаторе:** + +```sh +-- Создание процедуры +procedure create calculate_stats ' +function calculate_stats(collection_name) + local result = falcot_db.query(collection_name, "{}") + local count = 0 + for _ in string.gmatch(result, "\\\"_id\\\":") do + count = count + 1 + end + return "Количество документов в " .. collection_name .. ": " .. count +end +return calculate_stats +' + +-- Вызов процедуры +procedure call calculate_stats +``` + +**Создание хранимых процедур во одноимённой встроенной субд** + +```sh +# Создание процедуры +procedure create user_stats ' +function calculate_user_stats() + local users = falcot_db.query("users", "{}") + local count = 0 + for _ in string.gmatch(users, "\\\"name\\\":") do + count = count + 1 + end + return "Всего пользователей: " .. count +end +return calculate_user_stats +' +``` + +```sh +#### Вызов процедуры +procedure call user_stats +``` + +

(К началу)

+ + +## Триггеры + +Falcot помимо хранимых процедур поддерживает триггеры (обратные вызовы) +Триггеры можно создавать тремя способами: через lua-shell, через интерактивную оболочку, через хранимые процедуры встроенной субд + +**Создание триггеров через lua-shell** + +```sh + +-- Создаем триггер, который логирует создание документов в коллекции 'users' +falcot_db.add_trigger('log_user_creation', 'after_create', 'users', [[ + falcot_log('New user created with data: ' .. document) + -- Можно добавить дополнительную логику, например: + -- - Отправка уведомления + -- - Валидация данных + -- - Обновление связанных документов +]]) + +-- Триггер для проверки данных перед обновлением +falcot_db.add_trigger('validate_user_update', 'before_update', 'users', [[ + local user_data = json.decode(document) + if not user_data.email or not user_data.email:match('^[^@]+@[^@]+%.[^@]+$') then + error('Invalid email format') + end + if user_data.age and user_data.age < 0 then + error('Age cannot be negative') + end +]]) + +-- Триггер для очистки связанных данных при удалении +falcot_db.add_trigger('cleanup_user_data', 'before_delete', 'users', [[ + -- Удаляем связанные записи из других коллекций + falcot_db.delete('user_sessions', id) + falcot_db.delete('user_preferences', id) + falcot_log('Cleaned up user data for ID: ' .. id) +]]) +``` + +**Создание триггеров через интерактивную оболочку** + +```sh +##### Переходим в режим inbox +inbox.start + +##### Создаем триггер для логирования +trigger add log_creation after_create orders "falcot_log('New order created: ' .. document)" + +#### Триггер для автоматического обновления статистики +trigger add update_stats after_create orders [[ + -- Увеличиваем счетчик заказов + local stats = falcot_db.read('statistics', 'order_count') or '0' + local count = tonumber(stats) + 1 + falcot_db.update('statistics', 'order_count', tostring(count)) +]] + +#### Триггер для проверки цены перед созданием +trigger add validate_price before_create products [[ + local product = json.decode(document) + if product.price <= 0 then + error('Price must be positive') + end +]] + +``` + +**Пример создание триггеров через хранимые процедуры** + +```sh + +-- Создаем документ - сработает триггер after_create +falcot_db.create('users', '{"name": "John", "email": "john@example.com", "age": 25}') +-- В логах появится: "LUA: New user created with data: {"name": "John", "email": "john@example.com", "age": 25}" + +-- Попытка создать пользователя с невалидным email +falcot_db.create('users', '{"name": "Invalid", "email": "invalid", "age": 30}') +-- Получим ошибку: "Invalid email format" + +-- Обновляем пользователя +falcot_db.update('users', 'user123', '{"name": "John Updated", "email": "john.new@example.com", "age": 26}') +-- Сработает триггер before_update для валидации + +-- Удаляем пользователя +falcot_db.delete('users', 'user123') +-- Сработает триггер before_delete для очистки связанных данных + +``` + +

(К началу)

+ +## Lua-скрипты + +> [!CAUTION] +> **Поддержка работы lua в настоящий момент эксперементальная и может вызвать аварийное завершение сервера!!!** + +В Falcot существует несколько способов запуска Lua скриптов + + +**Способ 1: Непосредственный ввод кода в lua-интерпретатор** +```sh +lua> falcot_log("Привет, мир!") +LUA: Привет, мир! + +lua> local x = 10 + 5 +lua> falcot_log("Результат: " .. x) +LUA: Результат: 15 +``` + +**Способ 2: Многострочный ввод (через конкатенацию)** +```sh +lua> local script = [[ +>> for i = 1, 3 do +>> falcot_log("Итерация: " .. i) +>> end +>> ]] +lua> falcot.engine.execute_script(script) +LUA: Итерация: 1 +LUA: Итерация: 2 +LUA: Итерация: 3 +``` + +**Способ 3: Запуск из файла** + + 1. **`lua_scripts` - это каталог (директория), где хранятся Lua-скрипты для выполнения сервером Falcot** + 2. **При запуске сервера автоматически выполняются скрипты из `auto_execute` списка, находящиеся в этой директории** + 3. **Сервер автоматически создает этот каталог при первом запуске, если он не существует** + +**Как это работает:** + + 1. **Сервер при запуске создает каталог lua_scripts (если его нет)** + 2. **В этот каталог можно помещать Lua-скрипты** + 3. **Скрипты из списка auto_execute выполняются автоматически при старте сервера** + 4. **Другие скрипты можно выполнять вручную через Lua-интерпретатор командой falcot.engine.lua.execute("имя_скрипта.lua")** + + +```sh + +Пример структуры каталогов falcot: + +lua_scripts/ +├── init.lua (автоматически выполняется при старте) +├── utils.lua (вспомогательные функции) +├── procedures/ (подкаталог для хранимых процедур) +│ ├── user_management.lua +│ └── data_processing.lua +└── config/ (подкаталог для конфигурационных скриптов) + └── system_config.lua +``` + +### Примеры lua-скриптов +```sh +-- Простой Lua скрипт для демонстрации +falcot_log("Запуск примера Lua скрипта") + +-- Создание документа +falcot_db.create("users", '{"name": "John", "age": 30, "email": "john@example.com"}') + +-- Чтение документа +local result = falcot_db.read("users", "some-document-id") +falcot_log("Результат чтения: " .. result) +``` + +```sh +-- Математические операции +local x = 10 +local y = 20 +falcot_log("Сумма: " .. (x + y)) + +-- Циклы и условия +for i = 1, 5 do + if i % 2 == 0 then + falcot_log("Четное число: " .. i) + else + falcot_log("Нечетное число: " .. i) + end +end + +``` +

(К началу)

+ +## Транзакции + +Работа с транзакциями, во встроенной субд: + +```sh +# Начало транзакции +begin transaction_123 + +# Несколько операций в транзакции +create users '{"name": "Alice", "age": 25}' +create users '{"name": "Bob", "age": 30}' +create users '{"name": "Charlie", "age": 35}' + +# Фиксация транзакции +commit transaction_123 + +# Или откат при ошибке +begin transaction_456 +create users '{"name": "David", "age": 40}' +rollback transaction_456 +``` +

(К началу)

+ + +## Шардинг + +Встроенная в falcot субд **futriix** поддерживает горинзонтальный шардинг, т.е. горизонтальное масштабирование. +По умолчанию шардинг производится `по алгоритму Hash-based с консистентным хэшированием`. Шифрование производится согласно алгоритму `SipHasher13`. +Но также поддерживается возможность управлять шардингом вручную. Ниже приведены команды по управлению шардингом: + +**Пример добавления узла** + +```sh +#### Добавляем новый узел шардинга +falcot:~> shard add node1 127.0.0.1:8084 1024 + +#### Где: +#### - node1: идентификатор узла +#### - 127.0.0.1:8084: адрес узла +#### - 1024: емкость в MB +``` + +**Пример удаления узла** + +```sh +#### Удаляем узел из кластера +falcot:~> shard remove node1 +``` + +**Пример миграции между шардами узла** + +```sh +#### Мигрируем данные коллекции между узлами +falcot:~> shard migrate users node1 node2 user_id + +#### Где: +#### - users: коллекция для миграции +#### - node1: исходный узел +#### - node2: целевой узел +#### - user_id: ключ шардирования +``` + +**Пример просмотра статуса кластера** + +```sh +#### Показывает статус всего кластера +falcot:~> shard status + +#### Пример вывода: +#### === Cluster Status === +#### Total capacity: 2048 GB +#### Total used: 512 MB +#### Rebalance needed: false +#### +#### Node node1: +#### Address: 127.0.0.1:8081 +#### Capacity: 1024 MB +#### Used: 256 MB +#### Usage: 25.0% +#### Collections: users, products +``` + +**Пример ручной ребалансировки кластера** + +```sh +#### Запускает автоматическую ребалансировку +falcot:~> cluster rebalance +``` + +**Пример создания шардированной системы пользователей** + +```sh +#### Добавляем узлы +falcot:~> shard add node1 127.0.0.1:8081 1024 +falcot:~> shard add node2 127.0.0.1:8082 1024 + +#### Создаем constraints для пользователей +falcot:~> constraint add users unique_email unique email +falcot:~> constraint add users valid_age range age "{\"min\":13,\"max\":150}" +falcot:~> constraint add users valid_username pattern username "^[a-zA-Z0-9_]{3,20}$" + +#### Распределяем пользователей по шардам +shard migrate users node1 node2 user_id +``` + +**Мониторинг шардинга** + +```sh +#### Проверяем статус +falcot:~> shard status + +#### Если нужно перебалансировать +falcot:~> cluster rebalance + +#### Проверяем constraints +falcot:~> constraint list users +``` + +

(К началу)

+ + +## Сферы применения + +Идеальными сферами применения проекта falcot, являются следующие: + +1. **Микросервисы с потребностью в оперативной аналитике** +2. **Работающая в режиме реального времени панель мониторинга - для администрирования бекенда** +3. **Приложения, тербующие среднего масштабирования со смешанными рабочими нагузками (англ. workload)** +4. **Прототипирование перед выбором специализированного решения** + +
+Пример функциональных возможностей falcot классов OLTP и OLAP для микросервисов с потребностью в оперативной аналитике +
+ +```sh +-- OLTP-операция: быстрая транзакция +falcot_db.update("users", "user123", '{"balance": 100}') + +-- OLAP-операция: аналитический запрос +local analytics = falcot_db.query("transactions", '{"date": {"$gt": "2024-01-01"}}') +``` + +

(К началу)

+ + +## Дорожная карта + +- [x] Реализовать поддержку хранимых процедур +- [x] Реализовать поддержку триггеров (обратных вызовов) +- [x] Реализовать поддержку многопоточности +- [x] Реализовать неблокирующие чтение/запись +- [x] Реализовать мульти-мастер асинхронную репликацию через файл конфигурации +- [x] Реализовать логирование +- [x] Реализовать поддержку синхронной мастер-мастер репликации +- [x] Реализовать поддержку протоколов HTTPS и HTTP2 +- [x] Реализовать поддержку первичных индексов +- [x] Реализовать поддержку протокола MessagePack +- [x] Реализовать поддержку транзакций +- [x] Реализовать поддержку первичных и вторичных индексов +- [x] Добавить механизм сторонних модулей на языке lua, расширяющих базовый функционал сервера +- [x] Реализовать проверку запуска сервера при запуске клиента (если сервер НЕ запущен клиент не запускается) +- [x] Реализовать поддержку HTTP-restfull API +- [x] Исправить ошибки записи журнала логов (в журнал лога кроме текущего времени добавить текущий год) +- [x] Реализовать утилиту тестирования сервера на количество запросов на чтение/запись +- [x] Переписать асинхронную мастер-мастер репликацию на синхронную мастер-мастер репликацию +- [ ] Реализовать журнал WAL +- [ ] Реализовать графический веб-интерфейс для упраления кластером +- [x] Реализовать автоматический шардинг с консистентным хэшированием +- [ ] Реализовать поддержку алгоритма Raft +- [ ] Реализовать поддержку SQL +- [ ] Реализовать поддержку ACID-транзакций +- [ ] Интегрировать интеллектуального помощник FutBot на официальный сайт +- [ ] Реализовать полноценного интеллектуального помощника FutBot, задачами которого будут быстрый поиск ответов на вопросы, возникающие при эксплуатации субд Futrix. + +См. [Открытые проблемы](https://source.futriix.ru/gvsafronov/futriixw/issues) полный список предлагаемых функций (и известных проблем). + +

(К началу)

+ + + + + +## Контакты + +Григорий Сафронов - [E-mail](gvsafronov@yandex.ru) + +Ссылка на Интеллектуальный помощник - [FutBot](https://t.me/Futriix_bot) + +

(К началу)