5

Что делать, если я загружал файл напрямую на устройство, скорость записи которого значительно ниже скорости загрузки интернет-соединения.

  • Переносятся ли ожидающие записи данные в буфер или временное хранилище?

  • Зависит ли это поведение от операционной системы или браузера или, возможно, от чего-то еще?

И если есть проблема, могу ли я что-нибудь сделать, чтобы предотвратить ее?

4 ответа4

4

То, что я ожидал бы случиться, является одной-двумя вещами:

  1. Процесс, запрашивающий данные, будет буферизовать "избыток" в памяти.

    или более вероятно:

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

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

3

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

  1. Сначала заполняется окно приема стека, чуть меньше полной скорости передачи данных в сети. Он заполняется медленнее, чем скорость линии в сети, из-за алгоритма медленного запуска TCP и других эффектов поведения стеков TCP/IP.

    Окно TCP может быть до 128 КиБ (менее 1 байта) на моем компьютере с Linux. (Скажите sysctl net.core.rmem_max чтобы получить значение вашего ящика.) Однако обычно он меньше этого максимума. По умолчанию на моей коробке 4 КиБ. (Скажите sysctl net.ipv4.tcp_rmem чтобы получить это значение.)

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

    Размер буфера полностью зависит от программиста приложения. В программах, которые я написал, я использовал где-то от примерно дюжины байтов до 64 КиБ, в зависимости от потребностей приложения. Я сделал вывод об использовании гораздо больших буферов (Mi1 МиБ) в других приложениях, наблюдая за их поведением.

  3. Приложение будет почти наверняка будет использовать какой - то забуференном механизм ввода / вывода для записи файла, например, C «s STDIO. Обычно это не менее 1 КиБ, а может быть несколько КиБ. На моем ящике здесь, кажется, по умолчанию 8 КиБ.

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

  4. Драйвер устройства для запоминающего устройства может иметь некоторую буферизацию. Это, вероятно, не так много, но одностраничный буфер объемом 4 КиБ не был бы неразумным.

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

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

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

1

ОС / приложение просто снизит скорость загрузки. Просто загрузите файл из локальной сети 1 Гбит на старый USB1-накопитель и убедитесь сами.

1

Если основным протоколом является TCP (например, HTTP), то проблем не будет. Ваш загрузчик имеет буфер в памяти, где он временно хранит данные, которые были загружены. Он постоянно записывает данные из этого буфера на диск. Если диск работает медленно, буфер заполнится, и загрузчик не будет запрашивать у операционной системы больше данных с удаленного сервера. Это означает, что аналогичный буфер в драйвере Windows TCP заполняется. Протокол TCP гарантирует, что у вас не будет проблем, если чьи-то буферы заполнятся:

http://en.wikipedia.org/wiki/Transmission_Control_Protocol#Flow_control

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

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

Таким образом, когда буфер драйвера TCP заполнен, он не будет подтверждать другому компьютеру, что он готов получить больше данных.

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .