Поделиться в Facebook Поделиться ВКонтакте Поделиться в LinkedIn Опубликовать в Twitter

Сеть Qnet

Распределенная среда ОС QNX Neutrino

В основе собственной сети ОС QNX Neutrino лежит протокол Qnet, который реализуется в виде сети сильносвязанных доверяемых (trusted) машин. Протокол Qnet позволяет этим машинам эффективно обмениваться ресурсами с минимальными накладными расходами. В сети Qnet можно пользоваться стандартными утилитами (cp, mv и т. д.) для управления файлами в любом месте сети, как если бы эти файлы находились на вашей собственной машине. Кроме того, протокол Qnet не выполняет аутентификацию удаленных запросов, так как файлы защищаются обычными правами доступа, применяемыми для пользователей и пользовательских групп. Можно не только иметь доступ к файлам, но и запускать или останавливать процессы (в том числе различные администраторы) на любой машине в сети Qnet.

Возможности распределенных вычислений в сети Qnet позволяют эффективно выполнять следующие задачи:

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

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

Для понимания механизма межзадачного взаимодействия в сети Qnet рассмотрим два процесса, которые должны взаимодействовать: клиентский процесс и серверный процесс (в данном случае процесс, реализующий работу администратора последовательного порта). В случае одного узла, клиент просто вызывает функции open(), read(), write() и т. д. Как будет рассмотрено далее, высокоуровневые POSIX-вызовы (как, например, open()) в действительности порождают ряд низкоуровневых вызовов ядра, управляющих обменом сообщениями (ConnectAttach(), MsgSend() и т. д.). Однако, для клиента все эти функции оказываются "под поверхностью" и ему нет необходимости заботиться о них — он просто вызывает open() и все.

 fd = open("/dev/ser1",Q_RDWR....);
/*Открыть последовательное устройство*/

Теперь рассмотрим случай простой сети с двумя машинами: на одной находится клиентский процесс, на другой — серверный (рис.1).

Простая сеть, в которой клиент и сервер находятся на разных машинах

Рис.1. Простая сеть, в которой клиент и сервер находятся на разных машинах

Программный код, необходимый для реализации клиент-серверного взаимодействия, идентичен тому, который используется в случае с одним узлом, за важным исключением: путевое имя. Путевое имя будет содержать префикс, задающий узел, на котором расположена данная служба (/dev/ser1). Как будет рассмотрено далее, этот префикс преобразуется в дескриптор узла, предназначенный для последующего низкоуровневого вызова ядра ConnectAttach(). Каждый узел в сети имеет свой дескриптор, который служит единственным признаком, по которому можно определить, как работает ОС — в сети или автономно.

Более подробно о дескрипторах узлов см. в главе о прозрачном распределенном сетевом взаимодействии по протоколу Qnet в электронном документе «QNX Neutrino Realtime Operation System. Programmer's Guide».

Разрешение имен и поиск

При запуске сети Qnet пространство путевых имен всех узлов данной сети добавляется к вашему узлу. Напомним, что путевое имя — это символьное имя, которое сообщает программе путь, по которому следует искать файл в иерархии каталогов, начинающейся с корневого каталога /.

Пространство имен путей на удаленных узлах отображается с префиксом /net (каталог, по умолчанию создаваемый администратором протокола Qnet lsm-qnet.so).

Например, удаленный узел node1 будет отображаться следующим образом:

 /net/node1/dev/socket
 /net/node1/dev/ser1
 /net/node1/home
 /net/node1/bin
 ....

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

Например, приведенный ранее пример с функцией open(). Если необходимо открыть последовательное устройство не на своей локальной машине, а на узле node1, нужно указать следующий путь:

 fd = open("/net/node1/dev/ser1",Q_RDWR...); 
 /*Открыть последовательное устройство на узле node1*/

Каким же образом клиент в архитектуре "клиент-сервер" может определить, какой дескриптор узла необходимо использовать для сервера?

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

Если дескриптор узлато сервер
0 (или ND_LOCAL_NODE)локальный (т. е. "данный узел")
ненулевойудаленный

Файловый дескриптор (идентификатор соединения)

В обоих случаях — локальная машина или сеть Qnet — практически это означает, что когда клиент присоединяется к серверу, он получает файловый дескриптор (или, в случае вызова ядра (например, ConnectAttach()), идентификатор соединения). Этот файловый дескриптор затем используется для всех последующих операций обмена сообщениями. Следует обратить внимание на то, что, с точки зрения клиента, файловый дескриптор идентичен как в случае локальной машины, так и в случае сети Qnet.

Сущность простой операции open()

Вернемся к примеру с функцией open(). Например, клиент на одном узле (lab1) должен использовать последовательный порт (/dev/ser1) на другом узле (lab2). В этом случае клиент выполняет функцию open() по следующему путевому имени:

 /net/lab2/dev/ser1

На рис. 2 показано, какие операции применяются, когда клиент выполняет функцию open() по путевому имени /net/lab2/dev/ser1.

Обмен сообщениями между клиентом и сервером по сети Qnet

Рис. 2. Обмен сообщениями между клиентом и сервером по сети Qnet

Последовательность операций

1. Клиент отправляет сообщение локальному администратору процессов с вопросом о разрешении путевого имени /net/lab2/dev/ser1.

Так как сетевой администратор lsm-net отвечает за все пространство имен /net, администратор процессов возвращает сообщение переадресации, в котором указывает, что клиент должен связаться с локальным администратором сети для получения нужной информации.

2. Клиент отправляет сообщение локальному администратору сети с тем же вопросом о разрешении путевого имени.

Локальный администратор сети отвечает сообщением переадресации с указанием дескриптора узла, идентификатора процесса и идентификатора канала администратора процессов узла lab2, таким образом пересылая запрос на разрешение имени пути на узел lab2.

3. Клиент создает соединение с администратором процессов узла lab2 и еще раз отправляет запрос на разрешение путевого имени.

Администратор процессов на узле lab2 возвращает еще одно сообщение переадресации, на этот раз с указанием дескриптора узла, идентификатора канала и идентификатора процесса драйвера последовательного порта на своем собственном узле.

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

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

Ключевая особенность, которую следует иметь в виду, здесь состоит в том, что клиент не знает о происходящих операциях — все они обрабатываются внутри POSIX-вызова open(). Клиент только выполняет функцию open() и получает файловый дескриптор (или сообщение об ошибке).

Замечание
При разрешении имени на каждом последующем шаге из запроса клиента удаляются те компоненты имени, которые были разрешены. Это происходит автомагически1 внутри администратора ресурсов. Таким образом, на шаге 2 в приведенном ранее описании запрос локальному сетевому администратору относится только к lab2/dev/ser1. На шаге 3 запрос относится только к dev/ser1, так как это все, что должен знать администратор ресурсов узла lab2. И, наконец, на шаге 4 запрос относится только к ser1, так как это все, что должен знать драйвер последовательного порта.

Служба глобальных имен

В приведенных примерах удаленные службы или файлы расположены на известных узлах или по известным именам путей. Например, последовательный порт узла lab1 находится по пути /net/lab1/dev/ser1. Служба глобальных имен (Global Name Service, GNS) позволяет определить местонахождение служб по их именам независимо от того, находятся ли они в локальной системе или на удаленном узле. Например, если необходимо обнаружить модем в сети, можно просто применить поиск по имени "модем". В результате вместо использования статичного пути, GNS-сервер будет искать службу с именем "модем". GNS-сервер можно конфигурировать таким образом, чтобы он обслуживал все или только часть узлов в сети Qnet. Кроме того, в сети может быть несколько GNS-серверов.

Именование сетевых ресурсов

