Предостережения относительно выбора/опроса по сравнению сРеакторы epoll в Twisted

StackOverflow https://stackoverflow.com/questions/2032598

Вопрос

Все, что я читал и испытал (приложения на основе Tornado), заставляет меня поверить, что ePoll является естественной заменой сети на основе выбора и опроса, особенно с Twisted.Это делает меня параноиком: довольно редко за лучшую технику или методологию не приходится платить.

Прочитав пару десятков сравнений epoll с альтернативами, видно, что epoll явно является чемпионом по скорости и масштабируемости, в частности, он масштабируется линейным образом, что является фантастическим.Тем не менее, что насчет использования процессора и памяти, остается ли epoll чемпионом?

Это было полезно?

Решение

Для очень небольшого количества сокетов (конечно, зависит от вашего оборудования, но мы говорим о чем-то порядка 10 или меньше), select может превзойти epoll по использованию памяти и скорости выполнения.Конечно, при таком небольшом количестве сокетов оба механизма настолько быстры, что в подавляющем большинстве случаев эта разница не особо заботит вас.

Однако одно уточнение.И select, и epoll масштабируются линейно.Однако большая разница заключается в том, что API-интерфейсы, ориентированные на пользовательское пространство, имеют сложности, основанные на разных вещах.Стоимость select вызов примерно соответствует значению файлового дескриптора с наибольшим номером, который вы ему передаете.Если вы выберете один FD, 100, это примерно в два раза дороже, чем выбор одного FD, 50.Добавление большего количества fd ниже самого высокого не совсем бесплатно, поэтому на практике это немного сложнее, но это хорошее первое приближение для большинства реализаций.

Стоимость epoll ближе к количеству файловых дескрипторов, в которых действительно есть события.Если вы отслеживаете 200 файловых дескрипторов, но только 100 из них имеют события, то вы (очень грубо) платите только за эти 100 активных файловых дескрипторов.Именно здесь epoll предлагает одно из своих главных преимуществ перед select.Если у вас есть тысяча клиентов, которые в основном простаивают, то при использовании select вы все равно платите за каждую тысячу из них.Однако с epoll у вас их всего несколько — вы платите только за те, которые активны в любой момент времени.

Все это означает, что epoll приведет к меньшему использованию ЦП для большинства рабочих нагрузок.Что касается использования памяти, здесь все немного сложнее. select удается представить всю необходимую информацию в очень компактном виде (один бит на файловый дескриптор).И ограничение FD_SETSIZE (обычно 1024) на количество файловых дескрипторов, которые вы можете использовать с select означает, что вы никогда не потратите более 128 байт на каждый из трех наборов fd, которые вы можете использовать с select (чтение, запись, исключение).По сравнению с этими максимальными 384 байтами epoll — это своего рода свинья.Каждый файловый дескриптор представлен многобайтовой структурой.Однако в абсолютном выражении он все равно не будет использовать много памяти.Вы можете представить огромное количество файловых дескрипторов размером в несколько десятков килобайт (я думаю, примерно 20 тысяч на 1000 файловых дескрипторов).А еще можно добавить тот факт, что вам придется потратить все 384 байта на select если вы хотите отслеживать только один файловый дескриптор, но его значение равно 1024, тогда как при использовании epoll вы потратите только 20 байт.Тем не менее, все эти цифры довольно малы, поэтому особой разницы нет.

И есть еще одно преимущество epoll, о котором, возможно, вы уже знаете: он не ограничивается файловыми дескрипторами FD_SETSIZE.Вы можете использовать его для мониторинга любого количества файловых дескрипторов, которое у вас есть.А если у вас есть только один файловый дескриптор, но его значение больше FD_SETSIZE, epoll работает и с ним, но select не.

Случайно я также недавно обнаружил один небольшой недостаток epoll по сравнению с select или poll.Хотя ни один из этих трех API не поддерживает обычные файлы (т. е. файлы в файловой системе), select и poll представить это отсутствие поддержки как сообщение о том, что такие дескрипторы всегда доступны для чтения и записи.Это делает их непригодными для какого-либо значимого неблокирующего ввода-вывода файловой системы, программы, которая использует select или poll и случайно встретит файловый дескриптор файловой системы, по крайней мере, продолжит работать (а если и произойдет сбой, то это произойдет не из-за select или poll), пусть и не с лучшей производительностью.

С другой стороны, epoll быстро выйдет из строя с ошибкой (EPERM, видимо) когда его попросили проконтролировать такой файловый дескриптор.Строго говоря, это вряд ли неверно.Это просто явно сигнализирует об отсутствии поддержки.Обычно я приветствовал бы явные условия отказа, но этот недокументирован (насколько я могу судить) и приводит к полностью неработающему приложению, а не к тому, которое просто работает с потенциально сниженной производительностью.

На практике единственное место, где я видел это, — это взаимодействие со stdio.Пользователь может перенаправить стандартный ввод или вывод из/в обычный файл.В то время как раньше stdin и stdout были бы каналом, который прекрасно поддерживался epoll, затем он становится обычным файлом, и epoll громко завершает работу, нарушая работу приложения.

Другие советы

При тестировании в моей компании возникла одна проблема с epoll(), что привело к единой стоимости по сравнению с select.

При попытке чтения из сети с таймаутом создание epoll_fd (вместо FD_SET) и добавление fd в epoll_fd обходится намного дороже, чем создание FD_SET (который представляет собой простой malloc).

Согласно предыдущему ответу, поскольку количество FD в процессе становится большим, стоимость select() становится выше, но в нашем тестировании, даже со значениями fd в 10 000, select все равно был победителем.Это случаи, когда поток ожидает только один fd, и просто попытка преодолеть тот факт, что сетевое чтение и сетевая запись не истекают по тайм-ауту при использовании модели блокирующего потока.Конечно, модели с блокирующими потоками имеют низкую производительность по сравнению с неблокирующими реакторными системами, но бывают случаи, когда требуется интеграция с конкретной базой устаревшего кода.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top