Как можно одновременно установить и поддерживать большое количество TCP соединений?

Как можно обойти ограничение на количество портов для кластера большого размера, где каждый компьютер должен поддерживать соединения с каждым другим компьютером и клиентами? Какие проблемы с сокетами могут возникнуть после установки их максимального количества за сотни тысяч? Можно ли полагаться на обычную асинхронность, например, от Tokio, для поддержки такого количества соединений? Что ещё стоит учесть или какие "подводные камни" могут возникнуть?
  • 30 января 2024 г. 15:11
Ответы на вопрос 2
Для поддержки большого количества TCP соединений необходимо учитывать следующие аспекты и использовать соответствующие методы:

1. Использование асинхронного I/O:
   - Компоненты, такие как Tokio в Rust, являются асинхронными runtime системами, предназначенными для обработки множества одновременных операций ввода-вывода без блокирования, что делает их идеальными для управления большим количеством TCP соединений.
   - Эвент-драйвен архитектуры, как epoll в Linux и IOCP в Windows, позволяют эффективно оповещать приложение о готовности сокета к чтению или записи, минимизируя простой и использование системных ресурсов.

2. Увеличение максимального числа файловых дескрипторов:
   - Операционные системы имеют ограничения на количество открытых файловых дескрипторов (FDs), что включает в себя все соединения и сокеты.
   - В Unix-подобных системах можно увеличить это ограничение с помощью команд ulimit или путём изменения конфигурации системы (/etc/security/limits.conf).

3. Тюнинг сетевого стека:
   - Настраивайте параметры ядра, такие как размер буфера сокета или параметры TCP, для оптимизации производительности.

4. Избегание зависимостей от количества портов:
   - TCP порты локального узла ограничены числом от 1 до 65535. Для обхода этого ограничения можно использовать технику мультиплексирования, где один порт слушает сразу множество соединений.
   - В случае кластера с множеством соединений внутри него можно использовать сервисный дискавери и маршрутизацию на уровне приложений для установления связи между узлами через единую точку входа.

5. Использование прокси и балансировщиков нагрузки:
   - Распределите нагрузку по разным узлам и управляйте соединениями на более высоком уровне.

Проблемы, которые могут возникнуть при установке большого количества TCP соединений:

- Исчерпание памяти: Каждое соединение потребляет память для своих буферов и структур данных.
- Увеличение задержки и снижение производительности из-за конкуренции за системные ресурсы.
- Деградация производительности при наблюдении I/O "голодания", когда некоторые соединения обрабатываются медленнее других.
- Издержки на контекстные переключения и управление большим количеством параллельных операций.
- Уязвимости в безопасности, обусловленные управлением большим количеством сессий.

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

Подводные камни и что стоит уче
Порт задается 16-битным числом, значит максимальное кол-во портов - 65535. 
Но нужно помнить, что некоторые порты зарезервированы (первые 1023), другие уже могут использоваться.

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

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

UPD:
1. Асинхронность из rust тут вообще ни о чем - это фича языка. Главное здесь - возможности ОС
2. Такое большое кол-во соединений приведет не только к большому потреблению ресурсов, но и большому кол-ву прерываний. Производительность снизится. Рекомендую пересмотреть архитектуру огромного кластера с полносвязной топологией.
Похожие вопросы