Назначение системы: добавление, изменение, удаление данных трактовочной сети
Система состоит из:
- базы данных (непосредственно хранилища)
- графический интерфейс для работы с базой
Масштабируемость
Мы заранее не знаем какое количество пользователей будет работать с базой. Если мы ставим задачу "максимум", то рассчитывать следует на миллиарды пользователей. Однако, если мы будем проектировать базу сразу же на миллиард (например, как у facebook), то нам потребуется такая же как у facebook инфраструктура и разработчики, которыми разумеется мы не обладаем. Соответственно, мы должны заложить такую архитектуру, которая позволит наращивать вычислительные мощности по мере включения в работу с сервисом новых пользователей.
Распределённость
Учитывая характер наших планов, мы не можем опереться на какой-либо один сервер или компанию-хостинг-провайдера. Это сделает нашу систему уязвимой от произвола отдельного администратора или нашего финансирования. Поэтому база должна храниться на множестве компьютеров. Удовлетворение этого требования пересекается с требованием масштабируемости. Каждый новый участник сервиса должен взять на себя часть хранимой в базе информации и обеспечить её доступность для других участников, а также содействовать функционированию сервиса, помогать связывать других участников распределённой сети (т.е. предоставлять не только место на жёстком диске, но и процессорное время с трафиком). В сервисе должна учитываться активность участников и вознаграждаться.
Гибкость и универсальность
Мы заранее знаем, что при пользовании сервисом будут использоваться все типы данных, поэтому архитектура базы данных должна быть сервисно-ориентированной. Известно, что отдельные базы данных наиболее эффективно решают вопросы обработки определённых типов данных (большие бинарные данные, графы, таблицы, документы), что выделяет эти базы данных в семейства. Сервис должен представлять набор интерефейсов для использования любых семейств баз данных. Т.е. хранилище не может представлять из себя только одну СУБД, а должно быть составным, что накладывает определённые требования на архитектуру касаемо связности этих баз.
Кроссплатформенность
Приложение, в котором будет реализован интерфейс пользователя, должно разрабатываться с помощью кроссплатформенных библиотек (например, Qt, WxWidgets) и иметь версии для win, unix, macos операционных систем. Требованиям кроссплатформенности удовлетворяют также и веб-сервисы, построенные на базе протокола http(версии 2, бинарный). Традиционные веб-сервисы тоже могут выступать в качестве кроссплатформенных клиентов (браузера), однако имеют ограничения при работе с бинарными данными(файлами).
Ориентированность на структуру таблиц трактовочной сети
Графический интерфейс должен поддерживать базовые структуры трактовочной сети (все типы таблиц - спиральная, многогранниковая, хронологическая, заглавный классификатор или кругозор). Пользователь должен обладать инструментарием для создания, редактирования и удаления объектов в таблицах). Пользователь по-умолчанию располагает локальной копией Суз-Даля, которую может менять по собственному усмотрению. При желании, пользователь может сопоставить собственную версию с версией другого пользователя и осуществить слияние версий. (см. п.5 Коллективное управление данными)
Поддержка всех форматов данных (синтаксисов)
Сервис позволяет просматривать данные тех, или иных пользователей в соответствии с требуемым типом синтаксиса:
- речевой – текстовые форматы, аудиофайлы (и голос, и музыка), часть математики (алгебра и арифметика);
- образный – изображения, видео (с оговорками)
- поминающий – синтаксис смысловых переходов (оглавление, адресация, ссылки, структуры баз данных);
- переключающий – переключение между синтаксисами (конвертация и комбинирование); взаимосвязка при комбинировании, сценарий последовательностей разных синтаксисов;
- обрядовый – сетевое взаимодействие (коллективные права доступа);
- двигательный – управляющие сигналы (печать на принтер или 3-Д принтер).
Интерфейс должен позволять выключить тот или иной синтаксис в представлении. Графический интерфейс тоже является частью базы данных и может быть модифицирован/обновлён. Он содержит в себе инструментарий для создания запросов к базе данных. Заранее мы не может предусмотреть какие данные понадобятся пользователю, поэтому требуется обеспечить пользователя средством создания и редактирования запросов в соответствии с классификацией поминающего синтаксиса.
Чтобы обеспечить совместимость с другими open-source приложениями и тем самым сократить трудозатраты на ранней стадии проекта (в случае релизации web-интерфейса) предлагается использовать распространённый на данный момент стандарт Internet Media Types (MIME). Базовые mime-типы: application, audio, example, image, message, model, multipart, text, video. В дальнейшем классифицировать все mime-типы по базовым синтаксисам.
Простота в наполнении базы содержимым
С целью сделать наполнение базы данных делом простым и увлекательным предлагается создание инструмента добавления того или иного файла по ссылке (URL) для того, чтобы не сохранять предварительно файл на диск. Пользователь вводит в поле ссылку на файл и указывает куда необходимо поместить данный файл в структуре Суз-Даля (или же в нужной ячейке или ряду должна быть опция добавить туда файл). В перспективе оснастить сервис возможностью работать с выдачей поисковой системы, когда пользователь вводит ключевое слово, получает выдачу поисковой системы и выбирает какие данные нужно добавить, а какие не стоит.
Обеспечение коллективного управления данными:
- поиск других версий хранилища в сети интернет (любое изменение файлов и папок – это новая версия)
- просмотр других версий хранилища и сопоставление их со своей версией
- слияние хранилищ между собой (создание потомка из двух родителей)
- ведение истории изменений/слияний (генеалогическое древо версий)
- общение с другими разработчиками трактовочной сети (чат)
В ходе поиска решений, удовлетворяющим данным требования, была найдена Межпланетная Файловая система(IPFS), которая имеет:
- встроенные средства контроля версий (Git) - каждое изменение содержимого файла приводит к изменению адреса, по которому данный файл находится. Меняется и адрес репозитория, если файл входит в него. Пользователи будут буквально вынуждены версионировать свои хранилища и приучаться к культуре коллективной разработки.
- механизм поиска других узлов сети (распределённая хэш-таблица адресов DSHT) – предоставляет алгоритм быстрого поиска данных; является оверлейной сетью, т.е. обеспечивает маршрутизацию поверх TCP/IP-уровня OSI.
- p2p-протокол обмена данными (Bitswap) – позволяет обмениваться данными друг с другом, не прибегая к помощи хостинг-провайдеров; протокол имеет встроенные средства поощрения узлов, принимающих участие в раздаче файлов(в bittorrent такого нет).
- дескопный клиент go-ipfs (управляемый через интерфейс командной строки или http-api) и js-ipfs-api библиотеку для создания веб-интерфейса; всё open-source. Т.е. имеются возможности реализации как веб-решения, так и создание своего дескторного приложения графического интерфейса.
- сообщество разработчиков, которое уделяет особое внимание именно протоколам (организация называется “Protocol Labs”), а не реализующим эти протоколы приложениям; тщательно документирует свои решения. Таким образом разработчик располагает документацией для собственной реализации протокола. Ответвлениями от IPFS являются стандарты multiformats, ipld, filecoin.
- возможности для построения различных типов хранилищ (реляционных, KV, графовых, столбцовых, блокчейн) поверх себя; именно поэтому назывывается файловой системой, а не распределённой базой данных. Протокол IPLD уже поддерживает интеграцию с bitcoin, ethereum, git.
Этот список показывает, что IPFS(стек протоколов + приложения) полностью удовлетворяет заявленным в начале документа требованиям к системе: распределённости, маштабируемости, версионируемости, кроссплатформенности, гибкости. Текущая реализация ipfs-клиента практически полностью закрывает на первом этапе наши потребности в системе управления хранилищем - для ввода в эксплуатацию первой версии клиента будет достаточно взять go-ipfs клиент и написать для него веб-интерфейс, который посредством http-api будет взаимодействовать с файловым хранилищем. В дальнейшем будет довольно просто из этой связки сделать десктоп-приложение, засунув веб-интерфейс и go-ipfs в единый инсталлятор с помощью electron.
Данные трактовочной сети:
- Древовидная иерархическая структура именованных папок;
- Ссылки на файлы внутри папок.
Т.е. трактовочная сеть де-факто представляет собой обычное файловое хранилище, интуитивно понятное любому пользователю компьютера.
Хранилище имеет следующую структуру папок:
этап/строение/уровень/спирогранник/спираль/таблица/строка/ячейка (полная структура папок описана в формате JSON – см.приложение A)
где:
- всего 6 этапов [0..5]
- каждый этап состоит от 1 до 6 строений (первый этап – 1 строение, шестой - 6);
- каждое строение состоит из 6 уровней [0..5];
- уровень состоит из (1 | 2 | 3 | 4 | 6) спирогранников;
- спирогранник состоит из 2 цветиков;
- цветик состоит из (4 | 6) таблиц;
- таблица состоит из (1-7) строк;
- строка состоит из (2-7) ячеек.
Например, к файлу, относящемуся к ячейке, можно будет обратиться по адресу:
/номер_этапа/номер_строения/номер_уровня/номер_спирогранника/номер_системы_таблиц/номер_таблицы/номер_строки/номер_ячейки/<имя_файла>
С точки зрения IPFS хранилище представляет из себя направленный ациклический граф, в котором узлами являются файлы, а связями идентификаторы ссылок. Папки являются ссылками (merkle-link) типа ключ:значение, где ключ – это номер папки, а значение - мультихэш вложенного в папку объекта. Запрашивая объект по адресу /имя_этапа/имя_строения/, мы получаем два набора ссылок - на вложенные в это строение уровни и на данные, относящиеся к этому строению.
Структура объекта:
{
"ссылки":
[
{
"хэш":"<ссылка>", // по ссылке находится объект с data:“Нервная система” и ссылками на вложенные объекты
"имя":"7x7",
"размер_содержимого": 6065
},
{
"хэш":"<ссылка>", // data:"Сердечно-сосудистая система"
"имя": "5x7”,
"размер_содержимого": 2516
},
{
"хэш":"<ссылка>", // data:"Пищеварительная система"
"имя": “5x5”,
"размер_содержимого":6065
}
],
"данные": “Анатомия позвоночного”
}
Количество данных в списке “данные” заранее неизвестно. Каждый участник трактовочной сети управляет этим содержимым по своему усмотрению. Структура папок хранилища согласована между участниками обмена.
В ходе работы над хранилищем пользователь добавляет данные(ipfs add) и закрепляет их на своём узле(ipfs pin). При добавлении данные кэшируются в служебном хранилище ipfs-клиента, после чего к ним может получить доступ другой пользователь(прочитав эти данные, другой пользователь автоматически становится раздающим, что предуматривает протокл bitswap). Если пользователь удаляет добавленные данные, то доступ к ним будет возможен пока в сети существуют другие узлы, хранящие эти данные в кэше. Если в сети не останется узлов, хранящих эти данные в кэше, то доступ к ним, рано или поздно станет невозможен из-за отсутствия источников. Чтобы обспечить постоянный доступ к данным, производится операция закрепления(ipfs pin).
Результатом операции добавления данных будет dag-объект следующего вида:
{"ссылка_на_файл":{"/":"<мультихэш>"}, "имя":"анатомия_человека.jpg", "размер":85543}
в этот спиcок могут быть добавлены другие поля по усмотрению пользователя. Этот объект будет добавлен к список “данные” того объекта, к которому мы хотим отнести эти данные.
Доступ других пользователей к вашей версии хранилища осуществляется через ключ /ipns/<хэш_вашего_узла>/<путь_к_хранилищу>, по которому в распределённой хэш-таблице (DHT) находится мультихэш этого хранилища. Операцией ipfs name publish через интерфейс командной строки или аналогично через http-запрос к ipfs-api, пользователь меняет значение мультихэша (по которому адресуется всё содержимое вашего хранилища) по вашему адресу. Возможно создание адресов большего уровня вложенности – например, /ipns/<хэш_вашего_узла>/суздаль/версия0/.
Для того, чтобы получить данные по известному адресу, необходимо сделать запрос к ipfs-http-api (по умолчанию на http://localhost:5001/api/v0/): вида http://localhost:5001/api/v0/object/data?arg=<хэш_объекта>. Команда object/data запрашивает бинарные данные, содержащиеся в объекте по ключу data (см. Структура объекта). Object – это частный случай dag, имеющий как раз эту структуру. Чтобы пользоваться командами, встроенными в go-ipfs клиент текущей версии, входящий в дистрибутив ipfs-desktop, предлагается соблюдать данный формат.
Создание поисковых роботов для поиска и индексации хранилищ во всей сети IPFS выходит за рамки данного технического задания. В этой версии пользователя будут узнавать друг о друге через другие каналы связи – например, мессенджеры (каковые могут базироваться тоже на IPFS - см. orbit-chat). По мере роста числа участников данная задача станет более актуальной.
Хранилища сравниваются с помощью команды ipfs/object/diff. Данный способ имеет свои недостатки – у двух объектов с одинаковой структурой ссылок и файлами, но с разными данных в поле data, хэши будут отличаться, однако object/diff покажет отсутствие изменений. Т.е. ipfs/object/diff сравнивает объекты по ссылкам.
Пользователь скачивает ipfs-desktop, устанавливает, запускает узел, загружает папку с каркасом суздаля в ipfs(или заходит по ссылке, скачивая тем самым пустое хранилище? А закрепляет его только после внесения изменений?), копирует её хэш и закрепляет (по желанию); каркас суздаля содержит json-схему хранилища без данных и индексный html-файл для запуска веб-интерфейса; переходит по адресу /ipfs/хэш_хранилища в браузере, автоматически загружается index.html. В index.html содержится структура папок в виде классического навигационного меню:
имя_этапа > имя_строения > имя_уровня > спирогранник > имя_системы_таблиц > имя_таблицы (примечание - строки и тем более ячейки, число которых может достигать 137 шт. не предполагается открывать через навигационное меню, чтобы не усложнять его)
при наведении курсором на этап отображается список этапов, на строение - перечень строений и так до уровня вложенности таблиц; при нажатии кнопкой мыши на любой из пунктов навигационного меню отображается соответствующая таблица; в зависимости от уровня вложенности представление будет меняться - т.е. при открытии зеленого сектора(таблицы) будет открываться таблица 7x7. Программа отображения будет определять тип отображения по количеству вложенных элементов (?) -
“1х3“ , { “название сектора”;
[ { 0, {"название ряда”; [ { 0, {"название ячейки”, {файл_ячейки}, ...} , {файл_ряда}, ...] } },
{ 1, {"название ряда”; [ { 0, {"название ячейки”, {файл_ячейки}, ...}, {файл_ряда}, ...] } },
{ 2, {"название ряда”; [ { 0, {"название ячейки”, {файл_ячейки}, ... }, {файл_ряда}, ...] } } ,
{файл_сектора}, ...]
}
Типы таблиц:
- 3х3 – красного цвета
- 3Х5 – фиолетового цвета
- 5х5 – синего цвета
- 5х7 – голубого цвета
- 7х7 – зелёного цвета
- Тетраэдрическая – 3 типа таблиц – 2х2, 2х3, 2х2
- Октаэдро-гексаэдрическая – 3 типа таблиц - 2х4, 3х4, 2х3
- Додекаэдро-икосаэдрическая – 3 типа таблиц - 5х4, 5х6, 4х3