Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

Секреты производительности сетевых приложений для мобильных устройств

Глава 10 из книги "Производительность приложений с открытым исходным кодом".

Оригинал: Secrets of Mobile Network Performance
Автор: Bryce Howard
Перевод: А.Панин

Производительность сетевых протоколов

Теперь поговорим о вещах, которые мы можем как-либо контролировать.

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

Сетевые протоколы
Рисунок 10.3 - Сетевые протоколы

Протокол управления передачей

Протокол управления передачей (Transport Control Protocol - TCP) является ориентированным на создание сессий сетевым транспортным протоколом, реализованным на основе соглашений межсетевого протокола IP. Протокол TCP позволяет создавать безопасные двунаправленные соединения, необходимые для работы других протоколов, таких, как HTTP или TLS.

На уровне протокола TCP выполняется большое количество обращений сообщений, которых мы стремимся избежать. Некоторые из них могут быть устранены путем внедрения таких расширений протокола, как Fast Open. Другие могут быть минимизированы путем подстройки таких параметров системы, как размер начального окна перегрузки (initial congestion window). В данном разделе мы рассмотрим оба этих подхода, попутно обращая внимание на внутренние механизмы протокола TCP.

Расширение Fast Open протокола TCP

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

Трехэтапное рукопожатие TCP позволяет достичь соглашения, касающегося параметров взаимодействия между клиентом и сервером, благодаря которому становится возможным установление двухсторонней связи между ними. Начальное сообщение SYN (синхронизация - synchronize) является запросом соединения от клиента. В случае приема соединения, сервер ответит сообщением SYN-ACK (синхронизация и подтверждение - synchronize и acknowledge). Наконец, клиент подтвердит намерение установления соединения с сервером с помощью сообщения ACK. В этот момент логическое соединение является установленным и клиент может начинать передачу данных. Если вы были внимательны, вы могли заметить, что трехэтапное рукопожатие приводит к задержке, эквивалентной как минимум текущему времени обращения.

Трехэтапное рукопожатие протокола TCP
Рисунок 10.4 - Трехэтапное рукопожатие протокола TCP

Традиционно не существовало способа устранения задержки, вызванной трехэтапным рукопожатием, за исключением повторного использования соединения. Однако, не так давно благодаря созданию спецификации IETF TCP Fast Open, ситуация изменилась.

Расширение TCP Fast Open (TFO) позволяет клиенту начинать отправку данных перед тем, как соединение становится логически установленным. Эта возможность позволяет практически свести на нет все задержки трехэтапного взаимодействия. Кумулятивный эффект данной оптимизации впечатляет. В соответствии с исследованием компании Google, расширение протокола TFO позволяет снизить время загрузки страниц на целых 40%. Хотя спецификация все еще представлена в форме черновика, расширение TFO уже поддерживается основными браузерами (Chrome 22+) и платформами (Linux 3.6+), при этом другие разработчики программного обеспечения также собираются добавить в свои программные продукты код для его поддержки в ближайшее время.

Расширение TCP Fast Open является модификацией механизма трехэтапного рукопожатия, позволяющей размещать небольшой объем данных (например, данные запроса HTTP) в сообщении SYN. Эти данные передаются серверу приложения в процессе завершения рукопожатия таким же образом, как это могло быть сделано в ином случае.

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

Существуют незначительные недоработки, препятствующие использованию расширения TFO. Наиболее известной является отсутствие каких-либо идемпотентных гарантий доставки данных запроса, переданных вместе с начальным сообщением SYN. Протокол TCP гарантирует, что дубликаты пакетов (дупликация пакетов происходит достаточно часто) будут проигнорированы на принимающей стороне, но аналогичной гарантии не предоставляется в случае рукопожатия при установлении соединения. Существуют инициативы по стандартизации решения в рамках черновика спецификации, но на сегодняшний день расширение TFO все же может применяться для идемпотентных транзакций.

Начальный размер окна перегрузки

Начальный размер окна перегрузки (initial congestion window - initcwnd) является настраиваемым параметром протокола TCP, обладающим большим потенциалом ускорения небольших по объему сетевых транзакций.