Как упоминалось выше, префикс путевых имен /net используется администратором ресурсов lsm-qnet наиболее часто. При разрешении имен в сетевом пространстве путевых имен используются определенные термины.

  • Имя узла (node name) — последовательность символов, которая идентифицирует узел. Следует отметить, что имя узла не может содержать косых черт или точек. В приведенном ранее примере в качестве имени одного из узлов использовалось lab2. Имя по умолчанию можно получить с помощью функции confstr(), задав ей параметр _CS_HOSTNAME.
  • Домен узла (node domain) — последовательность символов, которую администратор ресурсов lsm-qnet "прикрепляет" к имени узла. Имя узла и домен узла вместе должны образовывать последовательность, уникальную для каждого узла. Имя домена по умолчанию можно получить с помощью функции confstr(), задав ей параметр _CS_DOMAIN.
  • Полностью определенное имя узла (fully qualified node name, FQNN) — последовательность символов, состоящая из имени узла и домена узла. Например, если имя узла lab2, а домен узла qnx.com, то полностью определенное имя узла (FQNN) будет lab2.qnx.com.
  • Сетевой каталог (network directory) — каталог в пространстве имен путей, организованном администратором ресурсов lsm-qnet. Каждый сетевой каталог (на узле их может быть множество) связан со своим доменом узла. Каталогом по умолчанию является /net (см. примеры в этой главе).
  • Разрешение имен (name resolution) — процесс, с помощью которого администратор ресурсов lsm-qnet преобразует FQNN в список адресов назначения, которые известны транспортному уровню.
  • Распознаватель имен (name resolver) — программный код, который реализует некоторый метод преобразования FQNN в список адресов назначения. Каждый сетевой каталог имеет список распознавателей имен, которые по очереди применяются для разрешения FQNN. По умолчанию используется ndp (см. следующий раздел).
  • Качество обслуживания (Quality of Service, QoS) — определение качества соединения между двумя узлами. По умолчанию используется политика качества обслуживания loadbalance (см. раздел о качестве обслуживания далее в этой главе).

Распознаватели

У сетевого администратора существуют три распознавателя (resolver).

  • en_ionet — рассылает широковещательные запросы по сети (схожим образом с протоколом TCP/IP ARP). Это распознаватель по умолчанию.
  • dns — этот распознаватель действует следующим образом: берет имя узла, добавляет точку (.) и следом домен узла и отправляет полученный результат функции gethostbyname() протокола TCP/IP.
  • file — предназначен для поиска доступных узлов (в том числе соответствующего сетевого адреса) в статическом файле.

Качество обслуживания (QoS) и резервированные соединения

Политика качества обслуживания (QoS) — это тот вопрос, который часто возникает в сетях высокой готовности, а также в системах управления реального времени. В сетях Qnet служба QoS по сути сводится к выбору среды передачи. В системе с несколькими сетевыми интерфейсами протокол Qnet выберет тот, который больше соответствует заданной политике качества обслуживания.

Замечание
Если в системе предусмотрен только один сетевой интерфейс, то служба QoS не применяется.

Политики качества обслуживания

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

  • loadbalance (по умолчанию) — протокол Qnet позволяет использовать любые доступные сетевые каналы связи и может распределять передачу данных между ними;
  • preferred — позволяет использовать только один канал связи и игнорировать все остальные сети (кроме случаев, когда выбранный канал оказывается недоступен);
  • exclusive — при этой политике качества обслуживания используется только заданный канал связи и игнорируются все остальные, даже если выбранный канал оказывается недоступен.

Для получения преимущества от использования QoS в Qnet, необходимо физически разделить сети. Например, рассмотрим сеть с двумя узлами и хабом, где каждый узел имеет два подключения к хабу:

Qnet и одна сеть

Рис. 3. Qnet и одна сеть

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

Теперь рассмотрим ту же самую сеть, но с двумя хабами:

Qnet и физически разделенные сети

Рис. 4. Qnet и физически разделенные сети

