Классическая проблема C10K на стороне сервера (перевод)

Java
Классическая проблема C10K на стороне сервера (перевод)

Классическая проблема C10K на стороне сервера

Я недавно читал контент, связанный с сетевым программированием Unix, а затем нашел очень классическую статью.Содержание может быть не очень новым, но оно действительно классическое.Проблема C10K была просто переведена (может быть небольшое количество проблем в формат конвертирован из уценки) У вас будет более глубокое понимание освоения linux io и linux threads.(В тексте много ссылок.) Исходная ссылкаThe C10K problem

Теперь веб-серверам нужно обрабатывать десятки тысяч запросов одновременно, не так ли? Ведь у сегодняшней сети будет много возможностей для развития. Компьютеры одинаково мощные. Вы можете купить 1000 МГц, 2 ГБ памяти и 1000 Мбит. /sec для машины за 1200 долл. Давайте посмотрим - 20 000 клиентов, каждый на 50 кГц, 1000 Кб и 50 Кб в секунду, это не что иное, как 20 000 клиентов, каждый из которых извлекает 4 Кбайт с диска в секунду, и отправка их в сеть каждую секунду требует больше ресурсов. (Кстати, 0,0,8 доллара за клиента, лицензионная плата в долларах за клиента, взимаемая некоторыми операционными системами, кажется несколько дорогой).

В 1999 году один из самых загруженных ftp-сайтов, cdrom.com, фактически обслуживал 10 000 клиентов одновременно через одну сетевую карту Gigabit Ethernet.Интернет-провайдер предлагает, они ожидают, что он будет становиться все более популярным среди крупных корпоративных клиентов.

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

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

содержание

  • Проблема C10K
    • содержание]
    • Связанные веб-сайты
    • предварительно прочитанные книги
    • Платформа ввода/вывода
    • Стратегия ввода/вывода
      • 1. Поток, обслуживающий несколько клиентов, использующий неблокирующий ввод-вывод иГоризонтальный триггерГотовое уведомление
      • 2. Поток обслуживает несколько клиентов, использует неблокирующий ввод-вывод и готовИзменятьУведомление
      • 3. Один поток обслуживает несколько клиентов, используя асинхронный ввод-вывод.
      • 4. Один поток, обслуживающий одного клиента
      • потоки Linux
        • NGPT: новое поколение потоков Posix для Linux
        • NPTL: Linux-Native POSIX Threading Библиотека
        • Поддержка потоков FreeBSD
        • Поддержка потоков NetBSD
        • Поддержка потоков Solaris
        • Поддержка многопоточности Java в JDK 1.3.x и более ранних версиях
        • Примечание: потоки 1:1 против потоков M:N
      • 5. Встроить серверный код в ядро
    • Принеси стек TCP в пространство пользователя
    • Комментарий
    • Ограничения на дескрипторы открытых файлов
    • предел потока
    • проблема с Java]
    • другое предложение
    • другие ограничения
    • Основные вопросы
    • Проверка работоспособности службы
    • пример
    • Интересный сервер на основе select()
    • Интересный сервер на основе /dev/poll
    • Интересный сервер на основе epoll
    • Интересный сервер на базе kqueue()
    • Интересный сервер на основе сигналов в реальном времени
    • Интересный потоковый сервер
    • интересный основной сервер
    • другие интересные ссылки

Связанные веб-сайты

См. превосходный Ника Блэкабыстрый Unix-серверВеб-страница примерно за 2009 год.

В октябре 2003 г. Феликс фон Ляйтнер подготовил отличную статью о масштабируемости сети.Веб-сайтидемо, провел сравнение производительности нескольких различных сетевых системных вызовов и операционных систем.Один из выводов заключался в том, что ядро ​​​​linux 2.6 превосходит ядро ​​​​2.4, конечно, здесь есть много хороших изображений, чтобы дать разработчикам ОС некоторые идеи в целом.

предварительно прочитанные книги

Если вы не читали покойного У. Ричарда СтивенсаСетевое программирование Unix: Network Apis: Sockets and Xti (Том 1)Пожалуйста, получите копию'thundering herd'Вопрос. Пока вы читаете его, пожалуйста, прочтитеДжефф Дарси о проектировании высокопроизводительных серверов.

(другая книгаСоздавайте масштабируемые веб-сайтыскорее всегоиспользоватьвместонаписатьПарень с веб-сервером был бы полезен)

Платформа ввода/вывода

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

  • ACE, облегченную среду ввода-вывода C++, которая включает некоторые стратегии ввода-вывода, реализованные в объектно-ориентированном мышлении, и много других полезных вещей.В частности, его Reactor выполняет неблокирующий ввод-вывод в объектно-ориентированной манере. объектно-ориентированный способ обработки асинхронного ввода-вывода.
  • ASIO— это инфраструктура ввода-вывода C++, которая становится частью Boost.Это как обновленный ACE для эпохи STL.
  • libeventЭто облегченная структура ввода-вывода C, написанная Нильсом Провосом. Она поддерживает kqueue и select, а также будет поддерживать poll и epoll. Я думаю, что она должна использовать толькоГоризонтальный триггер, у этого есть две стороны.Нильс привел график, иллюстрирующий функцию времени и количества подключений при обработке события, и из графика видно, что kqueue и sys_epoll являются явными победителями.
  • Моя собственная попытка создать легкий фреймворк (к сожалению, не обновленный)
    • Poller— это облегченная среда ввода-вывода C++, которая использует любой из готовых API (poll, select, /dev/poll, kqueue, sigio) для реализации готового к горизонтальному триггеру API.Протестируйте различные другие API, опрос работает намного лучше Документация ссылается на подкласс Poller ниже, а в следующем разделе связанной документации объясняется, как использовать эти готовые API.
    • rnэто облегченная структура CI/O, моя вторая попытка после Poller. Он использует lgpl (поэтому его проще использовать в коммерческих приложениях) и C (поэтому его проще использовать в продуктах, отличных от C++). Теперь он используется в некоторых коммерческих продукты.
  • В апреле 2000 года Мэтт Уэлш писал о том, как сбалансировать рабочие потоки и использование, управляемое событиями, при создании масштабируемых сервисов.бумага, в котором описывается его инфраструктура ввода-вывода Sandstorm.
  • Библиотека Кори Нельсона Scale!- Библиотека асинхронных сокетов, файлов и каналов ввода-вывода для Windows.

Стратегия ввода/вывода

У разработчиков сетевого программного обеспечения есть множество вариантов, вот некоторые из них:

  • Следует ли и как выполнять несколько вызовов ввода-вывода в одном потоке
    • Никакой обработки; используйте блокирующие и синхронные вызовы и используйте как можно больше потоков и процессов для достижения параллелизма.
    • Используйте неблокирующий вызов (например, установите O_NONBLOCK в сокете write()), чтобы начать ввод-вывод, уведомление о готовности (например, poll() или /dev/poll), чтобы узнать, когда канал в порядке, и начать следующий Ввод/вывод/вывод Обычно это можно использовать только для сетевого ввода-вывода, а не дискового ввода-вывода.
    • Используйте асинхронные вызовы (например, aio_write() ) для инициации ввода-вывода и уведомления о завершении (например, сигналы или порты завершения) для уведомления о завершении ввода-вывода Это относится как к сетевому, так и к дисковому вводу-выводу.
  • Как контролировать обслуживание каждого клиента
    • Один процесс обслуживает одного клиента (классический подход Unix, используемый примерно с 1980 года).
    • Поток системного уровня обслуживает несколько клиентов; каждый клиент контролируется:
      • Нить пользовательского уровня (например, нить штата GNU, классическая Java с зеленой нитью)
      • State Machines (немного эзотерический, но популярный в определенных кругах; мой любимый)
      • продолжение (несколько эзотерическое, но популярное в определенных кругах; мое любимое)
    • Поток системного уровня, обслуживающий одного клиента (например, классическая Java с собственными потоками).
  • Поток системного уровня, обслуживающий каждого активного клиента (например, внешний интерфейс Tomcat и apache, порт завершения NT, пул потоков)
  • Следует ли использовать стандартные системные службы или встроить службы в ядро ​​(например, в какой-нибудь пользовательский драйвер, модуль ядра или VxD)

Следующие 5 комбинаций кажутся очень популярными:

  1. Один поток обслуживает несколько клиентов, использует неблокирующий ввод-вывод иГоризонтальный триггерГотовое уведомление.
  2. Один поток обслуживает несколько клиентов, использует неблокирующий ввод-вывод и готов к работе.ИзменятьУведомление.
  3. Один поток обслуживает несколько клиентов, использует асинхронный ввод-вывод.
  4. Один поток, обслуживающий несколько клиентов Использование блокирующего ввода-вывода
  5. Встроить серверный код в ядро

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

... установите неблокирующий режим на всех сетевых дескрипторах, используйте select() или poll(), чтобы определить, какой сетевой дескриптор ожидает данных. Эта модель является наиболее традиционной. В этом режиме ядро ​​​​сообщает вам, является ли файловый дескриптор готов, и делали ли вы что-нибудь с этим файловым дескриптором с тех пор, как ядро ​​в последний раз сообщило вам об этом (термин «горизонтальный триггер» происходит от дизайна компьютерного оборудования; он связан с«Срабатывает по краю»Вместо этого) Джонатон Лемон в своемБумага на бумаге BSDCON 2000 kqueue()Эти термины введены в

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

Важным узким местом является чтение read() или sendfile() из блока диска, если страница в данный момент не находится в памяти. Обработка файлов на диске в неблокирующем режиме не имеет никакого эффекта. То же самое касается дисковых файлов с отображением памяти. Когда сервису требуется дисковый ввод-вывод, его обработка блокируется, всем клиентам приходится ждать, поэтому собственная непоточная производительность будет потрачена впустую.

Это цель асинхронного ввода-вывода, конечно, только в системах без AIO, использование многопоточности и многопроцессорности для дискового ввода-вывода также может решить это узкое место.Один из способов — использовать файлы с отображением памяти, если mincore() указывает Need I/ О, пусть рабочий поток выполняет ввод-вывод и продолжает обрабатывать сетевой трафик.Flashвеб-серверы используют этот прием; ониUsenix '99говорил об этом Похоже, mincore() доступен в Unix-системах, производных от BSD, напримерFreeBSDи солярис, но это неЕдиная спецификация UnixЧасть Linux. Поскольку Kernel2.3.51, он также начал быть частью Linux,Благодарим Вас за отправку исправленного варианта..

Но в списке freebsd-hackers в ноябре 2003 года Вивек Пей и др. сообщили о хорошем результате использования их веб-сервера Flash Затем, после атаки на их узкие места, одно из узких мест оказалось минкором (после предположения, что это не очень хороший способ). , а второй — то, что sendfile блокирует доступ к диску, это модифицированный метод sendfile(), который возвращает что-то вроде EWOULDBLOCK, когда его страница доступа к диску еще не находится в основном состоянии, что повышает производительность (не знаю, как сообщить пользователю, что страница теперь является резидентной... на мой взгляд, что действительно необходимо, так это aio_sendfile().) Конечным результатом их оптимизации является оценка SpecWeb99 около 800 на компьютере с FreeBSD 1 ГГц/1 ГБ, что лучше, чемspec.orgЛюбой файл в формате .

В коллекции неблокирующих сокетов перечислено несколько методов того, как один поток может определить, какой сокет готов:

  • традиционный выбор()
    К сожалению, select() ограничивает обработку FD_SETSIZE. Это ограничение скомпилировано в стандартную библиотеку и пользовательские программы (некоторые версии библиотеки C позволяют запрашивать это ограничение при компиляции вашего приложения).
    видетьPoller_select (cc,h) Пример взаимодействия с другим готовым режимом уведомлений.
  • традиционный опрос()
    Нет жестко запрограммированного ограничения на количество файловых дескрипторов, которые может обрабатывать poll(), но это может быть медленным, когда есть тысячи подключений, поскольку большинство файловых дескрипторов в какой-то момент простаивают, а тысячи полностью сканируются. Тысячи файловые дескрипторы потребуют времени.
    Некоторые операционные системы (например, Solaris 8) используют такие методы, как подсказки опроса для ускорения poll() и т. д. Нильс Провос в 1999 году для Linux.Внедряйте и тестируйте с помощью бенчмарков.
    видетьPoller_poll (cc,h, benchmarks) Это пример того, как использовать опрос для взаимодействия с другим режимом уведомления о готовности ().
  • /dev/poll
    Это рекомендуемый способ замены опроса на Solaris.
    Идея /dev/poll состоит в том, чтобы использовать poll() с одинаковыми параметрами для большинства вызовов. dev/poll; затем вы можете прочитать текущий набор готовых файловых дескрипторов из этого дескриптора.
    Он незаметно появился в Солярисе 7 (см. патчид 106541), но его первое публичное выступление состоялось вSolaris 8середина;Согласно СолнцуВ случае 750 клиентов это всего 10% от головы от опроса ().
    Пробовал различные реализации /dev/poll в Linux, но ни одна из них не была столь же эффективной, как epoll, и никогда не работала.Использование /dev/poll в Linux устарело.
    видетьPoller_devpoll (cc, hБазовый тест) является примером использования /dev/poll для взаимодействия с другими режимами уведомления о готовности (Примечание: этот пример предназначен для Linux /dev/poll и может не работать должным образом в Solaris).
  • kqueue()
    является рекомендуемой альтернативой опросу в системах FreeBSD (скоро, NetBSD).
    увидеть нижеkqueue() может указывать запуск по фронту или по горизонтали.

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