В новой редакции спецификации IETF приводится рекомендация относительно повышения стандартного значения начального размера окна перегрузки с 3 сегментов (т.е., пакетов) до 10. Это предложение основывается на проведенных компанией Google сложных исследованиях, демонстрирующих повышение производительности в среднем на 10%. Цель и потенциальное повышение производительности из-за изменения данного параметра сложно оценить без понимания принципа работы окна перегрузки (congestion window - cwnd) протокола TCP.

Протокол TCP дает гарантии надежной передачи данных клиенту и серверу при работе с ненадежным сетевым соединением. Данные гарантии включают в себя обещание о том, что все данные будут приняты в том виде, в котором они были отправлены или, по крайней мере, считаются отправленными; это обещание подразумевает необходимость использования механизмов определения, коррекции и предотвращения повреждений данных.

Протокол TCP использует соглашение о подтверждении успешно выполненных операций (positive acknowledgement convention) для определения отсутствующих пакетов, благодаря которому факт приема любого и каждого отправленного пакета должен быть подтвержден принимающей стороной, а отсутствие подтверждения говорит о том, что пакет был потерян по пути. В процессе ожидания подтверждений доставки, пакеты находятся в специальном буфере, называемым окном перегрузки. В момент, заполнения данного буфера наступает событие, известное, как заполнение окна перегрузки (cwnd exhaustion) и передача данных прекращается до того момента, когда принимающая сторона сможет подтвердить прием пакетов, освободив тем самым место для отправки новых пакетов. Эти события оказывают непосредственное воздействие на производительность протокола TCP.

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

В условиях отсутствия возможности точного определения емкости сети, протокол TCP вычисляет ее значение на основе размера окна перегрузки. Протокол TCP будет расширять окно перегрузки до того момента, когда станут наблюдаться потери пакетов, которые указывают на то, что одна из удаленных сетей не может передавать данные в текущем темпе. Применяя эту схему защиты от переполнения (congestion avoidance scheme) протокол TCP в конце концов минимизирует частоту событий заполнения окна перегрузки до того значения, при котором в рамках соединения происходит использование всей доступной емкости сети. И сейчас, наконец, мы подходим к цели и обоснованию необходимости установки начального размера окна перегрузки протокола TCP.

Размер окна перегрузки не может быть определен без выявления признаков потери пакетов. Новое или бездействующее соединение не имеет признаков потери пакетов, необходимых для установления оптимального размера окна перегрузки. Протокол TCP устанавливает, что лучше начать работу с окном перегрузки, которое с наименьшей вероятностью приведет к перегрузке сети; обычно это делается путем установки размера окна перегрузки в 1 сегмент (~ 1480 байт), причем в течение некоторого времени существовала именно такая рекомендация. Последующие эксперименты показали, что даже такое высокое значение параметра, как 4 может быть эффективным. На практике вы обычно будете сталкиваться с начальным размером окна перегрузки в 3 сегмента (~ 4 КиБ).

Начальный размер окна перегрузки влияет на скорость сетевых транзакций небольшого размера. Данный эффект несложно проиллюстрировать. При использовании стандартной настройки в 3 сегмента событие заполнения окна перегрузки наступит только после отправки 3 пакетов или 4 КиБ. Предполагая, что пакеты были отправлены последовательно, можно с точностью сказать, что доставка подтверждений будет осуществлена не быстрее времени обращения данных в рамках соединения. В том случае, если время обращения (RTT) равно, к примеру, 100 мс, эффективная скорость передачи данных будет ограничена значением 400 байт в секунду. Несмотря на то, что протокол TCP в конце концов увеличит размер окна перегрузки с целью полноценного использования доступной емкости сети, скорость передачи пострадает из-за очень медленного старта. Фактически, это ситуация описывается термином "медленный старт" (slow start).

Ввиду значительного воздействия медленного старта на производительность операций загрузки небольших объемов данных, возникает желание взвешенного рассмотрения возможности изменения начального размера окна перегрузки. Сотрудники компании Google выполнили эту задачу и выяснили, что размер начального окна перегрузки в 10 сегментов (~ 14 КиБ) позволяет достичь большей пропускной способности соединения с меньшей вероятностью перегрузки. Реальные тесты демонстрируют сокращение времени загрузки страниц в среднем на 10%. Тесты соединений с завышенными задержками обращения данных могут продемонстрировать даже лучшие результаты.

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


Продолжение статьи: Протокол передачи гипертекста.