Если сети физически разделены и канал становится недоступен, Qnet автоматически переключается на другой канал, в зависимости от QoS, который выбран. Приложение не узнаёт, что первый канал не доступен. Можно указать опцию tx_retries модулю lsm-qnet.so, чтобы ограничить количество попыток при повторной передаче в Qnet, а значит контролировать, как долго Qnet будет ждать, чтобы решить, что канал недоступен. Следует учесть, что если количество попыток повторных передач слишком маленькое, то Qnet не будет допускать потери пакетов и может постоянно считать, что канал недоступен.

Далее политики QoS будут рассмотрены более подробно.

loadbalance

Протокол Qnet решает, какие каналы связи использовать для передачи пакетов данных в зависимости от текущей нагрузки и пропускной способности каналов, определенной сетевым администратором io-pkt*. Пакет данных ставится в очередь на передачу по тому каналу связи, который способен быстрее других доставить пакет до удаленной точки назначения. Такой порядок обеспечивает, во-первых, эффективную пропускную способность между узлами по рабочим каналам связи (а эта пропускная способность является суммой пропускных способностей по всем доступным каналам), а во-вторых, в случае сбоя каналов связи, — ограничение передачи данных оптимальным способом.

Если какой-то канал связи обрывается, протокол Qnet обеспечит переключение передачи на другой доступный канал. В первый раз такое переключение происходит в течение нескольких секунд, так как сетевой драйвер на неисправном канале связи сначала применяет таймаут, затем делает повторную попытку, а потом канал обрывается. После этого протокол Qnet уже "знает", что данный канал не работает, и поэтому не будет использовать его для передачи пользовательских данных. (Эта особенность является значительным улучшением в сравнении с QNX 4.) Пока протокол Qnet перераспределяет нагрузку между доступными каналами связи, он будет периодически отправлять служебные пакеты на неисправный канал для того, чтобы обнаружить его восстановление. Если канал связи восстанавливается, протокол Qnet вновь помещает его в список доступных каналов.

Замечание
Политика качества обслуживания loadbalance применяется по умолчанию.

preferred

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

Как только предпочтительный канал связи восстанавливается, протокол Qnet возвращается к этому каналу и снова использует только его, игнорируя все остальные до тех пор, пока предпочтительный канал не откажет опять.

exclusive

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

В каких случаях может понадобиться политика качества обслуживания exclusive? Например, имеется две сети. Одна из них работает быстрее другой, есть приложение, которое обменивается большими объемами данных. С помощью этой политики можно ограничить передачу только посредством быстрой сети для того, чтобы в случае ее сбоя избежать перегрузки более медленной сети.

Задание политик качества обслуживания

Политика качества обслуживания задается как часть путевого имени. Например, для того чтобы открыть доступ к /net/lab2/dev/ser1 с QoS-политикой exclusive, можно использовать следующее имя пути:

 /net/lab2~exclusive:en0/dev/ser1

QoS-параметр всегда начинается с символа тильды (~). Таким образом, в приведенном примере протоколу Qnet дается команда использовать исключительно интерфейс en0 даже в том случае, если он даст сбой.

Символьные ссылки

Для различных путевых имен с заданными QoS-политиками можно назначать символьные ссылки:

 ln -sP /net/lab2~preferred:en1 /remote/sql_server

Данная команда присвоит "абстрактное" имя /remote/sql_server узлу lab2 с QoS-политикой предпочтительного использования (preferred) канала en1.

Замечание
Именное пространство /net зарезервировано протоколом Qnet, поэтому в нем нельзя создавать символьные ссылки.

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

 rm /remote/sql_server
 ln -sP /net/lab1 /remote/sql_server

В результате служба будет переназначена с lab2 на lab1. Преимущество здесь состоит в том, что при написании приложений можно использовать абстрактные "имена служб" вместо точных имен узлов.

Примеры

Несколько примеров использования сетевого администратора.

Замечание
Сетевой администратор lsm-qnet ОС QNX Neutrino по сути представляет собой разделяемый объект, который инсталлируется в исполняемый модуль io-pkt*.

