Я проектирую систему для обработки 10000 TCP-соединений в секунду, с какими проблемами я столкнусь?

18

У меня относительно новая 8-ядерная коробка под управлением CentOS. Я хотел бы разработать сервер статистики, который использует TCP. Это очень просто, он принимает TCP-соединение, увеличивает счетчик и закрывает соединение. Загвоздка в том, что это нужно делать как минимум 10 тысяч запросов в секунду. Я подозреваю, что процессор / память не будут проблемой, но меня больше волнуют искусственные ограничения (например, полуоткрытые соединения), которые мне может потребоваться настроить на моем сервере, чтобы разрешить такой объем. Так это возможно? Какие настройки мне следует знать? Мой сетевой адаптер не сможет с этим справиться?


источник
1
следите за тем, чтобы не порождать потоки для каждого входящего соединения, это
1
+1 за сообщение о ваших окончательных результатах здесь :)
agsamek 29.09.09

Ответы:

17

Это обычно известно как проблема c10k . На этой странице есть много полезной информации о проблемах, с которыми вы столкнетесь.

Грег Хьюгилл
источник
да, хорошая ссылка!
Sybreon
1
Я ожидаю увидеть больше / других проблем, чем те, которые упомянуты на странице c10k. Установление и закрытие 10 тыс. Соединений в секунду отличается от наличия 10 тыс. Открытых соединений. Соединения, находящиеся в состоянии TIME_WAIT, будут единичными, а ограничение предела ожидания для сокета прослушивания может быть другим. И я не удивлюсь, если этот вариант использования не получит столько профилирования / оптимизации в коде ядра, чем более распространенный случай открытых соединений 10k.
Cmeerw
2

Вы должны быть в состоянии сделать это [хотя это, вероятно, плохая идея].

на смоле appserv я могу получить ~ 5 тыс. запросов / сек на четырехъядерном ксеноне 2.6 ГГц. запросы вызывают простой сервлет, который читает 1 строку из mysql и отправляет очень маленький xml-ответ.

тест был сделан с

ab -n 10000 -c 16 http://some/url/

результаты теста:

Concurrency Level:      16
Time taken for tests:   1.904 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      3190000 bytes
HTML transferred:       1850000 bytes
Requests per second:    5252.96 [#/sec] (mean)
Time per request:       3.046 [ms] (mean)
Time per request:       0.190 [ms] (mean, across all concurrent requests)
Transfer rate:          1636.42 [Kbytes/sec] received

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

даже при длительном тестировании у меня не возникает проблем со связью [упомянутые полуоткрытые розетки]; тестовые прогоны между двумя Linux-блоками, подключенными через гигабитный Ethernet [хотя, как вы видите, пропускная способность не является узким местом].

PQD
источник
Ваши соединения закрываются после каждого ответа, как ОП? AB отправляет Connection: закрыть заголовок?
Нейт
1
@Nate - это http 1.0 - одно соединение для каждого http-запроса.
PQD
1

Возможно, вас заинтересует ограничение ядра Linux, которое я достиг при нагрузочном тестировании Apache. В моем случае ядро ​​выдало несколько полезных сообщений об ошибках, поэтому я советую написать вашу программу, и, если вам кажется, что вы достигли предела, обратите внимание на журналы ядра.

Бен Уильямс
источник
0

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

Zimmy-DUB-Zongy-Цзун-Dubby
источник
Я согласен. UDP был бы намного более легким
fpmurphy
1
У UDP есть свои недостатки, такие как проверки отправителя и доставки, поэтому следует рассмотреть их, прежде чем использовать UDP в работе.
SaveTheRbtz
0

Ваш ник должен быть в состоянии справиться с этим, но я подвергаю сомнению конструкцию наличия 10 000 новых TCP-соединений в секунду; если вы создаете / уничтожаете соединения так быстро, то вы должны либо: а) держать их открытыми дольше, либо б) использовать вместо них UDP.

В случае, когда у вас есть 1M клиентов, которым нужно время от времени выполнять запрос, но когда нагрузка будет достигать 10 Кбит / с, UDP, вероятно, будет лучшим выбором.

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

В случае, если у вас 10 000 запросов в секунду, я полагаю, что у вас в любом случае есть балансировщик внешней нагрузки, так что вам тоже нужно это проверить.

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

MarkR
источник