Надежность Tcp против бремени Udp для серьезного, высокопроизводительного сервера - PullRequest
8 голосов
/ 01 марта 2010

Скорость, оптимизация и масштабируемость являются типичными сравнениями протоколов Udp и Tcp.Tcp ставит надёжность с недостатком в виде небольшого дополнительного накладного расхода, но скорость от хорошей до превосходной.После создания экземпляра Tcp-сокета для его сохранения требуется некоторые накладные расходы.Но по сравнению с часто описанным бременем Udp, какой протокол на самом деле имеет больше накладных расходов?Я также слышал, что с Tcp есть проблемы с масштабируемостью ... но Интернет (веб-страницы / серверы) работает на Tcp - так что же такое с Tcp, который препятствует масштабируемости?

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

В основном, мои вопросы:

  1. Почему я бы выбрал Udp вместо Tcp для серьезного, высокопроизводительного сервера с дополнительными «издержками» проверки сообщений и ручного ACK по сравнению с«накладные расходы» непрерывного потока?
  2. Если Tcp достаточно хорош для подобных World of Warcraft, почему Tcp более широко не принят как протокол, используемый для игрового сервера?

Примечание: я не против реализации опций Udp для сервера.Мы используем C # на .Net 3.5 framework.Поэтому меня также интересовали бы лучшие практики по борьбе с бременем Udp .Я также использую асинхронные методы на уровне socket вместо использования TcpListener, TcpClient и т. Д. И т. Д.

Ответы [ 5 ]

12 голосов
/ 01 марта 2010

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

Однако эта ссылка может вас заинтересовать больше всего, так как она непосредственно касается программирования сетевых игр:

Если бы я цитировал что-то маленькое:

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

Неправильно.

Использование TCP наихудшее из возможных ошибка, которую вы можете сделать при разработке сетевая игра! Чтобы понять почему, вы нужно посмотреть, что на самом деле делает TCP выше IP чтобы все выглядело так простой!

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

7 голосов
/ 02 марта 2010

Во-первых, я просто перефразирую Стивенса из Сетевое программирование Unix Раздел 22.4 "Когда использовать UDP вместо TCP":

Он в основном говорит следующее:

  1. UDP является единственной опцией для широковещательной / многоадресной рассылки - поэтому вы должны использовать ее там.
  2. UDP может использоваться для простых приложений запроса / ответа. Но вы должны добавить свое собственное обнаружение ошибок, означающее как минимум подтверждение, превышение времени ожидания и повторную передачу.
  3. UDP не следует использовать для массовой передачи данных (передачи файлов), поскольку для правильной работы необходимо встроить все функции, имеющиеся в TCP,
  4. UDP следует использовать для данных в режиме реального времени, где скорость доставки является наиболее важной, и некоторые потери данных не являются проблемой, такие как данные датчиков в реальном времени, прямые мультимедийные потоки, котировки акций в реальном времени и т. Д.

Ответ на ваш первый вопрос очень зависит от вашего определения «высокая производительность». Если вас больше всего беспокоит низкая задержка, то есть отдельные пакеты / запросы данных, поступающие настолько быстро, насколько это возможно, чем UDP. Для этого есть две основные причины. Предполагая, что пакеты / запросы довольно независимы друг от друга, чем при использовании TCP, возникнет проблема, известная как блокировка заголовка .

Допустим, вы отправили два независимых пакета / запроса. Сначала A, а затем B. Поскольку TCP основан на потоке, если A get теряется в сети и нуждается в повторной передаче, то даже если B уже успешно прибыл, он не может быть доставлен в приложение стеком до тех пор, пока A не прибудет, что приводит к ненужным задержкам. , Не только это, но и до прибытия A, стек не может быть подтвержден B, что может привести к повторной передаче B, что приведет к ненужной перегрузке сети.

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

Другая проблема в высокопроизводительных (с низкой задержкой) серверах - это алгоритм Nagle , который может добавить значительную задержку при обмене данными по TCP.

Ответ на ваш второй вопрос заключается в том, что WoW, вероятно, отправляет потоки данных, а не независимые пары запрос / ответ. Кроме того, некоторые задержки TCP могут быть устранены путем отключения алгоритма Nagle . Если они используют какую-либо связь запрос / ответ, они, возможно, просто приняли проектное решение, что надежность для них важнее, чем задержка.

4 голосов
/ 01 марта 2010

Определите «серьезную высокую производительность» - о скольких одновременных подключениях вы говорите и сколько данных передается?

Посмотрите на ответы на этот вопрос Что вы используете, когда вам нужнонадежный UDP? , который перечисляет некоторые из надежных протоколов, которые уже построены на UDP.Вы можете найти тот, который подходит для вашей ситуации, или вы можете, по крайней мере, найти некоторые полезные идеи.

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

Так что, ИМХО, если вам нужна 100% надежность И в доставке заказа, тогда идите с TCP;не пытайтесь переопределить TCP в UDP.

1 голос
/ 02 марта 2010

Надежность против производительности.