Локальные сети

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

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

Поскольку распознаватель ndp включается по умолчанию при запуске администратора сети lsm-qnet.so, можно просто задать, например, такие инструкции:

 ls /net/lab2/

Если в локальной сети пользователя есть машина с именем lab2, то после этой инструкции можно увидеть содержание корневого каталога этой машины.

Удаленные сети

Замечание
Для обеспечения безопасности сети необходимо установить межсетевой экран (firewall) перед выходом в Интернет. Более подробную информацию можно найти в документации на OpenBSD по адресу ftp://ftp3.usa.openbsd.org/pub/OpenBSD/doc/pf-faq.pdf.

Для разрешения удаленных имен протокол Qnet использует службу доменных имен (Domain Name System, DNS). Для включения DNS-службы при работе администратора сети lsm-qnet.so следует задать имя этого распознавателя в команде mount:

 mount -Tio-pkt -o"mount=:,resolve=dns,mount=.com:.net:.edu" 
 /lib/dll/lsm-qnet.so

В этом примере протокол Qnet будет использовать обе службы: как распознаватель en_ionet (заданный первой командой mount=), так и DNS-службу, предназначенную для разрешения удаленных имен.

Для разрешения удаленных имен протокол Qnet использует службу доменных имен (Domain Name System, DNS). Для включения DNS-службы при работе администратора сети npm-qnet.so следует задать имя этого распознавателя в команде mount:

 mount ‑Tio‑net ‑o"mount=:,resolve=dns,mount=.com:.net:.edu" 
 /lib/dll/npm-qnet.so

В этом примере протокол Qnet будет использовать обе службы: как распознаватель ndp (заданный первой командой mount=), так и DNS-службу, предназначенную для разрешения удаленных имен.

Необходимо отметить, что в этом примере было задано несколько типов доменных имен (mount=.com:.net:.edu) в качестве точек монтирования просто для того, чтобы сделать разрешение имен более надежным. Таким образом, при вводе, например, инструкции:

 ls /net/qnet.qnx.com/repository

будет выведено содержание каталога repository, расположенного на сайте qnet.qnx.com.

Специализированные драйверы устройств

В большинстве случаев можно использовать стандартные драйверы QNX для реализации сети Qnet в локальной сети или для инкапсуляции Qnet-сообщений по протоколу IP (TCP/IP) с тем, чтобы обеспечить маршрутизацию Qnet-пакетов на удаленные сети. Если необходимо создать между двумя процессорами сеть с высокой степенью связности с использованием высокоскоростной среды передачи данных (например, PCI или RapidIO).

Можно легко использовать подобную высокопроизводительную среду передачи, так как сетевой протокол Qnet может напрямую взаимодействовать с драйверами оборудования. В данном случае администратор io-pkt* отсутствует. Требуется только добавить в самом низу уровня Qnet небольшой модуль, который должен выполнять передачу и прием пакетов. Сделать это довольно просто благодаря стандартному внутреннему программному интерфейсу между остальной частью сети Qnet и добавленным к ее нижнему уровню модулю интерфейса драйвера.

Qnet поддерживает разные интерфейсы передачи и приема пакетов данных, поэтому добавление других интерфейсов может быть сделано довольно легко. Протокол Qnet имеет оригинальный транспортный механизм (называемый "L4"), который можно конфигурировать с учетом разных максимальных размеров передаваемого блока данных (Maximum Transmission Unit, MTU), применения (или не применения) пакетов уведомления (ACK) или CRC-кодов и так далее, что позволяет наиболее эффективным образом использовать возможности (например, гарантированную надежность) имеющейся среды передачи.

Также можно использовать комплект разработчика для платформы Qnet, который позволяет писать специализированные драйверы и/или модифицировать компоненты протокола Qnet в соответствии с требованиями конкретного приложения.


Задать вопрос on-line Обсудить на форуме Написать электронное письмо