Уведомление об изменении готовности (или уведомление о готовности края) означает, что вы предоставляете ядру дескриптор файла, а затем, когда дескриптор изменяется сnot readyпреобразовать вready, ядро ​​каким-то образом уведомит вас.Затем оно предполагает, что вы уже знаете, что дескриптор файла готов, и не будет отправлять аналогичное уведомление о готовности этому дескриптору до тех пор, пока вы не сделаете что-то с дескриптором, из-за чего символ дескриптора больше не будет готов (например, пока вы не получите сообщение об ошибке EWOULDBLOCK) для отправки, получения или получения вызовов или отправки или получения переводов, размер которых меньше запрошенного количества байтов).

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

Это то же самое, что "Горизонтальный триггер«Уведомления о готовности работают наоборот. Они немного менее терпимы к ошибкам программирования, потому что, если вы пропустите хотя бы одно событие, подключение к событию зависнет навсегда. Ладно, однако, я обнаружил, что уведомления о готовности, запускаемые по краю, облегчают задачу. использовать неблокирующие клиенты OpenSSL Programming стало еще проще, поэтому стоит попробовать.

[Banga, Mogul, Drusha '99]Этот тип паттерна был описан в 1999 году.

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

  • kqueue()Это рекомендуемый способ использования граничного запуска в системах FreeBSD (а вскоре и в NetBSD).
    FreeBSD 4.3 и выше, а такжеNetBSD-текущий октябрь 2002 г.Общая альтернатива поддержке poll()kqueue()/ kevent(); Он также поддерживает запуск по фронту и уровню (см.Веб-страница Джонатана Лемонаи егоДокумент BSDCon 2000 по kqueue().)
    Как и /dev/poll, вы можете назначить объект-слушатель, но вместо открытия файла /dev/poll вызовите kqueue(). Вызовите kevent() для дескриптора, возвращаемого функцией (). Он может прослушивать не только готовность сокета, но также и для простого файла, сигналов и даже завершения ввода/вывода.
    Уведомление:По состоянию на октябрь 2000 года библиотека потоков на FreeBSD хорошо взаимодействует с KQueue (); следовательно, когда KQueue () блокирует, все технологические блоки, а не просто нить, вызывающие kqueue ().
    видетьPoller_kqueue (cc, h,Базовый тест) является примером того, как использовать kqueue() для взаимодействия с другими режимами уведомления о готовности.
    Примеры и библиотеки, использующие kqueue():
  • epoll
    Это рекомендуемый опрос, вызванный для края в ядре Linux 2.6.
    11 июля 2001 года Давиде Либензи предложил альтернативу сигналам реального времени; он назвал свой патч/dev/epoll www.xmailserver.org/linux-patches/nio-improve.htmlЭто похоже на уведомление о готовности сигнала в реальном времени, но в то же время оно может объединять избыточные события и имеет более эффективный метод пакетного поиска событий.
    Epoll был объединен с деревом разработки ядра 2.5.46, когда интерфейс был изменен со специального файла в /dev на системный вызов sys_epoll.Ядро 2.4 также может использовать патчи от более старых epoll.
    Примерно к Хэллоуину 2002 года список рассылки ядра Linux был унифицирован.Проблемы с EPOLL, AIO и другими источниками событийБыли долгие дебаты, это тоже могло случиться, но Давиде сначала сосредоточился на создании epoll.
  • Новости kevent Полякова (Linux 2.6+): 9 февраля 2006 г. и 9 июля 2006 г. Евгений Поляков выпустил патчи, которые, похоже, объединяют epoll и aio; его цель — поддержка сети AIO.
  • Новый сетевой интерфейс Drepper (предложение Linux 2.6+)
    На OLS 2006 Ульрих Дреппер представил новый высокоскоростной асинхронный сетевой API.
  • сигнал реального времени
    Опрос с надписью по краям рекомендуется в ядре Linux 2.4.
    Ядро Linux 2.4 может рассылать готовность к розеткам через определенные сигналы в реальном времени. Примеры следующие:
/* Mask off SIGIO and the signal you want to use. */
sigemptyset(&sigset);
sigaddset(&sigset, signum);
sigaddset(&sigset, SIGIO);
sigprocmask(SIG_BLOCK, &m_sigset, NULL);
/* For each file descriptor, invoke F_SETOWN, F_SETSIG, and set O_ASYNC. */
fcntl(fd, F_SETOWN, (int) getpid());
fcntl(fd, F_SETSIG, signum);
flags = fcntl(fd, F_GETFL);
flags |= O_NONBLOCK|O_ASYNC;
fcntl(fd, F_SETFL, flags);
  • Этот сигнал посылается, когда завершается обычная функция ввода/вывода, такая как read() или write().Чтобы использовать этот сегмент, в цикле, когда poll() обработает все дескрипторы, введите sigwaitinfo()sigwaitinfo()цикл.
    Если sigwaitinfo или sigtimedwait возвращают ваш сигнал в реальном времени, siginfo.si_fd и siginfo.si_band предоставляют почти ту же информацию, что и pollfd.fd и pollfd.revents после вызова poll(), если вы обрабатываете ввод-вывод, то продолжайте вызывать sigwaitinfo( )
    Если sigwaitinfo возвращает традиционный SIGIO, то очередь сигналов переполняется, и вы должныВременно изменив обработчик сигнала на SIG_DFLчтобы очистить очередь сигналов, а затем вернуться к внешнему циклу poll().
    видетьPoller_sigio (cc, h) является примером того, как использовать rtsignals для взаимодействия с другими режимами уведомления о готовности.
    видетьphhttpd, Зак Браун, например код, который использует эту функцию напрямую (или не используйте; phhttpd немного сложно понять...)
    [Прово, Левер и Твиди 2000] Описывает новейший эталон PHHTTPD из разных SigtimedWait используется (), sigtimedwait4 (), который позволяет получить несколько сигналов, позвонив один раз. Интересно SIGTimedWait4 () для их основного преимущества, по-видимому, разрешает приложения для измерения перегрузки системы (так что это может бытьвести себя подобающим образом) (Обратите внимание, что poll() также обеспечивает такое же измерение загрузки системы.)

Один сигнал на fd
Signal-per-fd — это улучшение сигналов реального времени, предложенное Чандрой и Мосбергером, которое уменьшает или устраняет переполнение очереди сигналов в реальном времени путем слияния избыточных событий, но не выходит за рамки epoll.) сравнил производительность этой схемы с select() и /dev/poll.
Виталий Любань анонсировал патч от 18 мая 2001 года для реализации программы; его патч был сгенерирован вWoohoo.luban.org/GPL/prettier.htm….(Примечание: по состоянию на сентябрь 2001 года этот патч может иметь проблемы со стабильностью при высокой нагрузке.dkftpbenchoops может срабатывать примерно при 4500 пользователях.)
видетьPoller_sigfd (cc,h) является примером того, как использовать signal-per-fd для взаимодействия с другими режимами уведомления о готовности.

3. Один поток обслуживает несколько клиентов, используя асинхронный ввод-вывод.

