Этот метод очень удобен с точки зрения прикладной программы, но требует большого количества накладных расходов по памяти на обеспечение окна, особенно при большом размере исходного и результатных пакетов. На этом уровне следует работать, если того требует специфика прикладной задачи (например, результаты расчетов используются при выдаче очередного пакета), либо если обеспечение произвольной выборки требует реализации дополнительных структур в программе, тогда, по сути, происходит реализация уровня произвольной выборки. Зная специфику прикладной задачи, можно организовать интерфейс к ней с помощью метода произвольной выборки более эффективно, чем в методе окна, который используется в нашей реализации.
4.2 Метод произвольной выборки
В методе произвольной выборки прикладная программа должна обеспечивать сквозную нумерацию заданий и быть готова в любой момент выдать задание с номером N из диапазона прикладной задачи. Результаты вычислений также могут приходить в произвольном порядке, но гарантируется, что все результаты будут получены и только один раз. В этом методе не требуется хранить в окне заданий сам запрос и результат вычислений, хранятся только номера пакетов, которые сейчас находятся в процессе вычислений. Если возникает необходимость послать пакет другому вычислительному узлу (при истечении времени ожидания), то прикладная программа запрашивается еще раз и заново выдает задание. Полученный от вычислительного узла результат расчета сразу же отдается прикладной программе.
4.3 Архитектура центрального сервера для реализации методов последовательной и произвольной выборки
Для реализации двух методов разбиения исходной задачи блок связи с прикладной программой разбит на два независимых блока: один для связи в случае использования метода произвольной выборки, другой – для реализации метода последовательной выборки.
Напомним, что прикладная программа взаимодействует с сервером X-Com через один из 3-х интерфейсов: Java, C/C++, Files. В каждом из этих интерфейсов предусмотрены независимые блоки функций как для одного, так и для другого метода.
В блоке логики сервера есть два независимых модуля реализующие соответственно два методов разбиения исходной задачи. Помимо этих 2-х модулей в блоке логики сервера есть общая часть, которая отвечает за:
идентификацию узла
ведение базы данных (информация об узлах, вычислительных возможностях узлов, а также о статистике соединений)
проверку корректности результата
5. Точки взаимодействия прикладной программы с системой X-Com
Прикладная программа в нашей системе разбивается на две части: серверную и вычислительную.
Серверная часть прикладной программы управляет формированием заданий для расчета на узлах. Программа может быть реализована на любом средстве программирования, важно только, чтобы она удовлетворяла APIX-Com.
Вычислительная часть прикладной программы представляет собой основной расчетный модуль в системе, который может быть реализован на любом средстве программирования (возможно не соответствующем серверной части прикладной программы заданий), важно только, чтобы этот блок удовлетворял соответствующим API.
Отметим, что интерфейсы вычислительной части прикладной программы не связаны с интерфейсами взаимодействия для серверной части прикладной программы, более того они не используют методы последовательной и произвольной выборки (метод разбиения исходной задачи на блоки не влияет на расчет каждого блока).
6. Ход вычислений в системе X-Com
Для того чтобы лучше понять работу системы и ее связь с архитектурой рассмотрим ход вычислений на некоторой задаче.
Для простоты предположим, что задача допускает решение методом прямой выборки и используется простая архитектура с одним центральным сервером и несколькими узлами (без промежуточных северов).
Прикладная программа разбивается на два блока: серверный и клиентский. Серверный модуль, отвечает за выдачу заданий и по запросу выдает очередную порцию вычислений, либо сигнал о том, что все задания выданы, и он переходит в режим ожидания оставшихся ответов. Клиентский блок проводит расчет задания и выдает результат.
6.1 Разбиение исходной задачи на блоки и нумерация этих блоков
Исходная задача разбивается на блоки, так как применяется метод прямой выборки количество блоков известно и все блоки можно пронумеровать от 1 до N. В дальнейшем мы будем оперировать этими номерами для идентификации вычислительного блока.
6.2. Начальный момент времени и соединение узлов с сервером
В начальный момент времени сервер находится в состоянии ожидания запросов от вычислительных узлов. Пусть у нас есть некоторое количество вычислительных узлов, и все они запущены.
Каждый узел все время пока он функционирует, периодически посылает запросы “дай задание” на сервер. Если произошел сбой соединения, либо сервер еще не готов узел снова ожидает некоторое время и повторяет попытку.
6.3 Подключение и идентификация узла
Предположим, что некоторый вычислительный узел соединился с сервером. Первым о соединении узнает серверный коммуникационный блок. Он не реализует никакой логики, просто принимает запрос, разбирает его заголовки, и передает данные запроса в серверный блок логики.
Возможны четыре типа соединений:
“Дай задание” – первичный запрос результата;
“Получи результат - дай следующее задание” – возврат рассчитанного задания и запрос следующего. Этот запрос делается в одной сессии для оптимизации сетевого взаимодействия;
“Получи задание” – возврат рассчитанного задания и сообщение о завершении работы. Сообщение о завершении работы может произойти и без возврата результата, это важно, чтобы корректно определить на сервере статус вычислительного узла;
Сообщение о статусе расчета на данном узле. Это информационный тип запросов, который важен при длительных вычислениях, чтобы сервер “помнил” о существовании узла, такие запросы передаются напрямую в блок сбора статистике о ходе вычислений и прямо не влияют на ход вычислений.
Любой подключившийся узел в независимости от типа соединения проходит процедуру идентификации, где однозначно находится соответствующая ему запись в таблице узлов, либо, если это первое общение данного узла, заводится новая запись.
6.4 Первичный запрос задания
В начальный момент времени все узлы обращаются к серверу с запросом “дай задание”. Предположим, что некоторый узел установил соединения и прошел процедуру идентификации.
На блок логики сервера поступил запрос о выдаче новой порции вычислений, блок логики в свою очередь передал этот запрос через API прикладной программе, которая вернула порцию данных, необходимую для расчета. Серверная часть прикладной программы не знает, на каком узле будет производиться расчет, она просто выдает очередной блок данных по номеру, который генерирует блок логики сервера.
Затем задание на расчет через блок логики, серверный коммуникационный блок, клиентский коммуникационный блок попадает на узел.
6.5 Расчет задания на узле
Получив задание, узел запускает прикладную программу для расчета. По ходу расчета фоновый процесс блока логики узла периодически посылает информацию, что узел находится в состоянии вычисления полученной порции. Данный процесс необходим, чтобы для сложных по времени вычисления порций данных, сервер не посчитал узел выбывшим из вычислений.
Окончив расчет, узел посылает результат расчет на сервера. Для этого используется запрос “Получи результат - дай следующее задание”.
6.6 Получение сервером результатов вычислений
Пройдя серверный коммуникационный блок, процедуру идентификации, проверку корректности запрос через блок логики сервера передает прикладной программе результат вычислений.
После этого происходит запрос новой порции вычислений, с точки зрения прикладной программы он полностью аналогичен первичному запросу задания.
6.7 Окончание вычислений
Предположим, что в некоторый момент времени все задания для расчета уже розданы. Тогда очередной узел, при возврате результата своего расчета получит ответ от сервера “Нет заданий”, после чего он отключится и перейдет в режим первичного запроса заданий. По мере окончания вычислений все узлы вернут результаты порученных им расчетов, и сервер зафиксирует окончание вычислений.
6.8 Структуры данных сервера для хранения информации об узлах
В таблице приведена структура базы данных, которая ведется сервером во время вычислений. Эти данные используются для управления ходом вычисления, а также для сбора и отображения статистики о ходе вычислений.
Тип поля | Название поля | Описание |
Идентификация сессии: основной способ идентификации узла | ||
String | sId | Идентификатор сессии, необходим для однозначной идентификации узла, случайно генерируется при первом подключении узла сервером, передается на узел и фигурирует во всех остальных запросах данного узла |
Эти данные не влияют на ход вычислений, они используются только при подсчете статистики. | ||
String | gcCode | Код клиента задается пользователем на узле, используется при расчете статистики. Может быть не уникальным, тогда в статистике все узла с данным кодом будут суммироваться. |
StringString | ClusterNode | Код клиента обычно состоит из двух частей: имени кластера и имени узла. Данное деление достаточно условно и необходимо только для более удобного сбора и отображения статистики. Если данное деление не используется код кластера остается пустым. |
Double | MHz | Частота процессора на узле. |
String | IP | Последний IP адрес, с которого происходил запрос от данного узла (он может изменяться в случае коммутируемого соединения). |
String | OS | Операционная система узла. |
Данные о ходе вычислений | ||
Double | Last_access_perf | Производительность последнего расчета на данном узле. В начальный момент времени содержит -1. |
Long | Last_access_time | Время последнего расчета на данном узле. В начальный момент времени содержит -1. |
Boolean | IsActive | Флаг активности клиента, если сервер считает, что данный узел выбыл из вычислений, флаг устанавливается в значение “Ложь”. После любого соединения от узла принимает значение “Истина”. |
Long | Portion | Номер порции, которую в данный момент вычисляет узел. Если узел не получил данных для расчета содержит -1. |
Long | Portion_time | Стартовый период времени, в который была передана последняя порция для расчета данным узлом. Если узел не получил данных для расчета содержит -1. |
6.9 Перераспределение заданий в методе произвольной выборки