Изменения

SockPQd - диспетчер очередей с приоритетами

631 байт добавлено, 12:42, 20 июня 2016
sockPQd — демон, управляющий множеством равноправных очередей с приоритетами и принимающий команды через TCP-сокеты. [{{SVN|vitaphoto/head/lib-sway/PQD/Daemon.pm}} PQD::Daemon] — головной модуль демона. Чтобы воспользоваться sockPQd, необходимо скачать модули [{{SVN|vitaphoto/head/lib-sway/PQD/}} PQD::xx], а также исполняемый файл [{{SVN|vitaphoto/head/bin-sway/pqd.pl}} pqd.pl]. Интерфейсом к sockPQd является библиотека [[SockPQd - Клиентский интерфейс PQD-Facade|PQD::Facade]].
== Описание ==
'''sockPQd очень гибок — гибок''' — вы поймёте это и сами после прочтения документации. По сути sockPQd является высокопроизводительным и надёжным диспетчером заданий. С помощью sockPQd вы превращаете свой сервер в клиента — доставку запросов (заданий) обеспечивает sockPQd. В основе распределения заданий лежит модель, представляющая из себя множество очередей с приоритетами.
'''sockPQd может служить «балансировщиком нагрузки» между очередями'''. sockPQd управляет множеством очередей с приоритетами. Каждая очередь имеет название, которое передаётся в запросах добавления и извлечения элементов из очереди вместе с приоритетом и данными задания. В случае выбора задания из произвольного очереди sockPQd выступает именно в роли «балансировщика нагрузки» между очередями, так как все очереди рассматриваются как равноправные, и задание выбирается из произвольной. Если же вы хотите реализовать целочисленные «приоритеты» очередей, чтобы средние количества выбранных из очередей заданий были им пропорциональны, просто используйте N очередей вместо одной, где N — приоритет очереди, и помещайте свои задания случайно в одну из них.
'''sockPQd не является ни многопоточным, ни многопроцессным демоном'''. Обслуживание всех клиентов осуществляется одним потоком, мультиплексирующим запросы
с помощью libevent и её Perl-биндингов {{CPAN|Event::Lib}}. Это ликвидирует необходимость в межпроцессном взаимодействии и синхронизации и позволяет sockPQd быть простым, а следовательно, надёжным. Кроме того, это же позволяет легко блокировать клиентов, просто откладывая на время ответ и предоставляя клиентской библиотеке осуществление блокировки вызывающего процесса или потока с помощью использования блокирующего ожидания входящих данных на сокете. Хотя, мультиплексирование имеет и недостаток: добавление и извлечение крупных заданий будут задерживать всех остальных клиентов. Следовательно, применяя sockPQd, нужно стараться использовать задания небольшого размера (до ~1450 байт, если помнить о том, что стандартное значение MTU (Maximum Transmission Unit — максимальный размер одного пакета) для протокола TCP/IP равно 1500 байтам). Но в любом случае, использование мелких заданий — хорошо, а больших — плохо, поэтому недостаток несущественный.
=== PUT — добавить задание в очередь ===
<pre>Запрос: PUT <q> <p> <длина_данных> [(IS <имя_элемента>|NEW) [WAIT <oq> [EXPIRE <сек> [THEN (DONE|LATER)]]]] <данные> Ответ: 200 OK Ответ: 200 OK IS <имя_элемента> Ответ: 206 Wait for output 200 OK <имя_очереди> <id_задания> <приоритет> <длина_данных> [IS <имя_элемента>] <данные> Ответ: 206 Wait for output IS <имя_элемента> 200 OK <имя_очереди> <id_задания> <приоритет> <длина_данных> [IS <имя_элемента>] <данные> Ответ: 500 Offline Mode</pre>
Действие:
В именованную очередь с именем <q> добавляется новое задание с приоритетом <nowiki><p></nowiki>. <Данные> задания сохраняются для последующей передачи исполнителям. Если в запросе передаётся <имя_элемента>, задание относится к элементу (подпоследовательности очереди) с именем <имя_элемента>. Имя очереди и имя элемента могут состоять из латинских букв, цифр и символа '_'. <nowiki><p></nowiki> — целое, возможно, отрицательное, число.
Если указать в запросе WAIT <oq>, sockPQd отдаст клиенту ответ 206 Wait for output, и будет ожидать появления задания, относящегося к элементу с именем <имя_элемента> в очереди с именем <oq>; когда такое задание станет доступно, оно сразу же будет отдано клиенту так же, как в ответе на GET-запрос. Если при этом в запросе было указано EXPIRE, то по прошествии <сек> секунд после отдачи задания оно будет поставлено в очередь заново или удалено, точно так же как и в команде GET, в зависимости от указания ключа -d при запуске sockPQd и указания в запросе THEN.
Второй тест представляет собой десятикратное измерение времени извлечения и «выполнения» (то есть, сообщения о выполнении задания в sockPQd) 40000 заданий из случайных очередей. Таким образом, на графике отражено время извлечения 40000 заданий при наличии в очередях суммарно 40000, 80000, и т. д., заданий.
 [[Изображение:sockPQd-pqb-put.png|thumb|300px|Слева — добавление Добавление заданий в очередь]][[Изображение:sockPQd-pqb-get.png|thumb|300px|Извлечение заданий, справа — извлечениеиз очереди]]
Таким образом, на рисунке мы видим, что:
Однако, как говорят нам и тесты, и здравый смысл, вместо реализации этого пути для дальнейшего масштабирования диспетчера гораздо проще модифицировать клиентские библиотеки и добавить в них возможность использования нескольких кластеров диспетчеров вместо одного. Чуть большая необходимость в распараллеливании очередей может появиться лишь при создании действительно огромных вычислительных кластеров… Хотя даже в этой ситуации присутствуют более простые пути решения проблемы.
 
== Ссылки ==
 
<references />
 
[[Категория:Архив]]
[[Категория:Perl]]