Подтвердить что ты не робот

TCP/IP - решение C10K с помощью потока на клиентский подход

После прочтения известной статьи C10k и поиска в Интернете о том, как все сложилось с момента ее написания, я хотел бы знать, возможно ли сегодня стандартный сервер для обработки > 10000 одновременных соединений с использованием потока на соединение (возможно, с помощью пула потоков, чтобы избежать процесса создания/убийства).


Некоторые детали, которые могут повлиять на подход к проблеме:

  • Вход, промежуточная обработка и вывод.
  • Длина каждого соединения.
  • Технические характеристики сервера (ядра, процессоры, оперативная память и т.д.)
  • Объединение этой системы с альтернативными методами, такими как AIO, опрос, зеленые темы и т.д.

Очевидно, я не эксперт в этом вопросе, поэтому любые замечания или советы будут высоко оценены:)

4b9b3361

Ответ 1

Совершенно верно. Стандартный сервер может обрабатывать более 10K одновременных соединений, используя модель с одним потоком для каждого соединения. Я создал такое приложение, и пять лет назад он работал с более чем 50K параллельными подключениями к каждому процессу на стандартном сервере Linux. В настоящее время должно быть возможно запустить одно и то же приложение с более чем 250K параллельными соединениями на текущем оборудовании.

Следует иметь в виду лишь несколько вещей:

  • Повторное использование потоков с помощью пула потоков. Нет необходимости убивать потоки, если они не используются, потому что использование ресурсов должно быть оптимизировано для пиковых нагрузок.
  • Размер стека: по умолчанию каждый поток Linux резервирует 8 МБ для своего стека. Это составляет до 80 ГБ для потоков 10K. Вы должны установить размер стека по умолчанию для некоторого значения между 64k и 512k, что не является проблемой, поскольку большинство приложений не требуют более глубоких стеков вызовов.
  • Если соединения недолговечны, оптимизируйте новые соединения, создав несколько сокетов на одной конечной точке с опцией SO_REUSEPORT.
  • Увеличьте пользовательские пределы: open files (по умолчанию 1.024), max user processes
  • Увеличение системных ограничений, например. /proc/sys/kernel/pid_max (по умолчанию 32K), /proc/sys/kernel/threads-max и /proc/sys/vm/max_map_count (по умолчанию 65K).

Приложение, упомянутое выше, было первоначально разработано для обработки только 2K параллельных соединений. Однако с ростом использования нам не пришлось вносить существенные изменения в код, чтобы масштабировать до 50K соединений.

Ответ 3

Обычными подходами для серверов являются: (a) поток на соединение (часто с пулом потоков) или (b) однопоточная с асинхронным IO (часто с epoll или kqueue). Я думаю, что некоторые элементы этих подходов могут и часто должны быть объединены для использования асинхронного ввода-вывода (с epoll или kqueue), а затем передать запрос соединения в пул потоков для обработки. Этот подход объединил бы эффективную отправку асинхронного ввода-вывода с parallelism, предоставляемым пулом потоков.

Я написал такой сервер для развлечения (на С++), который использует epoll для Linux и kqueue на FreeBSD и OSX вместе с пулом потоков. Мне просто нужно запустить его в своих шагах для тяжелых испытаний, выполнить некоторую очистку кода, а затем выбросить его на github (надеюсь, скоро).