FPS-играм не требуется, чтобы все пакеты доставлялись к месту назначения, достигали его по порядку, были исключительно большими или обеспечивали большую пропускную способность. Они только требуют, чтобы пакеты достигли сервера КАК СКОРО, КАК ВОЗМОЖНО. Это конечный приоритет, а издержки TCP - просто ненужное бремя.

WoW, в его связи "не совсем в реальном времени" и часто тоннах данных для передачи (в многолюдных областях), возможно, придется иметь дело с пакетами, превышающими MTU (требующие фрагментации) и требующими надежности (меньше больших пакетов = потеря пакетов вредит большему ). Так что его выбор TCP логичен. То же самое можно сказать о большинстве пошаговых стратегических игр и тому подобное. В играх, где игрок с пингом 30 мс бьет игрока с пингом 50 мс, UDP - король.

1 голос
/ 01 марта 2010

Я думаю, что самая большая часть TCP / IP, которая препятствует масштабируемости, состоит в том, что она поддерживает буфер для всех входящих / исходящих соединений вплоть до размера окна. Поэтому, если у меня клиент с высокой задержкой и высокой пропускной способностью, с которым я разговариваю, я должен хранить все отправленные пакеты в буфере, пока не получу подтверждение. Так что для некоторых соединений это нормально, но для обработки 100К соединений это может стать проблематичным. На принимающей стороне, если пакет отброшен, он снова буферизирует все новые принятые пакеты до тех пор, пока требуемый не будет повторно передан.

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

пакет 1 = перейти к 1,1 пакет 2 = стрелять пакет 3 = перейти к 2,2

Большинство разработчиков игр, если пакет 1 потерян, но пакет 3 получен, пакет 1 больше не важен, потому что он в любом случае содержит устаревшую информацию. Однако можно сказать, что пакет 2 важен, поэтому, если он не подтвержден, отправьте повторную передачу.

Если вам требуется высокая пропускная способность и подключение двух серверов напрямую с сетью Ethernet 1000 Мбит / с, TCP / IP потребуется некоторое время для масштабирования и дополнительных издержек, и, скорее всего, никогда не будет установлено истинное гигабитное соединение из-за механизмов предотвращения перегрузки. Однако вы знаете, что это 1 Гбит / с, поэтому вы можете настроить свой UDP для передачи со скоростью до 1 Гбит / с (минус накладные расходы) самостоятельно.

Чтобы ответить на ваши вопросы более прямо: В любом случае, если вы собираетесь подтверждать каждый пакет, использование UDP не имеет большого преимущества, кроме того, что вы можете обрабатывать некоторые сообщения в ожидании повторной передачи (если вы не хотите также и доставку по порядку).

Udp не учитывается для игровых серверов, в основном из сценария, описанного выше, и для боевых систем реального времени, таких как шутеры от первого лица, где сообщение может быть отброшено, а новое пришедшее сообщение сделает недействительным пропущенное сообщение в любом случае. World of Warcraft может обойтись без использования TCP, так как они не должны быть такими точными с точки зрения времени и, вероятно, имеют хорошую логику, которая в любом случае затруднит вам заметить разницу. Боевая система просто не требует скорости.

Я бы также утверждал, что некоторые оправдания остались в прошлом, когда у всех были менее надежные и медленные интернет-соединения. TCP также более удобен для совместного использования сети, поэтому, если что-то происходит, он будет замедляться, поэтому каждый получит долю подключения (предотвращение перегрузки).

TCP / IP - это протокол, разработанный людьми, намного умнее меня за годы исследований. Настройка за последние несколько лет позволила ему работать лучше с более высокими и быстрыми средними скоростями сети, которые мы наблюдаем, и не требует большого понимания для использования.

Однако замена этого на UDP требует значительного понимания работы в сети. Я видел плохо написанные UDP-программы, насыщающие ссылки со скоростью 1 Гбит / с и уничтожающие весь трафик на линии, потому что они реализовали довольно наивный алгоритм повторной передачи.

Вот список вещей, которые TCP / IP теперь может сделать, что вы потеряете, перейдя по UDP: - Для того, чтобы прибытие в вашу программу - повторная передача (теперь с быстрой повторной передачей, выборочным подтверждением и другими функциями) - максимальный размер сегмента - Path MTU Discovery - Обнаружение черной дыры (расширение Path MTU) - предотвращение заторов

В связи с этим я настоятельно рекомендую придерживаться протокола TCP / IP, если он вам подходит.

Тоже не задирать, но вы комментируете, что интернет, работающий по TCP / IP, неправильный, на самом деле существуют десятки маршрутизируемых интернет-протоколов проверьте их здесь Я думаю, что вы имели в виду веб-страницы, и все веб-серверы работают поверх TCP / IP. Что опять-таки для сети замечательно, когда мы, люди, не заметим задержки, если страница отображается правильно. Даже для TCP / IP существует некоторая проблема, заключающаяся в том, что TCP / IP недостаточно агрессивен для Интернета: Google считает, что tcp / ip должен быть более агрессивным по умолчанию

...