суббота, 27 декабря 2014 г.

22.3 ZeroMQ: надежные схемы "Запрос/Ответ". Надежность на основе прокси с очередью (шаблон "Простой пират")

  Запрос/Ответ. Надежность  на базе прокси с очередью (брокер с балансировкой нагрузки). Шаблон "Простой пират".

 Шаблон "Простой  Пират"

Расширим предыдущий шаблон обеспечения надежности типа "Ленивый пират", использовав прокси с очередями. Новый шаблон позволит общаться прозрачно с несколькими серверами, которые далее будем более точно называть "рабочими".

Во всех "пиратских"  шаблонах рабочие не сохраняют свое состояние. Разработка системы обмена сообщениями подразумевает, что мы ничего не знаем о том, что приложениям могут понадобится какие-либо разделяемые ресурсы, хранящие состояние, вроде баз данных. Использование прокси с очередями подразумевает, что рабочие могут приходить и уходить, не зная ничего о клиентах. Если падает один из рабочих, другой заменяет его. Это - хорошая, простая топология с одним слабым местом: а именно брокером с очередью в центре, который может стать проблемой для системы управления и единой точкой отказа.

четверг, 25 декабря 2014 г.

22.2 ZeroMQ: надежные схемы "Запрос/Ответ". Надежность на стороне клиента (шаблон "Ленивый пират")

  Запрос/Ответ. Надежность на стороне клиента. Шаблон "Ленивый пират".

 Шаблон "Ленивый  Пират"

 

 

Топология сети:




Небольшие изменения на стороне клиента позволяют получить надежную схему "Запрос-Ответ".
Вместо того, чтобы выполнять блокирующее чтение (receive) из сокета, поступаем иначе:

22.1 ZeroMQ: надежные схемы "Запрос/Ответ". Общие положения.

(Начало - здесь)

 Пора задуматься о надежности.


Будет рассмотрены повторяемые шаблоны, позволяющие добиться надежности при использовании схемы "Запрос-Ответ". Список шаблонов:
  • "Ленивый пират": надежная схема "запрос-ответ" на стороне клиента.
  • "Простой пират": надежная схема "запрос-ответ" с использованием балансировки нагрузки.
  • "Пират-параноик": надежная схема "запрос-ответ" с использованием хартбитинга.
  • "Мажордом": сервис - ориентированная надежная очередь.
  • "Титаник": диск-ориентированная надежная оффлайн очередь.
  • "Двоичная звезда": надежный отказоустойчивый бэкап - сервер.
  • "Фрилансер": надежная схема "запрос-ответ" без брокеров.

Что же такое - "Надежность"?

Ни о какой "теории надежности" речи не пойдет.

среда, 3 декабря 2014 г.

21.4 ZeroMQ: рабочий пример. Межброкерная маршрутизация. Вот что получилось.

(Начало - здесь).




Соберем все вместе.


Как и раньше, отдельный кластер будет представлен одним процессом.

Кода получилось довольно много, так как здесь объединяется логика обоих предыдущих примеров. Он достаточно хорошо имитирует кластеры, включающие клиентов и рабочих. 

Код:

21.3 ZeroMQ: рабочий пример. Межброкерная маршрутизация. Прототипирование локального и облачного потоков данных.


(Начало - здесь).

Прототипирование локального и облачного потоков.

Теперь займемся прототипированием потока данных локальных и облачных сокетов. Код будет тянуть запросы от клиентов и распределять их между локальными рабочими и облачными партнерами случайным образом.

Потоки данных задач:


Перед написанием кода (который все больше усложняется) обрисуем основы логики маршрутизации и разобьем её на простые, но надежные элементы.

21.2 ZeroMQ: рабочий пример. Межброкерная маршрутизация. Прототипирование потока данных о состоянии.


(Начало - здесь)

Прототипирование потока данных о состоянии


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

Код прототипа обработчика потока состояния:

пятница, 28 ноября 2014 г.

21.1 ZeroMQ: рабочий пример. Межброкерная маршрутизация. Разбор задачи.

(Начало - здесь).


Постановка задачи.

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

Нам эту задачу решить - как два байта переслать. 

Разберем задачу, используя ZeroMQ.

суббота, 15 ноября 2014 г.

20. ZeroMQ и Delphi: CZMQ, varargs и типы аргументов (zsock_bind(), zsock_connect(), zsock_send(), zsock_recv() и т.д.)


Использование функций с переменным числом аргументов.



В CZMQ появилось много методов с переменным число аргументов. В описании таких методов присутствует модификатор varargs: например:


function zsock_connect(p_self: p_zsock_t; format: PChar): Integer; varargs; 
  cdecl; external cZMQ_DllName;

или

function zsock_send(self: Pointer; picture: PChar): Integer; varargs; 
  cdecl; external cZMQ_DllName;


Как ими пользоваться?

вторник, 4 ноября 2014 г.

19. ZeroMQ: Асинхронный клиент-сервер.

(Начало - здесь).

Шаблон "Асинхронный клиент/сервер".

Будем создавать архитектуру сети N-1, когда несколько разных клиентов асинхронно общаются с одним сервером.

Работать это будет вот так:

- клиенты коннектятся к серверу и отправляют запросы;
- на каждый запрос сервер отправляет 0 или больше ответов;
- клиенты могут отправлять множество запросов без ожидания ответов;
- серверы могут отправлять множество ответов без ожидания новых запросов.

Топология:




18. ZeroMQ: реакторы CZMQ. ZLOOP.



(Начало - здесь).

Шаблон "Реактор".

<Теоория.>
Шаблон проектирования Реактор является событийно-управляемым шаблоном проектирования. Он предназначен для синхронной передачи запросов к сервису, поступающих параллельно от  одного или нескольких источников. Обработчик сервиса демультиплексирует  (разбирает) входящие запросы и  синхронно отправляет их ассоциированным обработчикам запросов.</Теория>

 Реактор напоминает процедуру окна Windows: разбирает поступившие сообщения и вызывает коллбеки, связанные с сообщениями.


Класс zloop - событийно-управляемый реактор.

понедельник, 3 ноября 2014 г.

17. ZeroMQ: брокер с балансировкой нагрузки + CZMQ. Обработка Ctrl+C в CZMQ. Реакторы.

(Начало - здесь).

Дальше рассмотрим кодирование брокера с балансировкой нагрузки с использованием API высокого уровня - CZMQ.

16. ZeroMQ: API высокого уровня. Библиотека CZMQ.

(Начало - здесь).

Наши примеры становятся все сложнее, код становится все более громозким и все менее располагает к пониманию.Вспомним, к примеру, последний вариант боркера с распределенной нагрузкой.

Громоздко, да. И это мы еще использовали наши вспомогательные процедуры вроде s_recv()/s_send(), а без них бы пришлось пересылать сообщения ZMQ и заниматься упаковкой-распоковкой данных.

В общем, если использовать низкуровневое API в сложных задачах, то и кодировать долго, и потом разбираться непросто.

Нужно переходить к более высоким уровням абстракции.
Например, для Delphi есть замечательная объектная библиотека: https://github.com/bvarga/delphizmq

Модуль zmqapi.pas предоставляет объектный интерфейс высокого уровня в соответствии видением прекрасного с создателя библиотеки и, надо полагать, в соответствии с задачами, которые стояли перед ним в момент написания.

К сожалению, больше года библиотека почти не обновляется, и зависла на поддержке ZeroMQ версий 2.* и 3.*.
~~~~~~~~~~~~

К счастью, выход есть: iMatrix (контора, которая и разрабатывает ZeroMQ) создала и развивает библиотеку API высокого уровня: http://czmq.zeromq.org/

15. ZeroMQ: реализация шаблона "Балансировка нагрузки".

(Начало здесь)

Шаблон "Балансировка Нагрузки"


Шаблон "Балансировка Нагрузки" чрезвычайно популярен. Он решает главную проблему, когда простые алгоритмы последовательной круговой(round robin) маршртизации (которые обеспечивают PUSH и DEALER) становятся неэффективными. Такое случается, когда для выполнения задач, решаемых рабочими процессами, требуется разное время.

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

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


14. ZeroMQ: Схема "Издатель - Подписчик", подробности, структура конверта.



Шаблон "Запрос - Ответ" - подробности.

Ранее несколько раз были немного упомянуты составные сообщения.
Использование составных сообщений дает возможность оформлять сообщения в форме "конвертов", когда адрес отделен от тела сообщения. Сообщения в SUB/PUB сокетах как раз пересылаются в таких конвертах. Наличие адресов позволяет легко организовать двусторонний обмен с помощью средств общего назначения - таких, как API ZMQ и прокси, которые на лету создают, читают и удаляют адреса, не затрагивая "полезные" данные.

В шаблоне "Запрос - Ответ" конверт содержит обратный адрес для ответа. Наличие обратного адреса позволяет получить ответ на запрос.

При использовании сокетов REQ и REP нет никакой нужды создавать конверты самостоятельно; это автоматически делают сами сокеты. 

Для понимания интересно разобрать, как такие конверты используются с сокетом ROUTER.

воскресенье, 2 ноября 2014 г.

13. ZeroMQ: универсальный решатель проблем или что делать, если сообщения теряются.

(Начало - здесь.)

Потери сообщений.


Сообщения атомарны, это хорошо. То есть, если вы что-то получаете - то получаете это полностью.
Плохо то, что если что-то теряется, то вы не получаете вообще ничего.

Далее - универсальный решатель проблем потерь сообщений.



12. ZeroMQ: высокая вода. High-Water Marks. Настройки пропускной способности сокетов.

(Начало - здесь.)




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

11. ZeroMQ: фильтрация входящих данных для схемы "Издатель - Подписчик" по первому кадру сообщения.


(Начало - здесь)

Вернемся к схеме "Издатель - Подписчик". (Приложение "Метеостанция").
Вспомним, что при подписке данные можно фильтровать.

Однако, фильтрация по самим данным не всегда удобна. Куда удобнее фильтровать по значению ключевого поля, связанному с данными.

10. ZeroMQ: нуль-копия (Zero-Copy).

(Начало - здесь)

Нуль - копия (Zero-Copy).


API ZeroMQ позволяет отправлять и принимать сообщения напрямую, используя буфера данных приложения, без копирования данных. Эта технология называется нуль - копия, её применение позволяет увеличить производительность в некоторых приложениях.

О нуль-копии следует вспоминать в случае, когда вы отправляете большие блоки памяти (тысячи байт) с высокой частотой.

Делаем нуль-копию. С помощью zmq_msg_init_data() создается сообщение, которое ссылается на уже существующий блок данных вашего приложения, которое затем передается в zmq_msg_send():

09. ZeroMQ: согласование работы между элементами сети.

(Начало здесь)

Согласование работы между узлами сети.

Если нужно согласовывать работы набора узлов в сети, то сокеты типа PAIR уже не так хороши.

Это как раз те области, где стратегии использования нитей и узлов различаются. В большинстве случаев узлы приходят и уходят "сами по себе", а нити обычно статичны. Сокеты типа PAIR не выполнят автоматическое переподключение, если удаленный узел сети уйдет, а потом появится снова. Другим существенным различием в применении узлов и применением нитей является то, что обычно мы имеем фиксированное число нитей , в то время как число рабочих узлов сети меняется.

Рассмотрим уже знакомый сценарий, реализующий схему "Запрос-Ответ" (с метостанцией - издателем и кучей клиентов-подписчиков) и попробуем координировать узлы так, чтобы быть уверенными в том, что при запуске подписчики-клиенты не потеряют данные.

08. ZeroMQ. Мультитрейдинг. Многонитевые приложения.

(Начало здесь).



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

Есть одно железное правило для успешного многонитевого кодинга - "не разделять между нитми изменяющиеся данные". Обычно, когда две нити в приложении пытаются между собой разделять данные, то это выглядит как будто два алкаша пытаются разделить пиво. И чем больше алкашей собирается за столом, тем хуже ситуация.
Большинство многонитевых приложений похоже на сборище пьяных алоголиков, учинивших драку в баре.

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

Для беспроблемного написания многонитевого кода с помощью ZeroMQ следует руководствоваться следующими правилами:

суббота, 1 ноября 2014 г.

07. ZeroMQ: обработка ошибок. ETERM.

(Начало здесь)

Обработка ошибок. ETERM.

Обработка ошибок ZeroMQ основана на двух положениях:
  1. Процессы уязвимы по отношению к внутреннем ошибкам.
  2. Внешние ошибки (и атаки) можно обработать (отразить атаки).

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

06. ZeroMQ: Проблема динамического обнаружения. Создание брокеров/прокси.

(Начало здесь)

Проблема динамического обнаружения


Вопрос сродни вот этому: Как получить список доступных MS SQL серверов?


Одной из проблем, возникающих при проектировании крупных распределенных систем является обнаружение сервисов. Частный случай проблемы - "как клиент узнает, к какому серверу нужно коннектиться?" А в общем случае - "как элементам сети найти друг друга?"

Особенно трудно в случае, когда разные элементы подключаются и отключаются, из разных узлов сети. Поэтому это называется "проблемой динамического обнаружения".

Эта проблема решается везде по-разному: используется служба DNS, или широковещательные сообщения (UDP) и т.п.

Есть несколько простых решений проблемы динамического обнаружения. Можно жестко закодировать адрес(ip + порт) (т,е., "конечную точку"). Вообще никаких проблем - и никакой гибкости. Впрочем, некоторой гибкости для tcp транспорта можно добавить с помощью службы DNS.
Можно конечную току задавать с помощью конфигурационных файлов (и т.д.). Главное - не забывать их вовремя обновлять .
Можно использовать специальный брокер адресации, который передаст вам нужные данные. Только вот адрес этого брокера должен быть известен...
Можно построить средство, исследующее окружение, сканирующее известные диапазоны адресов и порты. Или рассылающее (получающее) udp - пакеты об адресной информации.

05. ZeroMQ: поллинг. Опрашиваем готовность сразу нескольких сокетов. Метод zmq_poll().


Работа с несколькими сокетами ZMQ.

Во всех примерах, что мы рассмотрели ранее, схема работы была примерно одинаковой - в цикле повторялись одни те же действия:
    

    Ожидание сообщение из сокета
    Обработка сообщения.
    "Смыть, повторить."

Что делать, если нам нужно читать сообщения из нескольких конечных точек одновременно?
Самое простое - коннектить один сокет ко всем нужным конечным точкам и позволить, чтобы ZeroMQ втягивала нужные нам данные. Это допустимо, если все конечные точки настроены для работы по одному и тому же шаблону, но может быть и недопустмо, если, например, коннектить PULL - сокеты к конечной точке типа PUB.

Так вот, чтобы иметь возможность читать из множества сокетов сразу, следует использовать метод zmq_poll().

04. ZeroMQ: картинки из жизни сокетов и базовые сетевые топологии. Немного теории.

(Начало здесь).


Жизнь сокетов ZeroMQ состоит из четырех частей.

  1. Создание и уничтожение, которые должны идти парами: см zmq_socket (), zmq_close ().
  2. Настройка сокета: установить параметры сокета: zmq_setsockopt (), проверить настройки сокета: zmq_getsockopt ().
  3. Подключение сокета в топологию сети путем создания сходящего или исходящего ZeroMQ соединения: zmq_bind (), zmq_connect ().
  4. Использование сокета для передачи данных путем записи и приема сообщений в/из них: zmq_msg_send ()/ zmq_msg_recv ().

Сокеты в Delphi представлены просто указателями (Pointer).
А сообщения zmq_msg_t - структурой (массив длиной 48 байт):

zmq_msg_t = packed record
  _: Array[0..47] of Byte;
end; 

Подключение сокетов

Для создания соединения между двумя узлами на одном узле использует zmq_bind(), а на втором zmq_connect().
Принято считать, что узел, где используется zmq_bind() - это "сервер", который располагается в заранее известной точке сети (т.е., имеет фиксированный сетевой адрес). А узел, где используется zmq_connect() - "клиент", его сетевой адрес заранее неизвестен. Говорят "привязка" сокета ("биндинг") и подключение ("коннектинг"). То есть "привязываем" сокет к конкретной точке, и "подключаем" сокет к конкретной точке, "конкретная точка" - это известный сетевой адрес.

Соединения ZeroMQ отличаются от привычных соединений TCP:

пятница, 31 октября 2014 г.

03. ZeroMQ: "Параллельный трубопровод" (Parallel Pipeline). Задача для суперкомпьютеров.

Теперь попробуем разобраться с более удивительными вещами. (Начало здесь)



Рассмотрим топологию:


Процесс Ventilator - ставит задачи, которые будут решаться в параллельно выполняемых процессах Worker.
Процесс Worker - рабочий процесс, выполняющий поставленную задачу.
Процесс Sink - сборщик результатов от процессов Worker.

Считаем, что рабочие процессы типа Worker работают зверски быстро. Наверное, используя квантовые графические чипы с сигнальными процессорами, объединенными в нейронную сеть.

Практические задачи, которые в первую очередь приходят в голову:
- проверка натуральных чисел "на простоту";
- преобразование изображений к нужному формату;
- генерация биткоинов;
- ...

02. ZeroMQ: схема "Издатель - Подписчик" (Publisher-Subscriber).

Задача: (начало здесь)


Автоматическая метеостанция измеряет температуру, атмосферное давление и скорость ветра. Результаты измерений время от времени (например, после завершения цикла измерений) передаются "всем заинтересованным лицам".
Кого-то интересует всё, кому-то нужна температура, кого-то волнует только скорость ветра.




Пишем код метеостанции (), то есть, сервер-издатель.


Код сервера: 

00. ZeroMQ и Delphi. Файлы .pas для программирования. Файлы .dll для готового приложения.

Здесь можно скачать файлы, необходимые для создания и запуска приложений, использующих ZeroMQ.



Примечание:
1. При разработке рекомендуется использовать debug - версии библиотек. Однако, они не будут работать, если на компьютере не установлена соответствующая версия MS Visual Studio. То есть, такое приложение не запустится на компьютере без установленной MS VS нужной версии. Для распространения готовой программы следует использовать release - версию библиотек.
2. Для поставки пользователю готовой программы, следует также обеспечить инсталляцию рантайм библиотек MS VS соответствующей версии. Например: "Распространяемые пакеты Visual C++ для Visual Studio 2013".

1. Файлы .dll. Дата: 21.11.2014.

Версии: libzmq - 4.2.0.,  czmq - 3.0.1.
Компилятор: C++ MS VS 2013 CE Upd 4. Исполнение: в Windows XP и более новых.
Примечание: MS VS 2008 более не используется, т.к. czmq.dll  все равно в Win2K не будет работать: в ней используется отсутствующий в данной ОС метод API.
Ссылка для скачивания варианта Debug.
Ссылка для скачивания варианта Release.

Использование: распаковать в каталог, доступный приложению.
При разработке рекомендуется использовать debug - версии библиотек.

2. Файлы .pas. Дата: 28.03.2016.

Версии: zmq_h.pas - 1.0.1, czmq_h.pas - 1.0.1.
Изменен файл zmq_utils.pas.
Дата обновления – 28.03.2016. Использование: Delphi2007.
Ссылка для скачивания.
Использование: для компиляции приложения подключить к проекту.

PS: Не забываем, что для приложений, созданных в MS VS 2013, требуются "Распространяемые пакеты Visual C++ для Visual Studio 2013".

PS: Не забываем, что для приложений, созданных в MS VS 2013, требуются "Распространяемые пакеты Visual C++ для Visual Studio 2013".




01. ZeroMQ - "сокеты на стероидах"

ZeroMQ (ZMQ) - библиотека обмена сообщениями. 


Быстрая, компактная, удобная. Бесплатная.

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

ZMQ – кроссплатформенная библиотека. Реализована для множества операционных систем.
ZMQ написана на «чистом С». И именно "сишный" интерфейс  API позволил реализовать связь с ней практически из любого языка программировании. Ссылка на список: http://zeromq.org/bindings:_start

ZMQ - это не просто транспорт. Это - инструмент для создания сетевой архитектуры.
ZMQ позволяет в рамках одного приложения создать и отладить модель сложной сетевой архитектуры. Реализуется это очень просто: с помощью многонитевого приложения, когда отдельная нить имитирует отдельный процесс.
В ZMQ встроены средства буферизации сообщений. ZMQ, будучи реализована асинхронной, может работать как в синхронном, так и в асинхронном режиме.
У ZeroMQ пропускная способность выше, чем у TCP/IP, хотя ZeroMQ работает over TCP/IP...Поискал - "каким же образом?" ...нашел кое-какое описание, вроде специальной упаковки сообщений ZMQ в пакеты tcp.