Диссертация (1090660), страница 24
Текст из файла (страница 24)
Однако прежде чем сделать выбор в пользу данной технологии, был проведен ряд исследований. Для начала необходимо понять, каким комплексом технологий мы располагаем для решения поставленной задачи. К наиболеераспространенным технологиям межпроцессного взаимодействия относятся: канал,разделяемая память и сетевые сокеты.
Достоинство канала (англ. pipe) – в простоте реализации: достаточно осуществить его открытие и производить чтение и записьтак, как это происходит с обычными файлами. Другой способ – разделяемая память(англ. shared memory). К основному ее достоинству относится наивысшая быстротаобмена данными по сравнению с другими методиками. Тем не менее такое преимущество соседствует с серьезными недостатками: это и сложности в реализации, и низкаябезопасность, и отсутствие всякой кроссплатформенности.Сетевые сокеты (англ.
Network Sockets), на первый взгляд, являются наиболее громоздким способом организации межпроцессного взаимодействия. Но у этой технологии есть ряд значительных преимуществ. Во-первых, сокеты универсальны, чтодает возможность их использования на любых операционных системах – сохраняетсякроссплатформенность разрабатываемых решений. Во-вторых, сетевые сокеты могутиспользоваться не только внутри одной системы, но и взаимодействовать с другимисистемами удаленно, что позволит в будущем обеспечить горизонтальное масштабирование архитектуры.Тем не менее скорость обмена данными у сокетов одна из самых низких [61],поэтому при разработке возникло опасение, что связь между синхронизатором и интерпретатором будет образовывать «бутылочное горлышко» – уязвимое место в архитектуре, ограничивающее поток данных в системе.
Для проверки данного предположения было проведено нагрузочное тестирование, результаты которого показаны нарис. 4.10.4.4.5Разработка алгоритма сетевого взаимодействияСинхронизатор взаимодействует с интерпретатором через сокет, передавая в негоданные. Интерпретатор представляет собой специальное приложение, исполняемое всреде FastCGI, подчиненной, в свою очередь, Web-серверу. Среда FastCGI генерируетна основе логики конечный документ, а Web-сервер передает его в браузер клиента.141Многие архитектуры клиент-серверных приложений используют отдельный процесс, порождаемый системным вызовом fork() для обработки входящих подключений. Дочерний процесс обрабатывает подключение синхронно, шаг за шагом.
Подключение описанным способом блокирует исполнение остальной части программы[email]. Это означает, что процесс не завершится до тех пор,пока не будет разорвано подключение через сокет. К достоинствам такого подхода относится простота егореализации: нет необходимости введения дополнительных циклов и усложненных алгоритмических конструкций. Безусловно, это порождает недостаток, заключающийсяв невозможности использовать подобный способ организации сетевого взаимодействия на высоконагруженных системах: поскольку на одно подключение выделяетсяодин системный процесс, лимит на количество порождаемых процессов в системе сбольшим числом клиентов быстро исчерпается, поэтому часть из них будет находиться в режиме ожидания.
В то же самое время использование неблокирующих сокетовпозволит обслужить множество клиентов, используя лишь один системный процесс[117]. Тем не менее данная технология имеет другой недостаток – более трудоемкаяпроцедура разработки, так как асинхронная природа неблокирующих сокетовтребуетболее детального алгоритмического описания.Динамическая платформа FastCGI, используемая в составе интерпретатора, обслуживающего клиентские запросы и исполняющего логику BML, имеет свои особенности. Вместо создания нового подключения на один процесс FastCGI создает несколькоперсистентных процессов, остающихся в памяти и ожидающих новые подключения.На рис. 4.11 показана общая схема сетевого взаимодействия FastCGI-процессов интерпретатора с синхронизатором. Особенность FastCGI, как уже было сказано, в том, чтоее порожденный процесс не завершается после обслуживания клиентского запроса, аостается в памяти и ожидает нового подключения [48].
Это позволяет синхронизатору в принципе не закрывать соединение, а продолжать работу, ожидая новую порциюданных, что, в свою очередь, еще больше снижает накладные расходы, так как нетребуется затрачивать системные ресурсы на установку очередного подключения.Конечно, подобная организация требует периодической отправки специализированного пакета от процесса FastCGI, в противном случае синхронизатор решит, чтоинтерпретатор завершил работу и закроет соединение с ним по истечении периодаожидания. Итак, основная задача синхронизатора, как было сказано в начале, – обеспечивать своевременную отправку актуальной информации о логических структурахBML интерпретатору, работающему с клиентами. То есть синхронизатор является своего рода сервером данных.
В методологии BlockSet в целом и языке BML в частности142существует разделение на модель и локации. Свойства, хранящиеся в модели, делятся на две группы: 1) отвечающие за глобальную архитектуру проекта (например, ублоков – тип данных, у наборов – отношения друг с другом); 2) свойства, устанавливаемые для локаций по умолчанию. Подобное деление обусловлено исключительноудобством разработчиков, использующих представленный язык. В локациях же значения свойств модели из второй группы будут полностью переопределены, а свойствапервой группы идентичны для всех локаций.
Особенность в том, что интерпретатор водин момент времени работает только с одной локацией, конечные свойства которойопределяются слиянием свойств этой локации и модели. Таким образом, с технической точки зрения не имеет никакого смысла делить на две сущности единое целое.Передачу данных инициирует интерпретатор (процесс FastCGI) при запросе клиента.Он запрашивает свойства локации, идентифицируемой по URI, передавая переменнуюокружения REQUEST_URI.
Синхронизатор просматривает список локаций, выбираетподходящую под запрошенный критерий и формирует новую структуру на основе модели и найденной локации. Структура кодируется в формат BSON (двоичный JSON)и передается интерпретатору.Как известно, JSON (англ. JavaScript Object Notation) представляет собой набор пар«ключ-значение», причем эти пары могут вкладываться друг в друга. Особенностьформата BSON в том, что те же самые данные могут быть представлены в двоичном виде. Выигрыш от использования такого подхода наблюдается во всех аспектах:объем данных сокращается, а работа с ними производится с максимальной производительностью, так как практически не затрачивается время на синтаксический анализ[9].Комплексное тестирование архитектуры, включающее клиента и синхронизатор,осуществлялось на рабочем сервере с процессором Intel Xeon E5640 с тактовой частотой 2,66 ГГц объемом ОЗУ 16 Гб и объемом жесткого диска 500 Гб.
Испытанияпроводились для различных величин пакетов, порядок которых выбирался согласнопримерному подсчету требуемого объема данных в реальном проекте, передаваемыхна один запрос одного клиента: от 128 байт до 10 Кб. В качестве основных точекотсчета было взято различное количество клиентов – от 10 до 500. Стоит также отметить, что соединение при окончании обработки каждого клиента не закрывалось засчет использования неблокирующих сокетов.Результаты испытаний показали, что наименьшее суммарное время обработки десяти клиентов при величине пакета 128 байт не превышает 1 микросекунды, в тоже время самый длительный цикл обработки пятисот клиентов при величине пакета14310 Кб занимает 107 мкс.
На графике видно, что передача малых порций данных от128 байт до 1 Кб занимает практически одинаковое количество времени, а со значительным возрастанием объема, время, при прочих равных, начинает увеличиваться.В рамках исследования были также проведены дополнительные испытания и сболее объемными пакетами данных вплоть до 5 Мб, не зафиксированные на графике.Тенденция роста отношения числа обрабатываемых клиентов ко времени обработкипрослеживается в виде квадратичной функции.Испытания для других методик межпроцессного взаимодействия не проводились,так как целью исследования производительности сокетов было выявить порядок величин затрачиваемого времени (микросекунды) на обработку всех поступивших запросов, а не показать самую быструю технологию. Ведь сервер общается с интерпретатором небольшими порциями данных, едва ли превышающих десяток килобайт.Исходя из этого, несмотря на то, что сокеты являются одной из самых медленных технологий межпроцессного взаимодействия, порядок величин затрачиваемоговремени является более чем умеренным в рамках поставленной задачи.
Более того,сетевые сокеты кроссплатформенны и позволяют осуществлять удаленное взаимодействие, что в будущем позволит горизонтально масштабировать архитектуру.4.4.6Разработка структуры базы данных и алгоритма ее перестроенияИмя набора ассоциируется с таблицей в базе данных, содержащей постфикс “$set”на конце.
Имя блока по аналогии ассоциируется с полем таблицы и имеет постфикс“$blk”. При необходимости структура базы данных перестраивается синхронизаторомнаряду со структурой исходных файлов.Структура БД должна загружаться синхронизатором при запуске процедуры проверки соответствия базы данных с исходным кодом BML путем исполнения соответствующего запроса к СУБД. После этого осуществляется анализ BML на предметналичия следующих факторов: добавление/переименование/удаление блока или набора, изменение типа блока.При изменении имени блока или набора появляется задача корректного перестроения базы данных без ущерба самим данным.
Возникает неопределенность при выборе модели поведения синхронизатора после переименования разработчиком блокаили набора в исходных файлах. Ведь с точки зрения алгоритма неясно, был ли действительно переименован объект или это совершенно новая сущность.144Для предотвращения таких неопределенностей предлагается у наборов и блоковиспользовать атрибут "oldname"(старое имя) внутри модели наряду со стандартныматрибутом name, обозначающим уникальное имя, по которому идентифицируется объект. Общий алгоритм описанного преобразования представлен на рис. 4.9, где показана обобщенная схема перестроения таблиц наборов и полей блоков в базе данных.Здесь эти сущности объединены общим понятием «объект», а аналогичные сущностив понятиях синтаксиса BML – понятием «элемент».При удалении объекта и наличии в нем данных (экземпляров наборов или блоков) соответствующее поле или таблица не удаляются физически из базы данных, апереименовываются, добавляя к своему имени постфикс “$deleted”.