Есть, что называется, single packet workload, когда HTTP-сервер клиентам отдает данные, которые умещаются в один пакет. С целью выжать максимум пишется собственный HTTP-сервер на базе асинхронной модели (используя epoll/kqueue).Тестирование ведется на стенде из двух серверов на Intel платформе (quad core xeon 2.4 ghz / 4 gb / 2 x 1 gbps). Сервер работает на одной машине, а тестирущий клиент на другой. Тестируется связь, как через свич, так и напрямую, через кабель соединяющий два порта.
При обработке соединений сервером, когда accept делается одним серверным потоком производительность примерно 32 000 обработанных соединений в секунду. Когда accept делается четырьмя серверными потоками с мутексами или без - производительность та же.
Проблема, вероятно, в сериализации accept(). Хотя может быть и в другом - тюнинг параметров TCP не помог :)
CPU при 2000 одновременных коннектах на сервере грузятся примерно вот так:
------------------------------------------------------------------------------
top - 23:19:02 up 3:12, 2 users, load average: 0.23, 0.16, 0.08
Tasks: 68 total, 1 running, 67 sleeping, 0 stopped, 0 zombie
Cpu0 : 4.6%us, 10.2%sy, 0.0%ni, 60.1%id, 0.0%wa, 0.3%hi, 24.8%si, 0.0%st
Cpu1 : 5.0%us, 13.5%sy, 0.0%ni, 63.4%id, 0.0%wa, 0.3%hi, 17.8%si, 0.0%st
Cpu2 : 4.7%us, 10.6%sy, 0.0%ni, 63.5%id, 0.0%wa, 0.0%hi, 21.3%si, 0.0%st
Cpu3 : 4.0%us, 11.6%sy, 0.0%ni, 66.0%id, 0.0%wa, 0.7%hi, 17.8%si, 0.0%st
Mem: 4150524k total, 153228k used, 3997296k free, 19048k buffers
Swap: 4000104k total, 0k used, 4000104k free, 68668k cachedPID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3146 root 20 0 16860 9492 468 S 91 0.2 1:52.68 tests
------------------------------------------------------------------------------Обидно, что остается много неиспользованных ресурсов. Гигабит мелкими пакетами, естественно, также не нагружается до упора - по крайней мере по пропускной способности.
Как побороть данную проблему, чтобы увеличить число обрабатываемых коннектов?
Судя по всему дело в packet rate сетевой карты.
При 1 гигабите получается около 170000 пакетов в секунду,
что эквивалентно 34000 полных соединений в секунду.Вопрос в том, что такой пэкетрэйт для 1 gige должен
быть для пакетов размером около 1560 байт.В теории с меньшими пакетами должен быть больший
пэкетрэйт. Вопрос теперь в том, как уже с этим бороться :)
>Судя по всему дело в packet rate сетевой карты.
>При 1 гигабите получается около 170000 пакетов в секунду,
>что эквивалентно 34000 полных соединений в секунду.
>
>Вопрос в том, что такой пэкетрэйт для 1 gige должен
>быть для пакетов размером около 1560 байт.
>
>В теории с меньшими пакетами должен быть больший
>пэкетрэйт. Вопрос теперь в том, как уже с этим бороться :)так ты чего вместо 32тыщ хочешь 34 получить? :)
>>Судя по всему дело в packet rate сетевой карты.
>>При 1 гигабите получается около 170000 пакетов в секунду,
>>что эквивалентно 34000 полных соединений в секунду.
>>
>>Вопрос в том, что такой пэкетрэйт для 1 gige должен
>>быть для пакетов размером около 1560 байт.
>>
>>В теории с меньшими пакетами должен быть больший
>>пэкетрэйт. Вопрос теперь в том, как уже с этим бороться :)нашел на опененте подборку: http://www.opennet.me/links/sml/91.shtml
>[оверквотинг удален]
>>>При 1 гигабите получается около 170000 пакетов в секунду,
>>>что эквивалентно 34000 полных соединений в секунду.
>>>
>>>Вопрос в том, что такой пэкетрэйт для 1 gige должен
>>>быть для пакетов размером около 1560 байт.
>>>
>>>В теории с меньшими пакетами должен быть больший
>>>пэкетрэйт. Вопрос теперь в том, как уже с этим бороться :)
>
>нашел на опененте подборку: http://www.opennet.me/links/sml/91.shtmlвот еще по тюнигу, а то там все старое
http://xgu.ru/wiki/TCP_tuning
>[оверквотинг удален]
>связь, как через свич, так и напрямую, через кабель соединяющий два
>порта.
>
>При обработке соединений сервером, когда accept делается одним серверным потоком производительность примерно
>32 000 обработанных соединений в секунду. Когда accept делается четырьмя серверными
>потоками с мутексами или без - производительность та же.
>
>Проблема, вероятно, в сериализации accept(). Хотя может быть и в другом -
>тюнинг параметров TCP не помог :)
>а почему вы решили что параллельный вызов accept() из
разных потоков решит проблему ? сокет-то один - и
очередь входящих соединений у него тоже одна..
Проблема судя по всему не в акцепте и не в стеке TCP, а в ethernet frame rate.Я пробовал различные настройки, которые оптимизированя для гигабитного езернета (включая различные режимы прерываний).
Несмотря на любой тюнинг на сейчас - это не особо не помогло. При больших пакетах трафик вырос с 88 до 90 мегабайт в секунду - едва заметное улучшение.
Скорость передачи пакетов в любом случае около 170000 пакетов в секунду, что для гигабитного линка мало, если используются небольшие пакеты. Пакетная скорость для небольших пакетов для гигабитного езернета должна быть, как минимум в несколько раз выше.
Кажется, что даже когда отсылается небольшой TCP-пакет, то драйвер заворачивает его внутрь неоостветственно большего ethernet-пакета. Каким хитрым способом подебагить raw ethernet? :)
>[оверквотинг удален]
>При больших пакетах трафик вырос с 88 до 90 мегабайт в
>секунду - едва заметное улучшение.
>
>Скорость передачи пакетов в любом случае около 170000 пакетов в секунду, что
>для гигабитного линка мало, если используются небольшие пакеты. Пакетная скорость для
>небольших пакетов для гигабитного езернета должна быть, как минимум в несколько
>раз выше.
>
>Кажется, что даже когда отсылается небольшой TCP-пакет, то драйвер заворачивает его внутрь
>неоостветственно большего ethernet-пакета. Каким хитрым способом подебагить raw ethernet? :)возмьите свитч гигабитный, и настройте на нем порт мироринг. подсоедините еще одну линуху и тспдамп-ом.