LINUX.ORG.RU

пересылка сообщения по графу узлов в сети

 ,


1

2

Вот есть, допустим, такой граф узлов в сети, которые имеют возможность пересылать сообщения друг другу напрямую:

 A------C
 ║      |
 B------D
Связность узлов задает некий мастер-узел. В данном случае выставил вручную.

Узлы А и В находится в одной группе (потому что, например, находятся географически рядом), С и D для этой группы узлы удаленные. Узлы C и D единственные в своих группах.

Далее отправляется сообщение из узла В на все остальные узлы. Для этого сначала из В посылаем сообщение в А, как в близкий узел. Потом из В в D как в связанный с В «дальний» узел. В это время А получает сообщение от В с пометкой, что оно «широковещательное» и отсылает его в свой «дальний» узел, т.е. в С.

Теперь сообщение есть во всех узлах, но С и D этого не знают. Поэтому они отсылают сообщение дальше (C в D и А, D в В и С), получают ответ, что такое сообщение в этих узлах уже есть и прекращают пересылку. На этом все.

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

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



Последнее исправление: jcdr (всего исправлений: 2)

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

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

ya-betmen ★★★★★
()
Ответ на: комментарий от ya-betmen

Ну запили уникальный ид сообщения и дописывай шапку с именами пройденных узлов

Была такая мысль, но тогда к короткому сообщению «Hello» будет добавляться по N*4 байта «хвоста» (где N - число пройденных узлов, а 4 - длина уида узла).

jcdr
() автор топика
Ответ на: комментарий от jcdr

В условии ничего не было про оптимизацию размера сообщения.

Тогда давай оценку по толщине каналов, связанности, числу узлов и размерам пакетов.

ya-betmen ★★★★★
()
Ответ на: комментарий от ya-betmen
  • Максимальное число узлов - 1000
  • Среднее число узлов - 100
  • Размер пересылаемого сообщение в среднем - 512байт
  • Связность узлов произвольная и задается мастер-узлом, который знает IP адреса всех узлов и, например, их географичекие координаты.
  • Географически распределение узлов заранее неизвестно и может быть произвольным

Рассылку надо сделать за минимальное время и с минимальной нагрузкой на сеть (время важнее)

jcdr
() автор топика

дальше (C в D и А, D в В и С),

Я так понял они у тебя отправителям обратно отправляют. А зачем? И почему при получении копии просто ее не игронить, вместо ответа?

anonymous
()
Ответ на: комментарий от ya-betmen

Когда перестало ходить.

Я пока для себя решил так: у каждого узла и отсылаемого сообщения есть переменная «Логическое время».

Каждое новое сообщение должно быть ровно на 1 старше (по этому времени) логического времени каждого узла.

Если время сообщения <= времени узла, то оно никуда дальше не идет и вообще пропускается.

Если оно больше времени узла на 2 или более, то значит мы что-то пропустили и сначала ждем какое-то время, и запрашиваем «пропуски» у остальных, если не дождались.

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

Создавая новое сообщение, узел, с которого начинается «вещание», присваивает ему время на 1 больше своего.

jcdr
() автор топика
Ответ на: комментарий от jcdr

Создавая новое сообщение, узел, с которого начинается «вещание», присваивает ему время на 1 больше своего.

Так ты только одно сообщение хочешь разослать что ли?

ya-betmen ★★★★★
()
Ответ на: комментарий от ya-betmen

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

jcdr
() автор топика
Ответ на: комментарий от jcdr

Источник сообщения всегда один? Как ты определишь что сообщение доставлено и можно отправлять следующее?

ya-betmen ★★★★★
()
Ответ на: комментарий от anonymous

Я так понял они у тебя отправителям обратно отправляют. А зачем? И почему при получении копии просто ее не игронить, вместо ответа?

</thread>

ps: годный анон

unt1tled ★★★★
()
Ответ на: комментарий от ya-betmen

Источник сообщения всегда один? Как ты определишь что сообщение доставлено и можно отправлять следующее?

Да, не подумал об этом. Получается, надо _каждому_ узлу оповещать все остальные узлы о получении сообщения. Это плохо

jcdr
() автор топика
Ответ на: комментарий от jcdr

Т.е. получается тут нужна точка синхронизации, когда все узлы свои «сверят часы» (логическое время сообщения).

jcdr
() автор топика
Ответ на: комментарий от jcdr

вопрос в том, как это реализовать самостоятельно на клиентском уровне по TCP протоколу?

каждый соединён с каждым. во все сокеты по пакету разослал и - voi la - велосипедистый велосипед велосипедид велосипеду велосипеды через велосипедный велосипедопед с квадратными велосипедными велосипедоколёсами

anonymous
()
Ответ на: комментарий от ya-betmen

В том и дело, что надо это реализовать без явно выделенного сервера.

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

jcdr
() автор топика

Мне кажется, ты пытаешься переизобрести стек протоколов и сервисов TCP/IP. Как миниум, маршрутизацию и какую-то разновидность мультикаста.

blexey ★★★★★
()
Ответ на: комментарий от blexey

Может быть! А как бы вы сделали? Есть сотня-другая узлов, в общем случае раскиданных по всему свету. Надо от одного узла послать сообщение всем остальным узлам. Так, чтобы минимизировать трафик и время доставки сообщения.

Добавлю, что любой узел может быть за NAT'ом.

Доступный для всех сервер есть, но может использоваться _только_ для «пробития» NAT'а и для доставки сообщений использоваться, к сожалению, не может.

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

jcdr
() автор топика
Ответ на: комментарий от jcdr

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

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

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

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

blexey ★★★★★
()

Раз связанность узлов задаёт «мастер-узел», значит для каждого узла имеется возможность построить SPF. Простой вариант — пересылать «широковещательные» сообщения только тем узлам, которые согласно SPF находятся дальше от источника.

«Правильная очерёдность» требует более подробного определения. Если надо гарантировать, что до тех пор пока «все» не получили от А сообщение А1, никто не получит А2, то А должен получить подтверждение получения А1 от каждого узла в SPF прежде чем делать что-то ещё.
Чё бум делать, если один из ста узлов подтверждение не прислал?
Если это дико важно, то придётся прикручивать таймауты, повторы, отправку юникастов, объявление узла сдохшим и так далее.

Если же всё что нужно, чтобы каждый живой узел получил все сообщения «в правильном порядке», то на многое можно забить и просто реализовать в «подтверждениях» поддержку selectve NACK, чтобы узел получателя мог зарепортить отправителю «получил А1», а потом «получил А4, но не получил А2 и A3» и поддержку «дефрагментации» цепочки сообщений. Пока сообщения приходят в правильном порядке — обрабатывать, а если что-то потерялось — собирать чего приходит в буфер, а в отправителя пулять selective NACK-ами.

Пытаться оптимизировать подтверждения я б не стал — слишком много шансов в погоне за наименьшей избыточностью профуфлить всё остальное.
Но если очень хочется, то можно навертеть уменьшающиеся по мере удаления от источника таймауты и поддержку в подтверждениях списка подтверждателей, чтобы в направлении от дальнего получателя к источнику транзитные узлы добавляли своё «+1» (ну или слали по таймауту своё «персональное» подтверждение).

frob ★★★★★
()
Ответ на: комментарий от jcdr

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

Iron_Bug ★★★★★
()
Последнее исправление: Iron_Bug (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.