На сегодняшний день это не прижилось в Unix, либо потому, что меньшее количество операционных систем поддерживает асинхронный ввод-вывод, либо потому, что (как и неблокирующий ввод-вывод) это требует переосмысления приложения.интерфейс aio_Предоставляет (прокрутите вниз от этой ссылки до «Асинхронный ввод и вывод»), который связывает сигнал и значение с каждой операцией ввода-вывода. Сигнал и его значение помещаются в очередь и эффективно доставляются пользовательскому процессу. Это из POSIX 1003.1 b Расширение реального времени, а также вторая версия единой спецификации Unix.

AIO обычно используется с уведомлениями о завершении, инициируемыми краем, т. е. когда операция завершена, сигнал ставится в очередь (это также можно сделать, вызвавaio_suspend()Работает с горизонтальными уведомлениями о завершении, хотя я подозреваю, что мало кто так делает.)

glibc 2.1 и более поздние версии предоставляют общую реализацию только для соответствия стандарту, а не для повышения производительности.

Начиная с ядра Linux 2.5.32, реализация Linux AIO от Ben LaHaise была объединена с основным ядром Linux.Он не использует потоки ядра, но по-прежнему имеет очень эффективный низкоуровневый API, но (начиная с 2.6.0-test2) еще не поддерживает вложенность (ядро 2.4 также имеет патч AIO, но реализация 2.5/2.6 немного отличается.) Дополнительная информация:

Супарна также рекомендует посмотретьПодход DAFS API к AIO.

Red Hat ASА SUSE SLES обеспечивает высокую производительность на ядре 2.4.Это связано с производительностью ядра 2.6, но не совсем так.

В феврале 2006 г. у Network AIO был новый подход; см.Вышеприведенная заметка о AIO Евгения Полякова на базе kevent.

В 1999 году,SGI реализует высокоскоростной AIO для Linux, начиная с версии 1.1, хорошо совместим с дисковым вводом-выводом и сокетами. Кажется, он использует потоки ядра. Тем не менее будет полезен для тех, кто не может дождаться, когда AIO Бена поддержит сокеты.

книга О'РейлиPOSIX.4: программирование реального мираПредположительно охватывает хорошее введение в aio.

Учебники для ранних нестандартных реализаций aio в Solaris доступны онлайн.Sunsite, Возможно, на это стоит взглянуть, но имейте в виду, что вам нужно мысленно преобразовать «aioread» в «aio_read» и т. д.

Заметьте, что AIO не позволяет открывать файлы, не блокируя дисковый ввод-вывод; если вы опасаетесь, что открытие файлов на диске приведет к гибернации, Линус рекомендует просто выполнять open() в другом потоке вместо системного вызова aio_open().

В Windows асинхронный ввод-вывод связан с терминами «перекрывающийся ввод-вывод» и IOCP или «порт завершения ввода-вывода». единая константа IOCP для постановки в очередь уведомлений о завершении (например, при использовании поля aio_sigevent с aio_write) и новая идея блокировки определенных запросов от попыток сохранить количество потоков.sysinternals.comНаписано Марком Руссиновичем наПорт завершения ввода/вывода внутренний, книга Джеффри Рихтера "Написание серверных программ для Microsoft Windows 2000" (Amazon, MSPress), U.S. patent #06223207, илиMSDN.

4. Один поток, обслуживающий несколько клиентов

... сделать блок read() и write(). Использование всего стека для каждого клиента имеет большой недостаток, связанный с потреблением памяти. Многие операционные системы также с трудом обрабатывают сотни потоков. Если каждый поток получает стек 2 МБ (не очень распространенный по умолчанию ), то (2^30/2^21) = 512 потоков на 32-битной машине будут исчерпаныВиртуальная память, с доступной пользователю виртуальной машиной объемом 1 ГБ (как Linux обычно позволяет на x86) вы можете обойти это, предоставив меньший стек, но большинство библиотек потоков не позволяют увеличивать стек потоков после создания потока, поэтому это означает, что вы Вы должны сделать так, чтобы ваша программа использовала минимум памяти.Вы также можете обойти это, перейдя на 64-битный процессор.

В Linux, FreeBSD, Solaris поддержка потоков идеальна, даже для основных пользователей, грядущих 64-битных процессоров.Возможно, в будущем не будет, и те, кто любит использовать поток для каждого клиента, также имеет возможность обслуживать 10 000 клиентов а. Однако в настоящее время, если вы действительно хотите поддерживать такое количество клиентов, возможно, вам лучше использовать какой-либо другой метод.

Для тех, кто беззастенчиво поддерживает темы, см.Почему события — плохая идея (для серверов с высокой степенью параллелизма)Автор: фон Берен, Кондит и Брюэр, UCB, на HotOS IX. Может ли кто-нибудь из сторонников указать на статью, опровергающую эту статью? :-)

потоки Linux

потоки LinuxЭто название стандартной библиотеки потоков Linux.Начиная с glibc2.0, она была интегрирована в glibc, в основном в соответствии со стандартами Posix, но производительность и поддержка сигналов неудовлетворительны.

NGPT: новое поколение потоков Posix для Linux

NGPTэто проект, начатый IBM, чтобы улучшить совместимость потоков Posix с Linux. Его текущая стабильная версия - 2.2, и она работает очень хорошо... но команда NGPTобъявитьОни перевели кодовую базу NGPT в режим только поддержки, потому что считали, что это «лучший способ поддержать сообщество в долгосрочной перспективе». Команда NGPT продолжит улучшать поддержку многопоточности в Linux, но сейчас сосредоточена на NPTL (спасибо). команде NGPT за прекрасную работу и элегантное обращение к NPTL.)

NPTL: встроенная в Linux библиотека потоков Posix.

NPTLУльрих Дреппер (англ.glibcсопровождающие) иUlrich DrepperИнициирован, чтобы внедрить в Linux поддержку библиотеки потоков Posix мирового класса.

По состоянию на 5 октября 2003 г. NPTL объединен с cvs-деревом glibc в качестве дополнительного каталога (так же, как поток linux), так что он почти наверняка будет выпущен в следующей версии glibc.

Red Hat 9 был первым дистрибутивом, который включал NPTL (что было немного неудобно для некоторых пользователей, но кто-то должен был сломать лед...)

Ссылка на НПТЛ:

Вот моя попытка написать статью с описанием истории NPTL (см. такжеСтатья Джерри Куперштейна):

В марте 2002 г.Билл Абт из команды NGPT, сопровождающий glibc, встречается с Ульрихом Дреппером и другимиИсследует разработку LinuxThreads Одна из идей, высказанных на собрании, заключалась в повышении производительности мьютексов, Расти Рассели другиеПозже понялБыстрые блокировки пользовательского пространства (фьютексы)), который сейчас используется в NGPT и NPTL.Большинство участников считают, что NGPT следует объединить с glibc.

Но Ульриху Дрепперу не нравится NGPT, и он думает, что может сделать лучше (для тех, кто пытается делать патчи для glibc, это может не стать большим сюрпризом :-) В следующие несколько месяцев Ульрих Дреппер, Инго Молнар работали над glibc и изменения ядра, которые составляют Native Posix Threading Library (NPTL). NPTL использует все улучшения ядра, разработанные NGPT, и использует некоторые новые функции:

