На моем сервере есть один большой файл. Я нахожу, что многопоточная загрузка может получить 20 Мбит, но одна нить может получить 10 Мбит, кто-нибудь может объяснить это?
4 ответа
Обычно это происходит потому, что где-то между вами и другим сервером существует брандмауэр, ограничивающий каждый поток HTTP до 10 Мбит / с. Когда вы используете многопоточность, вы получаете 2x 10 Мб (по одному для каждой нити).
Это связано с вашим пингом между вами и сервером и размером окна / размера окна tcpip, используемого вашей загружаемой программой.
По сути, если у вас 100 мс на сервер и вы запрашиваете пакеты размером 100 Кб, вы можете получать только 10 пакетов в секунду, используя 1 соединение, даже если ваша скорость интернета бесконечна.
TCP работает лучше всего, когда вы "держите канал заполненным" - когда отправляющее приложение продолжает посылать буферы достаточно быстро, чтобы стек TCP отправителя постоянно получал данные, так что он всегда мог иметь данные "в полете" в сети, и когда получатель приложение продолжает читать из получающего TCP-стека достаточно быстро, чтобы окно TCP получателя никогда не заполнялось (опять же, поэтому отправляющий TCP-стек всегда может хранить данные "в полете" в сети).
Я мог бы представить плохо написанное однопоточное приложение отправителя, которое передает один буфер в стек TCP, ждет, когда он полностью Acked, а затем передает другой буфер. Это означает, что как только конец первого буфера "в полете" в сети, отправляющему стеку TCP не хватает данных для отправки, что означает, что канал истощается и не заполняется до тех пор, пока не вернется Ack и приложение-отправитель. передает ему новый буфер.
Я мог бы также представить плохо написанное однопоточное приложение-получатель, которое недостаточно быстро читает из принимающего TCP-стека и, таким образом, позволяет заполнять буферы TCP-стека, что означает, что окно TCP заполняется, что приводит к тому, что отправляющий TCP-стек прекратить отправку, пока не откроется окно. Увеличение размера окна TCP получателя может немного помочь, но реальным решением в этом случае является более быстрое считывание данных.
Ну, это, вероятно, потому что вы можете передавать столько данных только через одно соединение. Однако в многопоточной программе вы можете иметь два соединения, которые получают данные одновременно и удваивают объем информации, которую вы можете получить. Есть некоторые ограничения, например, скорость сервера, с которого вы скачиваете ... Снимаю шляпу у двух, кто бы ни написал многопоточный загрузчик, это нелегко написать.