Рассмотрим приложение для кэширования с тысячами запросов в секунду, когда клиент запрашивает объект с помощью целочисленного индекса, а сервер отправляет объект обратно к нему.(Только для Linux)
Что будет быстрее для протокола UDP:
- Отправить несколько ответов в одном пакете?
- Отправить один ответ в одном пакете?
(применимо для обеих сторон, сервера или клиента)
Недостатки:
Похоже, что оба метода имеют свои недостатки, и неясно, какое решение будет лучше, однако тактовая частота гигабитного Ethernet работает на частоте 1 ГГц, в то время как процессор, например, 3 ГГц, также шина памяти намного шире, чем витая пара.интерфейс Ethernet.Таким образом, несколько ответов для каждого пакета будет лучшим выбором, поскольку дополнительные memcpy () уменьшат сетевой трафик, верно?
Теперь, если мы будем использовать TCP вместо UDP:
- Несколькоответы на пакет:
- снова, много memcpy () потребуется для сборки пакета, который не должен быть больше 65535, а затем он будет фрагментирован ядром для отправки его в пакетах размером MTU Здесь нет большой разницы, как в случае UDP
- Один ответ на пакет:
- Поскольку наши 16-байтовые объекты распределяются случайным образом в памяти сервера, мы будемнеобходимо выдавать системный вызов write () для каждого объекта, то же количество системных вызовов, что и для udp один запрос.
- каждый get () приведет к накладным расходам в 52 байта из-за этого TCPимеет больший заголовок + нам понадобится еще один заголовок пакета ACK, который составляет около 40 байтов. еще больший сетевой трафик
Вывод:
- Для этого конкретного приложения (отправка простого блока данных клиенту изиндекс, указанный клиентом) TCP не будет работать лучше, чем UDP .+ учтите, что реализация стека TCP намного сложнее, чем UDP, там выполняется больше инструкций. Весь смысл для ускорения работы протокола состоит в том, чтобы собрать пакеты UDP как можно большего размера для MTU .
- Стоимость добавления другого сетевого адаптера в систему ниже, чем добавления другого центрального процессора.,Имеет смысл пойти на снижение количества memcpy (), но отправлять кучу небольших пакетов UDP и доплачивать за издержки каждого заголовка udp на стороне сети (+ немного больше накладных расходов, выполняя множество системных вызовов sendto (), которыея думаю, что будет ниже, чем издержки memcpy ()), потому что таким образом с одним ЦП можно будет отправлять запросы на многие сетевые карты
. Буду очень признателен за ваши комментарии и опыт выбора протокола.
Примечание: давайте оставим в стороне вопросы надежности и предположим, что в наших сетях нет ошибок, чтов большинстве случаев верно, если вы подключили их правильно, и если произошла ошибка, это, конечно, не норма