NPTL использует три функции ядра, представленные NGPT: getpid() возвращает PID, CLONE_THREAD и фьютексы; NPTL также использует (и опирается на) более широкий набор новых функций ядра, разработанных в рамках этого проекта.

> Некоторые элементы NGPT, представленные в ядре 2.5.8, были изменены, очищены и расширены, например, обработка группы потоков (CLONE_THREAD). способ уничтожить.]

> Функции ядра, разработанные и используемые NPTL, описаны в официальном документе по проектированию,people.RedHat.com/Geothermal BrandWhile/Южный Путуо… ...

Краткий список: поддержка TLS, различные расширения клонов (CLONE_SETTLS, CLONE_SETTID, CLONE_CLEARTID), обработка сигналов потока POSIX, расширение sys_exit() (для выдачи фьютекса TID при выпуске виртуальной машины), системный вызов sys_exit_group(), улучшения sys_execve() и поддержка отдельного потока .

> Также ведется работа по расширению пространства PID - например, procfs зависал из-за дизайна 64K PID, работа по присвоению масштабируемости max_pid и pid, а также ряд улучшений, связанных только с производительностью.

По сути, новая функция заключается в использовании подхода к многопоточности 1:1 — ядро ​​теперь может помочь улучшить все, что касается многопоточности, и мы делаем в точности минимально необходимые переключения контекста и вызовы ядра для каждого базового примитива многопоточности.

Поддержка потоков FreeBSD

FreeBSD поддерживает библиотеки потоков Linux и пользовательского пространства. Кроме того, во FreeBSD 5.0 ​​была введена реализация M:N под названием KSE.Woohoo. ООН ОСВОИССКОГО.

25 марта 2003 г.,Джефф Роберсон опубликовал на freebsd-arch:

...Благодаря Джулиану, Дэвиду Сю, Мини, Дэну Эйшену и всем остальным участникам, участвовавшим в разработке KSE и libpthread, за предоставление основы, мы с Мини разработали многопоточную реализацию модели 1:1. код работает параллельно с KSE и никак его не меняет, он реально помогает сблизить потоки M:N, тестируя общие биты...

и в июле 2006 г.Многопоточность 1:1, предложенная Робертом Уотсоном, должна быть реализацией по умолчанию в FreeBsd 7.x.:

Я знаю, что это обсуждалось в прошлом, но я думаю, что по мере продвижения 7.x пришло время пересмотреть это В тестах для многих распространенных приложений и конкретных сценариев libthr показывает лучшую производительность, чем libpthread Производительность... libthr также реализован на большом количестве наших платформ, и libpthread был реализован на нескольких платформах.Наш совет пользователям MySQL и других тяжелых потоков - "переключиться на libthr", что также подразумевается! libthr библиотека потоков по умолчанию в 7.x.

Поддержка потоков NetBSD

Согласно описанию Нориюки Сода:

Поддержка ядром библиотеки потоков M:N, основанной на модели планировщика активации, будет объединена с NetBSD-current 18 января 2003 г.

Для получения более подробной информации см. презентацию Натана Дж. Уильямса из NethanD Systems на FREENIX 2002.An Implementation of Scheduler Activations on the NetBSD Operating System.

Поддержка потоков Solaris

Поддержка многопоточности в Solaris развивается... Начиная с Solaris 2 и заканчивая Solaris 8, библиотека многопоточности по умолчанию использует модель M:N, но в Solaris 9 по умолчанию используется поддержка многопоточности модели 1:1.Руководство Sun по многопоточному программированиюиЗаметки Sun о потоках Java и Solaris

Потоки Java поддерживаются, начиная с JDK 1.3.x и более поздних версий.

Хорошо известно, что Java до JDK 1.3.x не поддерживала никаких методов обработки сетевых подключений, кроме одного потока на клиента.Volanomarkявляется хорошим микротестом, который измеряет пропускную способность сообщений в секунду при различном количестве подключений.По состоянию на май 2003 года JDK 1.3 от разных поставщиков фактически способен обрабатывать десять тысяч одновременных подключений, хотя производительность впечатляюще падает.Таблица 4, чтобы понять, какие виртуальные машины JVM могут обрабатывать 10 000 подключений, и производительность снижается по мере увеличения количества подключений.

Примечание: потоки 1:1 против потоков M:N

При реализации библиотеки потоков у вас есть выбор: вы можете поместить всю поддержку потоков в ядро ​​(это называется моделью потоков 1:1) или вы можете перенести изрядную часть этого в пространство пользователя (это называется M:N). модель потоков) В какой-то момент M:N считается более производительным, но это слишком сложно, чтобы сделать это правильно, и большинство людей держится от него подальше.

5. Встроить серверный код в ядро

Говорят, что Novell и Microsoft делали это в разное время, по крайней мере одна реализация NFS делает,khttpdСделано это для Linux и статических веб-страниц,«TUX» (поточный веб-сервер Linux)— это быстрый и гибкий HTTP-сервер пространства ядра для Linux от Инго Молнара.Объявление от 1 сентября 2000 г.означает, что изftp://ftp.redhat.com/pub/redhat/tuxЗагрузите альфа-версию TUX и объясните, как присоединиться к списку рассылки для получения дополнительной информации.

В списке linux-kernel обсуждались плюсы и минусы этого подхода, и кажется, что вместо того, чтобы перемещать веб-сервер в ядро, ядро ​​должно добавлять минимальные хуки для повышения производительности веб-сервера. серверов могут извлечь выгоду. См., например,Комментарий Зака ​​БраунаЧто касается отношения пользовательского пространства к http-серверу ядра, кажется, что ядро ​​​​linux 2.4 обеспечивает достаточную функциональность для пользовательских программ, потому чтоX15Сервер работает так же быстро, как Tux, но не использует никаких модификаций ядра.

Bring the TCP stack into userspace

Например, см.netmapПлатформа пакетного ввода-вывода иSandstormНа основе этого экспериментального веб-сервера.

Комментарий

Ричард Гуч писал оДокументы, в которых обсуждаются варианты ввода/вывода.

В 2001 году Тим Брехт и Михал Островски протестировалинесколько стратегийДля упрощения выберите серверы, их данные стоит посмотреть.

В 2003 году Тим Брехт выпустилисходный код userver, небольшой веб-сервер с несколькими серверами, написанными Абхишеком Чандрой, Дэвидом Мосбергером, Дэвидом Париагом и Михалом Островски, Он может использовать select(), poll() или sigio.

Еще в марте 1999 г.Статья Дина Годе:

Меня постоянно спрашивают: «Почему бы вам, ребята, не использовать модель, основанную на выборе/событии, такую ​​​​как Zeus? Она явно самая быстрая»....

Его рассуждения сводились к тому, что «это действительно сложно, отдача неясна», однако через несколько месяцев стало ясно, что люди готовы продолжать попытки.

Марк Руссинович написалредакционныйистатьяОбсуждает проблемы политики ввода-вывода в ядре linux 2.2. Стоит посмотреть, даже он, кажется, в чем-то дезинформирован. В частности, он, кажется, думает, что асинхронный ввод-вывод (см. F_SETSIG выше) в Linux 2.2 находится в данных. пользовательский процесс не уведомляется о готовности, а только при поступлении нового соединения. Это похоже на странное недоразумение. См. такжеранний проект,Опровержение Инго Молнара 30 апреля 1999 г.,Комментарий Руссиновича от 2 мая 1999 г., Опровержение от Алана Коксаи различныеlinux-kernel постыСомневаюсь, что он пытался сказать, что Linux не поддерживает асинхронный дисковый ввод-вывод, что когда-то действительно было, но в SGI реализовано.KAIO, это уже не так реально.

Информацию о портах завершения см.sysinternals.comиMSDNНа этих страницах он говорит, что это уникально для NT; короче говоря, «перекрывающийся ввод-вывод» win32 оказывается слишком низким для удобства, а «порт завершения» — это оболочка, которая обеспечивает очередь событий завершения, а также магию отладки. пытается поддерживать номер в рабочем состоянии, позволяя большему количеству потоков получать события завершения, если другие потоки, получающие события завершения из этого порта, находятся в спящем режиме (возможно, блокируя ввод-вывод), тем самым сохраняя потоки нетронутыми.

смотрите такжеПоддержка портов завершения ввода-вывода в OS/400

Сентябрь 1999 года на linux-kernel велась интересная дискуссия».> 15 000 одновременных подключений"(ивторая неделя треда).Подчеркивать:

  • Ed HallвыпускНесколько замечаний о его опыте: он достиг > 1000 соединений в секунду на UP P2/333 под управлением Solaris Его код использует небольшой фрагмент потоков (1 или 2 на ЦП), каждый из которых использует «модель на основе событий» для управления большое количество клиентов.
  • Mike Jagdis Опубликованный анализ накладных расходов на производительность опроса/выбораИ говорит «текущий реализация выбора / опроса может быть значительно улучшена, особенно в блокирующих случаях, но поскольку Select / Poll нет, накладные расходы все еще увеличиваются с количеством дескрипторов, а не могут, помнить, какие дескрипторы Интересно. Это легко исправить с новым API. Предложения приветствуются ... »
  • Mikeвыпуско немУлучшить работу select() и poll().
  • Mike Опубликованы некоторые возможные API для замены poll()/select().: «Вы можете написать структуру «Pollfd Like» «Device Like» Api, «устройство», прослушивающее события и предоставляющее «pollf-подобную» структуру, когда вы ее читаете? ..."
  • Rogier Wolff предположениеИспользуйте «API, предложенный цифровыми парнями»,У-у-у. В это время. Райс. Quota/~G aura V/ Боюсь...
  • Joerg Pommnitz указыватьЛюбой новый API в этом направлении должен иметь возможность ожидать не только событий файлового дескриптора, но также сигналов и SYSV-IPC.Наши примитивы синхронизации должны, по крайней мере, уметь выполнять Win32's WaitForMultipleObjects.
  • Stephen Tweedieутверждение, _SETSIG, комбинация поставленных в очередь сигналов реального времени и sigwaitinfo()У-у-у. В это время. Райс. Quota/~G aura V/ Боюсь..., SuperSet предлагаемого API он также упомянул, что если вы заинтересованы в производительности, вы всегда можете остановить сигнал; вместо использования асинхронного передающего сигнала, используя процесс SIGWAITINFO (), получает следующий сигнал из очереди.
  • Jayson Nordwick сравниватьПорт завершения и модель событий синхронизации F_SETSIG, можно сделать вывод, что они очень похожи.
  • Alan Cox указыватьБолее старая версия исправления SIGIO от SCT включена в 2.3.18ac.
  • Jordan Mendelson выпускНекоторый пример кода, показывающий, как использовать F_SESTIG.
  • Stephen C. Tweedie ПродолжатьСравните порт завершения и F_SETSIG и обратите внимание: «Используя механизм исключения из очереди сигналов, если библиотека использует тот же механизм, ваше приложение будет получать сигналы, предназначенные для различных компонентов библиотеки», но библиотеки могут устанавливать свои собственные обработчики сигналов, так что это не должно не влияет на программу (сильно).
  • Doug Royerуказал, что он получил 100 000 подключений к Solaris 2.6, когда работал над сервером Sun Calendar Server.Другие оценили, сколько оперативной памяти потребуется Linux и какие узкие места могут возникнуть.

Весело читать!

Ограничения на дескрипторы открытых файлов

  • Любой Unix: ограничение устанавливается с помощью ulimit или setrlimit
  • Солярис: см.FAQ Solaris, выпуск 3.46(или около того; они периодически перенумеровываются)
  • FreeBSD:
    Отредактируйте /boot/loader.conf, добавьте строку
    set kern.maxfiles=XXXX
    где XXXX — требуемый системный лимит для файловых дескрипторов и перезагрузка.Спасибо анонимному читателю, который написал, что он получает более 10000 подключений на FreeBSD 4.3 и сказал
    «FWIW: на самом деле вы не можете легко настроить максимальное количество подключений в FreeBSD через sysctl… вам нужно сделать это в файле /boot/loader.conf.
    Причина этого в том, что вызов zalloci() для инициализации регионов структуры сокета и tcpcb происходит очень рано при запуске системы, так что регионы могут быть как стабильными по типу, так и заменяемыми.
    Вам также необходимо установить большее количество mbuf, потому что вы потребляете (в немодифицированном ядре) один mbuf на соединение для структуры tcptempl, которая используется для реализации поддержки активности».

    Другие читатели сказали:
    «Начиная с FreeBSD 4.4, структура tcptempl больше не выделяется; вам больше не нужно беспокоиться о потреблении mbuf для каждого соединения.

    Смотрите также:


  • OpenBSD: говорят читатели
    «В OpenBSD требуется дополнительная настройка для увеличения количества дескрипторов открытых файлов, доступных для каждого процесса:/etc/login.confПараметр openfiles-cur необходимо увеличить.Вы можете использовать sysctl -w или sysctl.conf для изменения файла kern.max, но это не работает.Это важно, потому что login.conf ограничен очень низким значением 64 для непривилегированные процессы, 128 для привилегированных процессов

  • Линукс: см.Файл /proc Бодо Бауэра.на ядре 2.4
    echo 32768 > /proc/sys/fs/file-max
    Увеличьте системный лимит на открытые файлы.
    ulimit -n 32768
    ulimit -n 32768
    Увеличить лимит для текущего процесса
    On 2.2.x kernels,
    В ядрах 2.2.x
    echo 32768 > /proc/sys/fs/file-max echo 65536 > /proc/sys/fs/inode-max
    Увеличьте системный лимит на открытые файлы.
    ulimit -n 32768
    ulimit -n 32768
    Увеличить лимит для текущего процесса
    Я проверил, что процессы на Red Hat 6.0 (2.2.5 или так плюс патч) могут открываться не менее 31000 файловых дескрипторов таким образом. Другой исследователь подтвердил, что процессы на 2.2.12 могут открываться не менее 31000 файловых дескрипторов. с соответствующими ограничениями). Верхний предел, кажется, имеющаяся память.
    Stephen C. Tweedie ПочтаО том, как установить ограничения ulimit глобально или для каждого пользователя во время загрузки с помощью initscript и pam_limit.
    Однако в более старых ядрах 2.2, даже с вышеуказанными изменениями, количество открытых файлов на процесс по-прежнему ограничено 1024.
    смотрите такжеПост Оскара 1998 г., в котором обсуждаются ограничения для каждого процесса и общесистемные ограничения файловых дескрипторов в ядре 2.0.36.

предел потока

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

Java-проблема

В JDK 1.3 стандартная сетевая библиотека Java в основном предоставляетОдин клиент, одна модель потока, Это способ выполнения неблокирующего чтения, но нет способа сделать неблокирующую запись.

в мае 2001 года.JDK 1.4пакет был представленjava.nioОбеспечить полную поддержку безблокировкой ввода / вывода (и других хороших вещей).Примечания к выпускуВнимание! Попробуйте и дайте отзыв Sun!

Java от HP также включает в себяAPI ротации потоков.

В 2000 году Мэтт Уэлш реализовал неблокирующие сокеты для Java. Его тесты производительности показали, что они превосходят блокирующие сокеты на серверах, обрабатывающих большое количество (более 10000) подключений.Его библиотека классов называетсяjava-nbio;онSandstormЧасть проекта. Тесты показаныПроизводительность 10000 подключенийкозел.

См. разделы Дина Гауда по Java, сетевому вводу-выводу и многопоточности.статьяи Мэтт Уэлш о событиях и рабочих потоках.бумага

До Nio есть несколько предложений для улучшения API Java Network:

  • Мэтта Уэлшасистема ЯгуарПредлагаются предварительно сериализованные объекты, новый байт-код Java и изменения в управлении памятью позволяют выполнять асинхронный ввод-вывод с Java.
  • Авторы Си Си Чанг и Т. фон ЭйкенПодключение Java к архитектуре виртуального интерфейсаПредлагаемые изменения управления памятью, позволяющие Java использовать асинхронный ввод-вывод.
  • JSR-51Это технический проект Sun, в рамках которого был разработан пакет java.nio, в котором участвовал Мэтт Уэлш (кто сказал, что Sun не послушается?).

другое предложение

  • нулевая копия
    Как правило, данные многократно копируются из одного места в другое.Любая схема, сводящая эти копии к минимуму физических данных, называется «нулевой копией».
    • Томас Огрисегг mmaped файлы под Linux 2.4.17-2.4.20Отправить патч для отправки с нулевым копированием.утверждает, что это быстрее, чем sendfile() .
    • IO-Liteпредставляет собой набор примитивов ввода-вывода, который избавляет от необходимости во многих копиях.
    • В 1999 году Алан Кокс заметил, что нулевое копирование иногда не стоит усилий (но ему нравится sendfile()).
  • Ingo в ядре 2.4 как TUX 1.0 в июле 2000 г.Реализован протокол TCP с нулевым копированием., он говорит, что скоро сделает его доступным для пользователей.
    • Дрю Галлатин и Роберт добавили во FreeBSD некоторые функции нулевого копирования.; Кажется, идея заключается в том, что если вы вызываете write() или read() для сокета, указатель выравнивается по странице, а объем передаваемых данных составляет не менее одной страницы,в то же времяВы не получите буферы сразу, будут использоваться навыки управления памятью, чтобы избежать копирования.Следите за этим сообщением на linux-kernel, чтобы понять опасения людей по поводу скорости этих трюков с управлением памятью.
      По словам Нориюки Соды:
      Начиная с выпуска NetBSD-1.6, нулевое копирование на стороне отправителя поддерживается путем указания параметра ядра "SOSEND_LOAN". Этот параметр теперь является параметром по умолчанию в NetBSD-current (вы можете отключить эту функцию, указав "SOSEND_NO_LOAN" в ядре). в NetBSD_current ).При использовании этой функции нулевое копирование автоматически включается, если в качестве данных для отправки указано более 4096 байтов данных.

    • Системный вызов sendfile() включает сеть с нулевым копированием.
      Функция sendfile() в Linux и FreeBSD позволяет указать ядру отправить часть файла или весь файл, заставляя ОС делать это максимально эффективно. Его также можно использовать на сервере с потоками или на серверах, использующих неблокирующий ввод-вывод (в Linux в настоящее время он плохо документирован;Используйте его для вызова _syscall4.Andi Kleen пишет man-страницу, посвященную этому См. также Jeff Tranter в Linux Gazette, выпуск 91.Изучите системный вызов sendfile.) имеютслухСкажем, ftp.cdrom.com выигрывает от sendfile().
      Реализация функции sendfile() с нулевым копированием предоставляется для ядра версии 2.4. См.LWN Jan 25 2001.
      Разработчик использует SendFile в FreeBSD для отображения использования PollWrand вместо plays.
      Solaris 8 (по состоянию на июль 2001 г.) имеет новый системный вызов sendfilev.Копия справочной страницы находится здесь. Solaris 8 7/01 примечания к выпускуЭто также было упомянуто.Я подозреваю, что это наиболее полезно при отправке в сокет в режиме блокировки; использование неблокирующего сокета было бы немного больно.
  • Используйте writev, чтобы избежать маленьких фреймов (или TCP_CORK)
    Новая опция сокета в Linux, TCP_CORK, говорит ядру избегать отправки частичных кадров, что немного помогает, например, когда есть много небольших вызовов write(), которые вы не можете объединить вместе по какой-то причине.Опция Unset сбрасывает буфер , Лучше использовать writev(), но...
    СмотретьLWN Jan 25 2001, резюме некоторых очень интересных дискуссий о linux-kernel на TCP-CORK и возможной альтернативе MSG_MORE.
  • Будьте умны, когда перегружены.
    [Provos, Lever, and Tweedie 2000] упоминает, что сбрасывание входящих подключений при перегрузке сервера улучшает форму кривой производительности и снижает общую частоту ошибок. В качестве меры перегрузки используется сглаженная версия «Количества клиентов, готовых к вводу-выводу». легко применять Серверы, написанные с использованием select, poll или любого другого системного вызова, возвращающего технику события готовности для каждого вызова (например, /dev/poll или sigtimedwait4()).
  • Некоторые программы могут выиграть от использования потоков, отличных от Posix.
    Не все потоки одинаковы.Например, функция clone() в Linux (и ее аналоги в других операционных системах) позволяет вам создать поток с собственным текущим рабочим каталогом, что полезно при реализации ftp-сервера. FTPd для примера использования собственных потоков вместо pthreads.
  • Кэширование ваших собственных данных иногда может быть выигрышным.
    Vivek Sadananda Pai (vivek@cs.rice.edu) вnew-httpd«Re: исправить проблему смешанного сервера», 9 мая, заявление:
    «Я сравнил чистую производительность серверов на основе выбора и многопроцессорных серверов на FreeBSD и Solaris/x86. В микротестах различия в производительности архитектуры программного обеспечения были небольшими. Кэширование уровня.Хотя многопроцессорные серверы могут быть реализованы с более высокой стоимостью, тех же преимуществ труднее достичь с реальными рабочими нагрузками (по сравнению с микробенчмарками).Я представлю эти измерения как часть документа, который появится в следующей конференции Usenix Если у вас есть послесловие, документ можно найти по адресуУ-у-у. В это время. Рис. Квота/~vi VE can/Flushing…"

