Библиографическое описание:

Бурмистров В. Д., Заковряшин Е. М. Создание хранилища данных для распределённой системы // Молодой ученый. — 2016. — №12. — С. 143-147.



В данной работе рассматривается реализация модуля хранения данных в распределённой системе, решающей задачи хранения и анализа файлов, содержащих данные в виде текста. Задачами модуля являются размещение файлов, а также управление загруженными файлами. Модуль реализован на языке программирования Java с использованием технологии OpenstackSwift.

Ключевыеслова: хранилище данных, объектное хранилище, распределённые системы, OpenstackSwift, документация

В настоящее время происходит переход от традиционного способа хранения и обработки данных к цифровому. В конце прошлого столетия были предложены концепции «облачных» проектов, реализующих модель приложений, при которых обработка информации осуществлялась бы не на компьютере пользователя, а на удалённых серверах. В то время реализация такого рода проектов не представлялась возможной из-за отсутствия глобальной сети Интернет.

Сейчас «облачная» модель обработки данных является перспективной и быстроразвивающейся. В такой модели данные хранятся в распределённой системе на основе множества серверов, объединённых общей сетью. В пользу такой модели говорят следующие преимущества:

  1. Доступ может предоставляться любому устройству, имеющему подключение к сети Интернет;
  2. Сохранность данных в случае сбоя, отказоустойчивость;
  3. Неограниченная масштабируемость.

Зачастую, процесс обучения и другие области человеческой деятельности тесно связаны с работой с текстовыми материалами. В настоящее время большая часть этих материалов хранится в электронном виде и их число постоянно растёт. Потому актуальна проблема упорядоченного хранения большого объёма информационных ресурсов, содержащие текстовые данные.

Решение данной проблемы — это создание «облачного» программного продукта, реализующего функции систематизированного хранения файлов, содержащих текстовую информацию.

В данной работе рассматривается задача реализации одного из важнейших модулей распределённой системы — модуля размещения и управления размещёнными в системе файлами. То есть модуля, реализующего такие функции работы с файлами, как создание директорий, перемещение файла, переименование и прочие функции, аналогичные функциям файловых систем.

Инструмент разработки

В качестве инструмента разработки файлового хранилища был выбран проект OpenstackSwift. OpenStack — это open source проект по разработке платформы, позволяющей строить частные и публичные «облака». Технология включает в себя серию взаимосвязанных проектов, обеспечивающих разработку многочисленных составляющих инфраструктурного решения для «облака» [1].

Swift (OpenStack Object Storage) — распределённое объектное хранилище, главными особенностями которого являются высокий уровень надёжности и отказоустойчивости, а также лёгкая масштабируемость системы. Доступ к объектам в Swift осуществляется по интерфейсу REST с помощью базовых HTTP запросов.

Swift организован на базе четырёх основных компонент:

– Proxy Server (сервер, объединяющий остальные компоненты вместе). Отвечает за приём пользовательских запросов HTTP, производит поиск местоположение запрошенного объекта с помощью кольца;

– Object Server (непосредственно хранящий данные);

– Container Server (отдаёт список объектов в контейнере);

– Account Server (листинги контейнеров для конкретного аккаунта) Отслеживает имена контейнеров, принадлежащих определённому аккаунту.

При этом, путь доступа к каждому из объектов хранения в Swift состоит из трёх компонент: аккаунт, контейнер, объект и выглядит следующим образом: AccountName/ContainerName/ObjectName. Под объектом хранения подразумевается хранящийся файл.

Как правило, хранилище данных, созданное с помощью Swift, имеет вид масштабного кластера, одна из машин которого выполняет роль прокси-сервера; некоторое количество машин — контейнер-серверы и аккаунтинг-серверы; остальные же — объектные серверы и их количество может исчисляться сотнями и более машин, в зависимости от нужд потребителя [4].

Отдельно стоит упомянуть структуру данных, используемую Swift для поиска положения данных в системе — «кольцо» (ring). По сути, кольцо является базой данных, описывающей местоположение объектов. При любом действии, связанном с записью или удалением данных в хранилище, а также выходе из строя узлов хранилища, кольцо изменяется.

Важнейшим элементом абсолютно любого хранилища являются объектные серверы, выполняющие функции размещения и отдачи файлов. Объектный сервер — это хранилище BLOB-объектов (большой двоичный объект). Каждый объект хранилища оказывается на жёстком диске объектного сервера и хранится на нём в двоичных файлах, сопровождаемых метаданными, которые, в свою очередь, хранятся в расширенных атрибутах файлов (xattr). Swift обеспечивает надёжное хранение данных, благодаря их репликации сразу в несколько серверов. Таким образом, в случае утери данных с одного из серверов при его отказе, система восстановит данные с другого сервера и снова создаст копию [2].

Реализация поставленной задачи

Для реализации требуемого модуля программного продукта, необходимо реализовать элементы MVC-модели приложения на языке программирования Java. Для этого используется фреймворк Spring, предоставляющий архитектурный каркас для реализации следующих компонентов системы:

– Классы модели представления, получаемые при получении запроса от пользователя и формировании ответа на него;

– Контроллеры, обрабатывающие объекты, представляющие пользовательский запрос, передавая их в соответствующие сервисы;

– Сервисы, реализующие типовые функции, используемые контроллером или другими сервисами.

Кроме того, используется библиотека-провайдер Apache jclouds, обеспечивающая доступ к функциям, предоставляемым облачными средствами, в том числе Swift API [3], позволяющий управлять аккаунтами, контейнерами и объектами в системе объектного хранения.

Таким образом, для решения поставленных задач, связанных с хранением файлов, нужно создать классы, описывающие сущности необходимые для выполнения заданных функций, таких как местоположение файла, его атрибуты, а также, на основе этих классов, сервисы и контроллеры, которые в свою очередь реализуют непосредственно логику осуществления функции и их выполнение посредством обращения к API.

На рисунке 1 продемонстрирована схема взаимодействия данных элементов системы.

Рис. 1. Взаимодействие элементов модуля хранения

Как видно из диаграммы, контроллер WarehouseController и сервис ObjectWarehouserService реализуют методы интерфейса RemoteObjectWarehouser, используя классы модели сервера хранилища данных. Причём контроллер генерирует соответствующие запросу JSON-запросы, а сервис реализует логику исполнения этих запросов. Методами интерфейса RemoteObjectWarehouser описываются запросы для взаимодействия с объектами хранения и ответы на эти запросы.

На рисунке 2 представлена диаграмма классов для класса GetObjectByWarehousingLocationRequest, описывающего запрос обращения к объекту хранения. Для выборки хранящегося объекта необходимо установить его местоположение, кроме того, это объект может быть предназначен для публичного доступа, либо для личного, потому необходимо также установить является ли этот объект публично доступным. Эти два требования ясно видны из рисунка 2.

Рис. 2. Диаграмма для класса GetObjectByWarehousingLocationRequest

Ниже приведены краткие описания классов, отвечающих за запросы к объектам хранения:

– GetObjectByWarehousingLocationRequest — запрашивает объект хранения, использует для этого, как было написано ранее, местоположение объекта и данные о его публичности;

– PutObjectRequest — создаёт объект вместе с его метаданными в выбранном контейнере;

– PostObjectRequest — создаёт или обновляет метаданные объекта хранения;

– DeleteObjectRequest — удаляет выбранный объект;

– CopyObjectRequest — создаёт копию объекта в указанном местоположении;

– MoveObjectRequest — перемещает объект в указанное местоположение;

– ChangeObjectAttributesRequest — изменяет атрибуты выбранного объекта (имя, публичность доступа);

– PostObjectResponse — в ответ на произведённое действие возвращает результат в виде выбранного объекта и его обновлённых метаданных;

– GetObjectResponse — по аналогии с предыдущим, возвращает выбранный объект.

Механизм работы большинства из этих функций интуитивно понятен и почти продиктован названием. Swift API предоставляет почти аналогичные по названиям функции, которые реализуют «серверную» составляющую этих запросов, так, например, операция DELETE, с указанием местоположения и названия объекта, удаляет этот объект из контейнера.

Но в Swift не предусмотрены операции перемещения и переименовывания объекта, в привычном понимании. Такого функционала Swift API не предоставляет. Проблема реализации данных функций решается элементарно. Для перемещения файла необходимо совместить операции копирования объекта и его удаления, таким образом операция перемещения объекта легко исполняется с помощью последовательности тривиальных функций: копирование существующего объекта, размещение его в новом, указанном местоположении, удаление исходного объекта.

