Futriix

Проект futriix это timeseries NOSQL субд без блокировок


## Краткая документация проекта Futriix
Содержание
  1. О проекте
  2. Лицензия
  3. Основные термины
  4. Подготовка
  5. Компиляция
  6. CRUD команды по работе с временными рядами
  7. Репликация
  8. Резервное копирование
  9. HTTP API
  10. Lua-скрипты
  11. Проблемы
  12. Дорожная карта
  13. Вклад
  14. Контакты
## О проекте Futriix это time-series NOSQL субд без блокировок написанная на языке программирования Rust. Поддерживает модель временных рядов (time series), в качестве основной модели. Для расщирения базового функционала имеет встроенный lua-интепретатор. При этом futriix является резидентной субд, т.е. хранящей свои данные в оперативной памяти, с их периодическим сохранением на внутренний носитель: HDD (жёсткий диск) или SSD-накопитель. ## Лицензия Проект распространяется под 3-пунктной лицензией BSD. Подробнсти смотрите в файле `LICENSE.txt`. ## Основные термины * **База Данных(БД)** -массив информация, хранящийся, например, на флешке, в файле, на кластере * **Система Управления Базами Данных(СУБД)** - Это программа для внесения изменений в базу данных и поиска по ней * **Временная метка (timestamp)**-Это метка времени, однозначно связывающая каждую запись в бд с конкретным моментом во времени. Если проводить аналогию с реляционными субд, то временнная метка это аналог термина **ключа** в реляционных субд. * **Резидентная СУБД** - субд, хранящая все свои данные в оперативной памяти, с периодическим сохранением на HDD или SSD * **Инстанс** - запущенный экземляр базы данных * **Узел (хост,нода)** - физический сервер * **Слайс(slice)** - аналог документа в любой документно-ориентированной субд * **Репликасет** - группа актуальных данных,хранящиеся на нескольких узлах * **Временные ряды (time series)** - это данные, последовательно собранные в регулярные промежутки времени, полученные из какого-либо устройства (цены на акции, данные температуры, объёмы продаж и.т.д.) * **Кластер** - группа компьютеров, объединённых высокоскоростными каналами связи и представляющая с точки зрения пользователя единый аппаратный ресурс * Команды, выполняемые с привилегиями суперпользователя (root), отмечены символом приглашения **«#»** * Команды, выполняемые с правами обычного пользователя(user), отмечены символом приглашения **«$»** * **FutBot** - интеллектуальный помощник в мессенджере Телеграмм, помогающий осущесвлять быстрый поиск по документации проекта ## Подготовка **Для операционных систем семейства 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 ``` ## Компиляция 1. Копируем репозиторий ```sh $ git clone https://source.futriix.ru/gvsafronov/futriix ``` 2. Переходим в каталог с исходном кодом src ```sh $ cd futriix/ ``` 3. Компилируем Futriix с помощью пакетного менеджера `Cargo` ```sh $ cargo build ``` 4. Для запуска тестов запускаем команды: ```sh $ cargo test --test integration # запуск только интеграционных тестов $ cargo test --bench benches # запуск только бенчмарков ``` > [!WARNING] > **Futriix также может быть скомпилирован для следующих операционных систем: `Linux`, `OSX`, `Open Indiana`, `FreeBSD`, но сборка для этих операционных систем не проводилась!!!** ## CRUD команды по работе с временными рядами В данном разделе приведён пример основных команд субд Futriix Запускаем клиент Futriix, перейдя в каталог с исходным кодом: ```sh $ cd /target/realease && ./clif ``` Представьте себе, что вы работаете на метерологической станции, где ежедневно вам необходимо фиксировать показатели погоды: влажность, темпратуру воздуха (и.т.д.) давайте посмотрим, на данном примере, как мы могли бы добавить значение `температура (temperature)`в бд. Для этого, выполняем команду `insert`, следующим образом: ```sh futriix:~> insert temperature 1672531200000 25.5 Insert successful ``` > [!TIP] > **Поcле вставки данных в slice, сервер автоматически добавит временную метку, в нашем примере 1672531200000** Как мы можем наблюдать ниже, сервером был получен ответ `successful`-это означает, что вставка данных (значение температуры) была внесена корректно. ```sh futriix:~> insert humidity 1672531200000 {"value": 65, "unit": "%"} Insert successful ``` Теперь давайте сделаем запрос на получение актуального значения с температурой (temperature) и влажностью (humidity) командой ниже `get`: ```sh futriix:~> get temperature [ [ 1672531200000, 25.5 ] ] ``` ```sh futriix:~> get humidity [ [ 1672531200000, { "unit": "%", "value": 65 } ] ``` Получим диапазон в которых лежат средние значени температуры и влажности, указав оба эти значения (температуры и влажности), в качестве параметров к оператору `get` ```sh futriix:~> get temperature 1672531200000 1672534800000 [ [ 1672531200000, 25.5 ] ] ] ``` Удалим оба значения ```sh futriix:~> delete temperature 1672531200000 1672531200000 Delete successful ``` Посмотрим как работают транзакции (создание, откат, коммит) ```sh futriix:~> begin Transaction 1 started futriix:tx1:~> insert pressure 1672531200000 1013 Insert successful futriix:tx1:~> commit Transaction 1 committed ``` **Выключение сервера через CLI** Для того чтобы выключить сервер через CLI, используйте команду `shutdown` введя её в `clif`: ```sh futriix:~> halt Server shutdown initiated ```

