Четверг, 21.11.2024, 17:14
Мой персональный сайт Добрым людям smart & sober

Главная Регистрация Вход
Приветствую Вас, Гость · RSS
Калькулятор


Меню сайта
Календарь
«  Июнь 2012  »
ПнВтСрЧтПтСбВс
    123
45678910
11121314151617
18192021222324
252627282930


Форма входа


Архив записей
Мини-чат


Категории раздела


Наш опрос
В чем заключается ваш смысл жизни
Всего ответов: 154
 
Главная » 2012 » Июнь » 24 » Как решить проблему 10 000 соединений?
02:20
Как решить проблему 10 000 соединений?


Способы решения этой проблемы, поднятой еще в 2001 году программистом Дэном Кегелем, рассматриваются в девятой лекции курса «Сетевое программирование в UNIX», подготовленного специалистами SkyDNS и компании «Айдеко». За подробностями – видео.

Из рассмотренных до того подходов модель prefork работает, но является расточительной с точки зрения памяти, а select()– не работает вообще.

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

Практическое задание состояло в переписывании астрологического сервера с использованием семейства функций epoll() и проверке, выдерживает ли он 10000 соединений.

А сколько одновременных соединений выдержит астрологический сервер на вашем ноутбуке?



Слайды доступны здесь.

Предыдущие лекции:
1. Курс для тех, кто не боится UNIX и C
2. Каждому клиенту по процессу
3. Реализуем протокол или как работают астрологи
4. О том, как читать до конца
5. Программы в автоматном стиле — трудности перевода
6. Как делать несколько дел одновременно и в то же время по очереди?
7. Эффективное чтение
8. Как сделать программу нетерпеливой?
22 июня 2012 в 16:11
153
AdMonster 32,4

комментарии (8)

0
romy4 #
Спасибище! Очень нужная тема затронута и актуальна для меня.
0
frasl #
Мы юзали сервер с 4 сетевыми картами — в общей сложности оно обслуживало до 50к подключений (исходящих), тоже на epoll. Единственное — каждый сокет перед коннектом надо ручками биндить на правильную сетевушку (да и вообще AFAIR у автоматического бинда есть количественные ограничения, но точно не вспомню — 7 лет прошло)
0
nuit #
Как всегда отличное видео.
Хотелось бы ещё добавить про необходимость отложеного удаления(сборщик мусора) при использовании указателей в epoll_event.data.ptr, тк в случае когда у нас идёт обработка результатов, которые вернул epoll_wait и результат первого евента повлёк к ситуации, когда нужно уничтожить «состояние», связаное с одним из последующих евентов, то нельзя убивать то на что указывает epoll_event.data.ptr, нужно это делать после обработки всех результатов, возвращаемых epoll_wait'ом.
0
petrkozorezov #
Erlang?
–1
amirul #
Что поразительно так это то, насколько регулярно в подобных обзорах/обучающих материалах «забывают» про единственный правильный способ: асинхронный ввод/вывод, который наконец-то появился даже в юниксах. Можете назвать хоть одно преимущество «неблокирующего» ввода/вывода перед настоящим асинхронным?
+1
nuit #
Более поразительным является то что люди, которые никогда в жизни не использовали ни epoll, ни этот aio, рассказывают о том что является единственным правильным способом.

>Можете назвать хоть одно преимущество «неблокирующего» ввода/вывода перед настоящим асинхронным?
ну начнём с того что это апи для работы с фс, а не сетью.
а закончим тем что в случае с проактор паттерном приходится выделять буфферы для чтения на каждый сокет чтобы пропихнуть его в aio_read, из-за чего получим проблемы с масштабируемостью в случае с сотнями тысяч слабоактивных сокетов.
0
amirul #
Как оказывается, еще более поразительным является то, что даже те, кто вроде бы и знают о существовании асинхронного ввода/вывода, совершенно не представляют себе что это такое и почему это единственный правильный способ.

ну начнём с того что это апи для работы с фс, а не сетью.

Ну начнем с того, что подтвердить это утверждение очень просто — нужно всего лишь привести цитатку из стандарта. Предупреждая Вашу попытку выставить aio_fildes как доказательство, отмечу, что socket возвращает как раз его: «Upon successful completion, socket() shall return a non-negative integer, the socket file descriptor».

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

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

Вот Вы сейчас противопоставляете необходимость выделения буфера под прием данных чему? Неужели сокет сам по себе не имеет буфера на прием? Неужто SO_RCVBUF в Линуксе по умолчанию установлен в 0 и любые данные, на которые нет outstanding read мгновенно теряются. Вот это новость.

Но позвольте мне продолжить Вашу мысль:

В-третьих: мы избавляемся от лишнего копирования: сначала в буфер драйвера tcp, а потом в пользовательский (пользователь в данном случае — это пользователь API, то есть программист). К тому же при наличии TOE (да, я знаю, что он не решает «проблему» c10k, но он очень хорошо вписывается в модель асинхронного ввода/вывода) количество копирований можно сократить до 0 (НУЛЯ): с «провода» сразу в пользовательский буфер по DMA.

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

В-пятых: асинхронный ввод/вывод концептуально чище: он превращается в синхронный (блокирующий или нет) всего лишь оберткой с одним дополнительным wait-ом в конце, в то время как синхронный в асинхронный не превращается никак (можно придумать схемы с пулом потоков или с порождением новых потоков на каждую операцию, но они будут либо слишком «дорогими», либо слишком неустойчивыми к «нестандартной» нагрузке, либо и то другое вместе).

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

В заключение хочу отметить, что конкретная РЕАЛИЗАЦИЯ асинхронного ввода/вывода может быть очень плохой (что в случае Линукса меня бы совершенно не удивило), что не отменяет моего изначального тезиса о том, что настоящий асинхронный ввод/вывод имеет кучу преимуществ перед «неблокирующим», в то время как обратное несправедливо: нет ни одного преимущества «неблокирующего» ввода/вывода перед асинхронным.
0
fossdev #
3 года назад эксплуатировал самописный сервер под Windows 2003. В пике было до 300к подключений и 1.5гбит/сек трафика с двух сетевых карт. Софт был написан под IOCP модель, число воркеров = cpu*2.
Просмотров: 655 | Добавил: Breger | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Copyright MyCorp © 2024