Аналогичным образом решается проблема переименовывания объекта. Для назначения объекту нового имени, необходимо сделать копию содержимого объекта, создать новый объект в этом же контейнере, но с новым именем, удалить исходный объект.

Следующая возникающая проблема связана со способом размещения объектов в Swift. Дело в том, что в отличии от привычных файловых систем, Swift не предусматривает создание директорий — контейнеры не могут быть вложены друг в друга, поэтому директорий, в привычном понимании, в Swift нет. Объектное хранилище Swift не может быть интерпретировано в смысле иерархической структуры, вместо этого оно может быть представлено псевдо-бесконечной картой «ключ-значение», где ключи — это строки, упорядоченные в алфавитном порядке, а значение — есть бинарные объекты.

Рис. 3. Представление хранимых объектов в ОС и в Swift

Взамен реального создания директорий, Swift предлагает механизм имитации директорий, то есть позволяет создавать псевдо-директории [4].

Как было указано ранее, доступ к объекту хранения в Swift осуществляется с помощью трёх компонент: аккаунта, контейнера и объекта. Запрос к хранимому объекту выглядит следующим образом: https://domain.name/{APIversion}/{accountname}/{containername}/{objectname}

Для создания псевдо-директории необходимо добавить символ «/» в имя объекта, к примеру, файл text.txt можно поместить в каталог texts путём добавления соответствующей строки в имя объекта: texts/text.txt. Таким образом, доступ к файлу text.txt будет осуществляться с помощью запроса https://domain.name/{API version}/{accountname}/{containername}/texts/text.txt. Фактическое местоположение объекта при этом — контейнер. Можно создать множество псевдо-директорий и даже «вкладывать» друг в друга, но фактическое место хранения при этом не изменится — все объекты располагаются внутри контейнера.

Для обращения к объектам, располагающимся «внутри» какой-либо директории при формировании запроса используется вспомогательные параметры «delimeter» и «prefix». Для примера, предположим, что в контейнере с названием container находятся объекты folder1/text1.txt и folder2/text2.txt, тогда для обращения к объекту text1 путь к объекту в запросе должен быть сформирован следующим образом:

{API version}/{accountname}/container?prefix=folder1/&delimeter=/. Соответственно, для получения данных о всех хранящихся в контейнере файлах следует формировать GET-запрос без вспомогательных параметров.

Псевдо-директории при этом не являются реальными объектами, Swift ссылается на реальный объект, название которого не заканчивается символом «/». Псевдо-директории не имеют типа содержимого, но каждая псевдо-директория имеет свою SUBDIR запись в JSON-ответе [4].

Таким образом, проблемы создания директории и перемещения файлов в директориях, а также изменения атрибутов директории, решаются изменением имени группы объектов. Решение задачи переименовывания было описано ранее. Перемещение и переименовывание целой директории осуществляется путём одновременного применения соответствующих операций к каждому объекту в директории.

Заключение

В ходе работы был реализован программный модуль, осуществляющий задачи хранения файлов в распределённой системе. Данный модуль предоставляет следующий функционал:

  1. Создание директории размещения файла;
  2. Изменение атрибутов созданной директории;
  3. Удаление директории и её содержимого с сервера;
  4. Копирование директории вместе с содержимым на сервере;
  5. Перемещение директории вместе с содержимым на сервере;
  6. Загрузка файла на сервер в выбранную директорию;
  7. Скачивание файла с сервера из выбранной директории;
  8. Удаление файлов;
  9. Изменение атрибутов файла (имя файла, флаг файла — публичный/частный);
  10. Перемещение файлов на сервере;
  11. Копирование файлов на сервере.

Реализация данного модуля предоставляет минимально необходимый для работы приложения, в данной проблемной области, функционал.

Литература:

  1. Кападиа Амар, Варма Средхар, Раджана Крис Реализация облачного хранилища с Openstack Swift. Packt Publishing, 2014. 140 с.
  2. Ротон Дж. Знакомство с OpenStack: Storage-компоненты Swift и Cinder — https://www.ibm.com/developerworks/ru/library/cl-openstack-swift-cinder/
  3. The Apache Software Foundation. Apache jclouds®:: User Guides — https://jclouds.apache.org/guides/
  4. The OpenStack Foundation. OpenStack Docs: Current — http://docs.openstack.org/index.html

Обсуждение

Социальные комментарии Cackle