Как открывать много TCP соединений и поддерживать их?

У меня есть некий кластер. Он может быть огромных размеров. Каждый компьютер должен открыть своё соединение с каждым другим компьютером в кластере. Более того, каждый компьютер также должен поддерживать соединения с клиентами. Сейчас я упираюсь не столько в производительность, сколько в порты.

Как обойти ограничение на количество портов? Не возникнут ли у меня проблемы с сокетами уже после установки их максимального количества за сотни тысяч? Достаточно ли использовать обычную асинхронность (например, от Tokio) для поддержки такого количества соединений? Есть ли ещё какие-нибудь "подводные камни" в этом вопросе?
  • Вопрос задан
  • 2621 просмотр
Пригласить эксперта
Ответы на вопрос 4
AshBlade
@AshBlade
Просто хочу быть счастливым
Порт задается 16-битным числом, значит максимальное кол-во портов - 65535.
Но нужно помнить, что некоторые порты зарезервированы (первые 1023), другие уже могут использоваться.

Обойти ограничение на кол-во портов ты никак не сможешь, т.к. это потребует изменение ядра ОС и TCP протокола.

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

UPD:
1. Асинхронность из rust тут вообще ни о чем - это фича языка. Главное здесь - возможности ОС
2. Такое большое кол-во соединений приведет не только к большому потреблению ресурсов, но и большому кол-ву прерываний. Производительность снизится. Рекомендую пересмотреть архитектуру огромного кластера с полносвязной топологией.
Ответ написан
bingo347
@bingo347
Crazy on performance...
Как уже написали в соседнем ответе, лимит портов 65535 на 1 интерфейс.
Но это на один интерфейс, самое простое решение тут воткнуть несколько сетевых карт, да у них будут разные ip (по сути у одной машины будет пул ip), но для 100к коннектов хватит 2 карточек.
В Linux (насчет других ОС не уверен, но возможно тоже) есть способы поизвращаться и поднять 2+ виртуальных интерфейса на одной сетевой карте. При этом у машины так же будет 2 ip адреса и нужно будет распределять соединения между ними.

Хотя по хорошему я бы посмотрел здесь в сторону UDP с одним занятым портом на машине, а необходимые возможности TCP уже воспроизводить программно.
Ответ написан
@rPman
Назначают несколько ip адресов на один интерфейс, и при открытии слушающего сокета, указывают разные ip адреса (обычно указывают 0.0.0.0 - слушать все интерфейсы, но можно указать конкретный). ОС это переваривают корректно.

Подводные камни - большое количество слушающих сокетов тратят ресурсы (ram).

У тебя неправильная архитектура - не нужно делать подключение 'все со всеми', делай граф - 'каждый с некоторыми', уведомления передавай через соседей, а для передачи самих данных уже открывай прямое соединение на это время и отключайся. Таких сетей полно, например dht, bitcoin p2p,...
Ответ написан
Комментировать
msHack
@msHack
При превышении числа в 65535 мой Микротик начинает кидать соединения в оперативную память а дальше все зависет от количества ОЗУ и мощности ЦП тестровал программой Rats on The Boat - BitTorrent search engine
65c716e5c1835535250568.png
Заметил что Роутеры на чипах Медиатек не умеют работать с большим количеством соединений ( зависают ) еще в некоторых чипах Медиатек есть аппаратный NAT который ужасен а вот на Микротиках все гуд там qualcomm
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы