Глава 6. Распределённые вычисления при помощи классов RADOS Ceph

Глава 6. Распределённые вычисления при помощи классов RADOS Ceph

Часто не распознанной до конца функциональностью Ceph является возможность загружать персональный код непосредственно в OSD, причём он затем может исполняться внутри некоторого приложения librados. Это делает для вас возможным получать преимущество от значительного распределённого масштаба Ceph не только для предоставления высокопроизводительного горизонтально масштабируемого хранения, но также для выполнения распределённых вычислительных задач поверх OSD для получения массивных параллельных вычислений. такая возможность реализуется путём динамической загрузки в классах RADOS на каждом OSD.

В данной главе мы изучим следующие темы:

Примеры приложений и преимущества применения классов RADOS

Написание некоторого простого класса RADOS в Lua

Написание некоторого класса RADOS, который эмулирует распределённое вычисление

Примеры приложений и преимущества использования классов RADOS

Как уже упоминалось ранее, применяя классы RADOS, код исполняется непосредственно внутри самого основного кода OSD и таким образом можно покорить мощность всех ваших узлов OSD. При обычном подходе клиентского приложения, при котором этому клиенту приходится считывать необходимый объект из имеющегося кластера Ceph для выполнения над ним вычислений, а затем записывать его обратно, имеется множество накладных расходов по передаче данных туда и обратно. Применение классов RADOS впечатляюще снижает обшее число перемещений данных с OSD и обратно, а также вся доступная вычислительная мощность намного выше, чем та, которую может предоставить отдельный клиент. Разгрузка операций напрямую в OSD, таким образом, позволяет некому отдельному клиенту впечатляюще увеличивать его скорости обработки.

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

Написание примера класса RADOS в Lua

Одним из имеющихся по умолчанию в Ceph классов Rados, начиная с выпуска Kraken и далее, является класс, который способен исполнять сценарии Lua. Сценарий Lua динамически передаётся в имеющийся класс объекта RADOS Lua, который затем исполняет всё содержимое данного сценария. Такие сценарии обычно передаются в формате строк JSON в имеющийся класс объекта. Хотя это и привносит преимущества над имеющимися обычно классами объектов RADOS, которые должны быть скомпилированы перед их применением, это также ограничивает доступную сложность того, что данные сценарии Lua могут выполнять и, следовательно, стоит обдумать какой метод подходит для той задачи, которую вы желаете выполнять.

Следующий код Python демонстрирует как создать и передать некий подлежащий исполнению в каком- то OSD сценарий Lua. Данный сценарий Lua считывает всё содержимое данного определённого объекта и возвращает данную строку текста обратно заглавными буквами, причём вся обработка выполняется в данном удалённом OSD, который содержит данный объект и никогда не отправляется самому клиенту.

Поместите приведённый ниже код в некий файл с названием rados_lua.py :

Теперь давайте создадим некий объект для проверки со всеми строчными символами:

По умолчанию имеющемуся классу объекта Lua не разрешается исполнение в OSD; нам необходимо добавить следующее во все свои OSD в их ceph.conf :

А теперь выполним наше приложение librados Python:

Предыдущая команда предоставит вам следующий вывод:

Рисунок 1

Вы должны увидеть, что весь текст из нашего объекта был преобразован в прописные буквы. Вы можете увидеть из приведённого ранее кода Python, что мы не делаем никакого преобразования в самом локальном коде Python и что всё выполняется удалённо в OSD.

Написание класса RADOS, который эмулирует распределённые вычисления

Как упоминалось в нашем приведённом ранее примере, хотя применение имеющегося класса объектов Lua снижает сложность использования класса объекта RADOS, имеется некое ограничение на то, что вы можете в настоящее время получить. Чтобы написать некий класс, который способен выполнять более продвинутую обработку, нам необходимо перейти на нижний уровень напсиания необходимого класса на C. Затем нам понадобится встроить этот новый класс в имеющийся исходный код Ceph.

Для демонстрации этой возможности мы напишем некий новый класс объекта RADOS, который будет вычислять хэш MD5 определённого имеющегося объекта и затем сохранять его в некотором атрибуте этого объекта. Данный процесс будет повторён 1000 раз для эмуляции некоторого занятого окружения, а также для более простого измерения времени исполнения. Затем мы сравним общую скорость обработки выполнения этого через данный класс объектов в сопоставлении с вычислением значения хэшей MD5 на самом клиенте. Хотя это всё ещё достаточно базовая задача, она также позволит нам воспроизвести некий управляемый повторяемый сценарий и позволит нам сопоставить общую скорость выполнения некоторой задачи клиентской стороны и прямого выполнения этого на имеющихся OSD при помощи класса RADOS. Это также послужит хорошей основой чтобы позволить понять как строить более продвинутые решения.

Подготовка к построению среды

Для клонирования имеющегося репозитория git Ceph воспользуйтесь следующей командой:

Предыдущая команда предоставит вам следующий вывод:

Рисунок 2

Когда у нас имеется клонированный репозиторий git Ceph, нам понадобится изменить его файл CMakeLists.txt и добавить раздел для нашего нового класса, который мы собираемся написать.

Измените следующий файл в дереве исходного кода:

Также поместите в этот файл следующее:

Когда файл CMakeLists.txt обновлён, мы можем взять cmake чтобы собрать необходимое построение среды выполнив приведённую ниже команду:

Предыдущая команда предоставит вам следующий вывод:

Рисунок 3

Это создаст некий каталог build в имеющемся дереве исходного кода.

Для того чтобы нам построить класс RADOS, нам необходимо установить все требующиеся пакеты, которые содержит данная команда make :

Также в нашем дереве исходного кода Ceph имеется некий файл install-deps.sh , который установит все остальные необходимые пакеты при своём исполнении.

Класс RADOS

приводимый ниже пример кода является неким классом RADOS, который при исполнении чтений определённого объекта вычисляет его хэш MD5 и затем записывает его в виде некоторого атрибута в сам объект без какого бы то ни было вовлечения клиента. Всякий раз, когда вызывается этот класс, он повторяет данную операцию 1000 раз локально для OSD и уведомляет своего клиента только по окончанию данной обработки. Нам предстоит выполнить следующие этапы:

Создадим для своего нового класса определённый каталог:

Теперь создадим необходимый исходный файл C++:

Поместим в него следующий код:

Перейдите в свой ранее созданный каталог build и создайте наш новый класс RADOS при помощи make :

Предыдущая команда предоставит вам следующий вывод:

Рисунок 4

Теперь нам нужно скопировать наш новый класс в OSD в своём кластере:

Предыдущая команда предоставит вам следующий вывод:

Рисунок 5

Также перезапустите все OSD чтобы они загрузили данный класс.

Вы теперь увидите в имеющемся журнале OSD что наш новый класс загружен:

Рисунок 6

Это необходимо повторить для всех узлов в данном кластере.

Клиентские приложения librados

Как уже упоминалось ранее, мы будем применять дав приложения librados, одно будет вычислять все хэши MD5 напрямую в нашем клиенте, а другое вызывать наш класс RADOS и заставлять его вычислять необходимый хэш MD5. Оба эти приложения необходимо исполнить из узла монитора в тестовом кластере, однако могут быть скомпилированы в любом узле и скопированы оттуда, если хотите. Для целей данного примера мы скомпилируем все приложения прямо в имеющихся узлах монитора.

Прежде чем мы приступим, давайте убедимся что построенная среда представлена в данном узле монитора:

Вычисление MD5 в самом клиенте

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

Создайте некий новый файл rados_md5.cc и поместите в него следующее:

Вычисление MD5 в OSD через класс RADOS

Наконец, самый последний пример кода является тем приложением librados, которое инструктирует OSD вычислять необходимый хэш MD5 локально без передачи каких- либо данных к- или от- данного клиента. Вы отметите, что данный представленный ниже код не имеет операторов чтения или записи librados и полностью полагается на имеющуюся функцию exec для включения создания необходимого хэша MD5.

Создайте некий новый файл rados_class_md5.cc и поместите в него следующее:

📎📎📎📎📎📎📎📎📎📎