TORRENT & eMule – добро или зло?

imageМногие пользователи p2p-клиентов замечали, что при их работе, пользоваться интернетом практически невозможно – соединение дико тормозит. Попробуем разобраться почему.

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

Основной идеей протокола TCP является гарантированная доставка всех пакетов и их сборка в единый кусок информации. Цель достигается следующим образом – перед отправкой каждому пакету данных присваивается уникальный порядковый номер, называемый sequence number. По этим номерам, в конечной точке маршрута, пакеты собираются в единое целое в правильном порядке, даже если часть пакетов задержится в пути и прибудет позже остальных. Это может случиться потому, что интернет штука динамичная, и попасть в точку назначения пакеты могут разными маршрутами – это как в городе, если отправить 100 таксистов из точки А в точку Б, вовсе не факт что они все паровозиком попрут одним путем, равно как и то, что приедут они в том порядке, в котором выехали.

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

Как показала практика, качество связи обычно достаточно высокое, и отправлять уведомление после получения каждого пакета данный не особо эффективно – это забивает канал связи кучей уведомлений, и что более критично, вынуждает канал бездействовать некоторое время. Бездействовать, потому что отправляющая сторона ждет уведомления о успешной доставке пакета, перед отправкой следующего. Чтобы повысить эффективность процесса был придуман принцип передачи, называемый windowing (плавающее окно). Суть его заключается в том, что сначала передается один пакет, и, если он доходит без проблем, при следующей передаче отсылаются два пакета, и если они доходят без проблем, то отсылаются три пакета и т.д. Получается, что скорость передачи постепенно растет, пока не наступает момент, когда какой-то пакет теряется или повреждается. В этот момент передача обрывается, и вся процедура начинается по новой – с передачи одного пакета.

TCP_2В противоположность TCP, основным приоритетом UDP является скорость. В пакетах UDP нет порядковых номеров и уведомлений – информация просто делится на пакеты и отправляется. Получатель на лету собирает пакеты в единое целое, в том порядке, в котором они к нему приходят (даже если часть пакетов потерялась в пути, а другая часть пришла с опозданием). Такая тактика оказывается очень полезной например в онлайн играх, онлайн видео и аудио и IP-телефонии. Например в том-же SKYPE при потере значительной части пакетов, речь все еще останется разборчивой. А это гораздо лучше, чем прерывистая речь, которая получилась бы при использовании TCP протокола и проблемах со связью. Опять-же, нельзя забывать, что как правило, связь стабильна и большинство пакетов доходит вовремя, в целости и сохранности. Кроме того в сетевом оборудовании, приоритетность UDP пакетов в общем траффике по умолчанию выше, чем у TCP пакетов.

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

Теперь, давайте разберемся с тем, как интернет-провайдер реализует оплаченную вами ширину канала связи, которую p2p-клиенты так удачно забивают до отказа. На стороне провайдера существуют специальная аппаратура, которая реализует так называемый pipe, который ограничивает входящий и исходящий траффик точно по ширине оплаченного потребителем канала. Технология похожа на водопроводный кран – чем больше платим, тем больше нам открывают кран. Все пакеты с информацией приходящие к pipe’у становятся в очередь, и pipe начинает их “стравливать” потребителю с максимально доступной для оплаченного тарифного плана скоростью. Пакеты находящиеся в очереди слишком долго (что-то вроде 5 секунд, по дефолту, если опять-же мне не изменяется склероз) устаревают и выбрасываются из очереди, ну или по умному, дропаются (от англ. drop – падать, бросать). Именно тут, в очереди, если она становился слишком большой, и не успевает “стравливаться” получателю, часто гибнут пакеты UDP, и прерываются передачи TCP.

В протоколе TCP, в отличие от UDP, есть еще такая важная штука как flow control. Кроме массы других полезностей, flow control легко распознает заторы на pipe’ах получателей и решает проблему – отправитель начинает медленнее слать пакеты, так что затор на pipe’е получателя разгружается.

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

TCP_3Ну, вернемся пока к TCP. Несмотря на все ухищрения протокола, все равно возникает ситуация, что канал связи то нагружается, то проседает. Чтобы решить эту проблему, были придуманы многопоточные закачки. Суть сводится к тому, что одновременно передается несколько потоков данных, и обрывы передач происходят в произвольном порядке, так, что в среднем канал загружается равномерно, а pipe дропает минимум пакетов:

TCP_1При этом, всему есть предел, так как слишком большое количество одновременных потоков вызывает частые срывы передач, и в результате эффективность всего предприятия падает.

Когда p2p приложение открывает сессии скачивания по TCP, при условии, что файл популярный и есть достаточно пользователей, готовых залить его нам, то на входе в pipe у провайдера образуется небольшой затор из кучи TCP сессий, который довольно быстро разруливается flow control’ем, так чтобы все сессии вместе взятые как раз и заняли примерно всю ширину купленного пользователем канала. В таком режиме, если пользователь вдруг решит еще и порыться в инете, почитать новости, он легко сможет это сделать. Не с таким комфортом конечно, как при свободном канале связи, но сможет.

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

Но этого показалось мало. В p2p решили заюзать и UDP, чтобы выжать все соки из канала связи. Не имея в своем распоряжении никакого flow control’я, входящие UDP пакеты мощным потоком вливаются в широкий канал нашего провайдера, и становятся в бесконечную очередь перед pipe’ом. Естественно, большая часть всей этой очереди тупо дропается, и в итоге, от всей массы посланной нам информации остаются только рожки да ножки. Подумайте – провайдер получает дофига траффика, дропает львиную долю оного и остатки пропихивает нам в pipe. Улавливаете да, насколько это может быть невыгодным предприятием для провайдера, с финансовой точки зрения?

Фактически, при условии достаточного количества источников файла в p2p сети, при попытке его скачать через UDP, запускается DDOS атака на провайдера. Выйти в интернет в это время, естественно, нереально. Именно поэтому провайдеры не любят p2p. Ну или они еще просто не знают, что они его не любят.

Потому и получается, что половина траффика в интернете, это траффик p2p сетей, значительная часть которого никогда не доходит до получателя.

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

Как решение проблемы, я могу предложить отключить использование UDP протокола в настройках p2p клиента, а также опытным путем определить максимальное количество TCP сессий, при котором и качает неплохо, и в инете можно копаться без проблем. Я давно уже не юзал eMule, но в torrent клиентах такая политика решила абсолютно все мои проблемы. Уверен в осле результат будет тем-же, так как принцип скачивания идентичен.

Другим решением может явиться покупка супер-толстого супер-дорогого канала, забить который будет сложнее. Это поможет… На некоторое время.

АНОНС: вскоре статья о непонятной херне, творящейся с популярным торрент клиентом uTorrent.



У этой записи 2 комментариев

  1. Gidof

    Спасибо огромное. А я всё понять не мог почему у меня интернет падает когда торрент запускаю. Отключил UDP и прямо с новой силой заработал, да ещё и раздавать нормально стал.

Добавить комментарий