другие ограничения

  • Старые системные библиотеки могут использовать 16-битные переменные для хранения дескрипторов файлов, что вызывает проблемы с дескрипторами выше 32767. С glibc2.1 все должно быть в порядке.
  • Многие системы используют 16-битные переменные для хранения идентификаторов процессов или потоков.Тест масштабируемости VolanoПри переносе на C было бы интересно посмотреть, каковы ограничения количества потоков для различных операционных систем.
  • Некоторые операционные системы предварительно выделяют слишком много локальной памяти потока; если каждый поток получает 1 МБ, а общее пространство виртуальной машины составляет 2 ГБ, это создает верхний предел в 2000 потоков.
  • Проверятьwoohoo.acme.com/software/dayhou…График сравнения производительности внизу.Обратите внимание, как разные серверы имеют проблемы с более чем 128 подключениями, даже на Solaris 2.6. Кто знает почему, дайте мне знать.

Примечание. Если в стеке TCP есть ошибка, вызывающая более короткую (200 мс) задержку для времени SYN или FIN, как в Linux 2.2.0-2.2.6, а ОС или демон http имеют жесткое ограничение на количество подключений, вы ожидаете такого поведения.Могут быть и другие причины.

Основные вопросы

Для Linux узкое место в ядре постоянно устраняется.Linux Weekly News,Kernel Traffic, the Linux-Kernel mailing listmy Mindcraft Redux page.

В марте 1999 года Microsoft спонсировала тест, сравнивающий NT и Linux для обслуживания большого количества клиентов http и smb, результаты для Linux были неудовлетворительными.Статья об контрольных показателях Mindcraft за апрель 1999 г.узнать больше информации

смотрите такжеПроект масштабируемости Linux.они занимаются интересной работой.в том числеПатч-подсказка для опроса Нильса Провосагромкий групповой вопросчасть работы.

Пожалуйста, также участвуйтеМайк Джагдис работает над улучшением методов select() и poll().;Вот Майк об этомПочта.

Мохит Арон (aron@cs.rice.edu) пишет, что синхронизация на основе скорости в TCP может улучшить время ответа HTTP на 80% при «медленных» соединениях.

Измеряйте производительность сервера

Два теста, в частности, легкие, веселые и сложные:

  1. Необработанных подключений в секунду (сколько файлов размером 512 байт можно обслуживать в секунду?)
  2. Общая скорость передачи для больших файлов со многими медленными клиентами (сколько 28,8 тыс. Модемных клиентов может загрузить с сервера одновременно, прежде чем производительность попадет в горшок?)

Джефф Посканцер опубликовал бенчмарки, сравнивающие множество веб-серверов.Посмотрите его результаты.woohoo.acme.com/software/dayhou…

у меня тоже такоеНекоторые старые заметки о сравнении thttpd с ApacheМожет быть интересен новичкам.

Чак Левер продолжает напоминатьо насБумага Банга и Друсчела на бенкере веб-сервера. Стоит прочтения.

У IBM есть статья под названиемТест Java-сервераОтличная статья [Baylor et al., 2000]. Стоит прочитать.

пример

Nginx— веб-сервер, который использует любой эффективный механизм сетевых событий, доступный в целевой операционной системе, стал очень популярным, есть дажедве книги

Интересный сервер на основе select()

  • thttpdОчень просто. Используйте один процесс. У него очень хорошая производительность, но он не зависит от количества процессоров. Также можно использовать kqueue.
  • mathopd, Аналогично thttpd.
  • fhttpd
  • boa
  • Roxen
  • Zeus, пытаясь стать самым быстрым коммерческим сервером. Посмотрите ихРуководство по регулировке.
  • Другие службы, отличные от Java, перечислены вwoohoo.acme.com/software/dayhou…
  • BetaFTPd
  • Flash-Lite- Веб-сервер с использованием IO-Lite.
  • Flash: эффективный и портативный веб-сервер- используйте select(), mmap(), mincore().
  • Веб-сервер Flash по состоянию на 2003 г.- Используйте select(), модифицированный sendfile(), асинхронный open().
  • xitami- Используйте select() для реализации собственной абстракции потоков для переносимости на системы, не требующие потоков.
  • Medusa- Набор инструментов для написания серверов на Python, предназначенный для обеспечения очень высокой производительности.
  • userver- Небольшой http-сервер, который может использовать select, poll, epoll или sigio.

Интересный сервер на основе /dev/poll

  • Н.Провос, К.Левер,"Scalable Network I/O in Linux"Май 2000 г. [Дорожка FREENIX, Proc.USENIX 2000, Сан-Диего, Калифорния (июнь 2000 г.)] Описывает версию thttpd, модифицированную для поддержки /dev/poll Сравните производительность с phhttpd.

Интересный сервер на основе epoll

  • ribs2
  • cmogstored- Используйте EPOLL / KQUEUE для большинства сетей, используя резьбы для диска и принять4

Интересный сервер на базе kqueue()

  • thttpd(начиная с версии 2.21?)
  • Адриан Чадд говорит: «Я много работаю над тем, чтобы squid действительно работал как система ввода-вывода kqueue»; его официальный подпроект Squid; см.squid.source forge.net/projects.Контракты…, Это явно лучше, чемBennoизпластырьвозобновить

Интересный сервер на основе сигналов в реальном времени.

  • Chromium X15. Использует функцию SIGIO ядра 2.4 вместе с sendfile() и TCP_CORK и, как сообщается, достигает даже более высоких скоростей, чем TUX.исходный код доступен, Смотреть Фабио Риккардиоригинальное объявление
  • Зак Браунphhttpd- «Более быстрый сервисный сервер для демонстрации модели событий sigio/siginfo. Если вы пытаетесь использовать его в производственной среде, считайте этот код экспериментальным и берегите себя», используя 2.3 .21 или более позднюю версию.siginfoсодержит необходимые обновленные исправления ядра. Ходят слухи, что он даже быстрее, чем khttpd. См. некоторые из его 31.05.1999инструкция

Интересный потоковый сервер

интересный сервер на основе ядра

другие интересные ссылки