четверг, 16 июня 2011 г.

Работа в сети с высокими задержками означает, что вам нужно "покупать оптом"

Это перевод Computing over a high-latency network means you have to bulk up. Автор: Реймонд Чен.

Одна из больших жалоб на Проводник, которые мы получали от корпораций, заключалась в том, насколько часто Проводник дёргал сеть. Если компьютер, к которому вы получаете доступ, находится в соседней комнате, то это не имеет большого значения, потому что вы быстро получаете отклик. Но если компьютер, с которым вы общаетесь, находится в офисе на другом конце земного шара, то даже, если вы сможете общаться на максимальной теоретически возможной скорости (а именно: скорости света), то 66 миллисекунд уйдёт на то, чтобы ваш запрос достиг второго компьютера, и 66 миллисекунд на обратное путешествие ответа. На практике всё происходит ещё медленнее. Задержка в полсекунды не так уж необычна для глобальных сетей. А для спутниковых сетей типичны задержки в одну-две секунды.

Заметьте, что задержка (latency) и ширина канала (bandwidth) являются независимыми метриками. Ширина канала показывает как быстро вы можете отправлять данные. Она измеряется в данных за единицу времени (вроде бит в секунду); задержка - это сколько времени у данных займёт перенос до получателя. Она измеряется во времени (например, в миллисекундах). Даже хотя глобальные сети имеют большие пропускные способности, но высокая задержка может вас убить.

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

Перечисление папок в Проводнике - это нечто большее, чем просто получение файловых имён. Папке Оболочки нужны метаданные, вроде даты последней модификации и размера, чтобы создать структуру SHITEMID, которая является основой для идентификации элементов в Оболочке. Ещё один кусочек информации, который нужен Оболочке - это файловый индекс: 64-битное значение, которое уникально для каждого файла тома. Но эта информация не возвращается "медленной" FindNextFile. В результате Оболочке нужно делать до трёх операций, чтобы вернуть эту информацию:
  • CreateFile
  • GetFileInformationByHandle (которая возвращает индекс файл в записи BY_HANDLE_FILE_INFORMATION),
  • CloseHandle.
Если у вас сеть с задержкой в 500 миллисекунд, то эти три дополнительные операции добавляют полторы секунды к каждому файлу в каталоге. Если в каталоге всего 40 файлов, то это будет целая минута - и только на получение файловых индексов (как мы видели прошлый раз, FindNextFile выполняет собственное внутреннее кэширование, чтобы избежать этой проблемы при выполнении типичного перечисления содержимого папки).

И вот где на сцену выходит "fast mode". Запрос в "быстром режиме" - это ещё один тип оптового запроса, при котором сервер возвращает всю необходимую информацию за раз. В результате информация о файловых индексах располагается поверх существующей информации в стиле FindNextFile. Вот что делает запрос быстрым. В "быстром" режиме перечисление 200 файлов из каталога займёт несколько секунд (два "оптовых" запроса для FindNextFile, которые вернут всю информацию, включая индексы, за один заход, плюс небольшие издержки на обслуживание соединения). В "медленном" режиме это время уйдёт только на получение типичной информации FindNextFile, получение файловых индексов добавит ещё полторы секунды для каждого файла, получая в итоге 1.5 × 200 = 300 секунд или 5 минут.

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

Если ваша программа будет работать в многонациональных корпорациях, то вам придётся принять высокие задержки сетей во внимание. И это означает "покупку оптом".

Стороннее замечание: некоторые люди обвинили меня в намеренном введении в заблуждение с характеристикой этой ошибки. Любое заблуждение с моей стороны было непреднамеренным. У меня не было всех фактов на руках, когда я писал первый пост, и даже сейчас у меня ещё не все факты. Например, FindNextFile использует оптовые запросы? Я не знал этого, пока не сел расследовать комментарии к посту во вторник - и это в то время, которое я должен был посвятить планированию ужина в среду (да, я лентяй и не планирую свои блюда на неделю за раз, как это делают организованные люди).

Заметьте, что это упражнение всё ещё ценно как мысленный эксперимент. Предположим, что FindNextFile не использует оптовые запросы, но проблема действительно проявляет себя только после 101-го запроса. Как бы вы её исправили?

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

Комментариев нет:

Отправить комментарий

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.