(К началу)

## Репликация 1. Включите репликацию в конфигурационном файле `futriix.config.toml`, установив enabled = true в секции [replication] в файле конфигурации `futriix.config.toml` ```sh [replication] enabled = false # Включена ли репликация peer_nodes = [] # Список узлов для репликации (например ["192.168.1.2:8080"]) sync_interval = 1000 # Интервал синхронизации в мс ``` 2. Откройте файл конфигурации `futriix.config.toml` в любом текстовом редакторе, например nano, если вы всё сделали правильно, он должен выглядеть так: ```sh $ nano futriix/futriix.conf.toml ``` ```sh [server] ip = "127.0.0.1" # IP-адрес сервера (0.0.0.0 для доступа из сети) port = 8080 # Порт для TCP-сервера log_path = "futriix.log" # Путь к лог-файлу [client] ip = "127.0.0.1" # IP для клиента (обычно localhost) port = 8080 # Порт клиента (должен совпадать с серверным) [replication] enabled = false # Включена ли репликация peer_nodes = [] # Список узлов для репликации (например ["192.168.1.2:8080"]) sync_interval = 1000 # Интервал синхронизации в мс [http_api] enabled = true # Включить HTTP API port = 8081 # Порт для HTTP API (обычно на 1 больше основного) ``` 4. Сохраните внесённые вами изменения, после чего репликация будет доступна в субд, выйдите из редактора, воспользовавшись командами ниже: ```sh $ ctrl+O $ ctrl+x ``` 5. Также для включения репликации вы можете использовать команду в `futriix-cli`: ```sh futriix:~> replication on ``` Сервер автоматически начнёт синхронизацию с указанными пирами (peer_nodes) с заданным интервалом (sync_interval). После включения сервер будет периодически отправлять команды из истории (command_history) на все пиры для поддержания согласованности данных. ### Команды для управления репликацией В проекте добавлены следующие команды для управления репликацией: ```sh replication on — включить репликацию replication off — выключить репликацию replication status — получить статус репликации (включена/выключена, список пиров, время последней синхронизации) replication add-peer — добавить пир для репликации (например, replication add-peer 127.0.0.1:8081) replication remove-peer — удалить пир из списка репликации ``` ## Резервное копирование Для создания и восстановления из бекапа используются команды futload (восстановление из бэкапа) и futunload (создание бэкапа). Вот примеры использования команд futload (восстановление из бэкапа) и futunload (создание бэкапа) в Futriix CLI: futunload - Создание бэкапа ```sh futunload <путь_к_файлу_бэкапа> ``` Пример 1: Создать бэкап в текущей директории ```sh futunload ./backups/snapshot_2025.fut Вывод при успехе: text Backup created successfully at ./backups/snapshot_2025.fut ``` Пример 2: Создать бэкап с абсолютным путём ```sh futunload /var/backups/futriix/db_export.fut ``` 2. futload - Восстановление из бэкапа Формат команды: bash ```sh futload <путь_к_файлу_бэкапа> ``` Пример 1: Восстановить из локального файла bash ```sh futload ./backups/snapshot_2025.fut Вывод при успехе: text Backup restored successfully from ./backups/snapshot_2024.fut ``` Пример 2: Восстановить из системного пути ```sh futload /mnt/backups/prod_db.fut ```

(К началу)

## HTTP API C помощью HTTP API можно быстро получить данные из субд по протоколу HTTPS, которые можно использовать в своём приложении, что называется "из коробки". Ниже приведены примеры для работы с HTTP API. > [!WARNING] > В данной реализации HTTP-API НЕ поддерживают аутентификацию и сложные операции (транзакции, репликация). Для использования сложых операций используйте TCP-клиент. Добавление данных: ```sh curl -X POST http://127.0.0.1:8081/api/insert \ -H "Content-Type: application/json" \ -d '{ "temperature": [1672531200000, 25.5], "humidity": [1672531200000, {"value": 60, "unit": "%"}] }' ``` **Ответ в случае успеха:** ```sh {"status": "ok"} ``` Получение данных: ```sh curl "http://127.0.0.1:8081/api/get/temperature/1672531200000/1672534800000" ``` **Ответ в случае успеха:** ```sh [ [1672531200000, 25.5], [1672531300000, 26.1] ] ``` Получение последнего значения: ```sh curl "http://127.0.0.1:8081/api/latest/temperature" ``` **Ответ в случае успеха:** ```sh [1672531300000, 26.1] ``` Удаление данных: ```sh curl -X DELETE "http://127.0.0.1:8081/api/delete/temperature/1672531200000/1672531300000" ``` **Ответ в случае успеха:** ```sh {"status": "ok"} ``` Пример Python-программы с использованием Http-API: ```sh import requests # Добавление данных requests.post("http://127.0.0.1:8081/api/insert", json={ "cpu_load": [1672531200000, 0.75] }) # Получение данных response = requests.get("http://127.0.0.1:8081/api/latest/cpu_load") print(response.json()) # [1672531200000, 0.75] ```

(К началу)

## Lua-скрипты > [!CAUTION] > **Поддержка работы lua в настоящий момент эксперементальная и может вызвать аварийное завершение сервера!!!** 1. Интерактивный режим работы, (выполнение скрипта в клиенте `futriix-cli`): ```sh futriix:~> futexec lua> return "Hello, " .. os.date("%Y-%m-%d") ``` 2. Выполнение файлов скриптов (c помоью команды в клиенте `SysExec`): ```sh futriix:~> sysexec my_script ```` 3. Доступ к данным из сервера Lua на примера lua-скрипта для чтение и записи данных из субд Скрипты имеют доступ к специальному API: ```sh -- read.lua -- Чтение данных local value = futriix.get("my_key") -- Запись данных futriix.put("temp_key", {data = "test", ts = os.time()}) -- Пример сложной логики for i = 1, 10 do futriix.put("counter/"..i, i*2) end ```

(К началу)

## Проблемы В данном разделе описаны типовые проблемы, возникающие при эксплуатации субд Futrix. 1. **Описание проблемы:** После запуска futriix, в лог-файле `futriix.log` дата указывается без указания текущего года: ```sh 11:29:49 [INFO] Futriix Server started successfully 11:29:49 [INFO] Listening on: 127.0.0.1:8080 ``` **Решение:** ```sh На данный момент это выявленный программный баг, нужно ждать выпуска новой версии. :-)) ```

(К началу)

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

(К началу)

## Вклад Вклады — это то, что делает сообщество открытого исходного кода таким замечательным местом для обучения, вдохновения и творчества. Любой ваш вклад **очень ценится**. Если у вас есть предложение, которое могло бы улучшить ситуацию, создайте форк репозитория и создайте запрос на включение. Также можно просто открыть задачу с тегом «улучшение». 1. Форкните проект 2. Создайте свою ветку функций (`git checkout -b Feature/AmazingFeature`) 3. Зафиксируйте свои изменения (git commit -m 'Add some AmazingFeature'`) 4. Отправьте в ветку (`git push main Feature/AmazingFeature`) 5. Откройте запрос на включение ## Контакты Григорий Сафронов - [E-mail](gvsafronov@yandex.ru) Ссылка на Интеллектуальный помощник - [FutBot](https://t.me/Futriix_bot)

(К началу)