Как максимизировать http.sys производительность загрузки файла

Я создаю инструмент, который передает очень большие наборы данных потоковой передачи (возможно на порядке терабайт в едином потоке; обычно в десятках гигабайтов) от одного сервера до другого. Клиентская часть инструмента считает блоки из исходного диска и отправит их по сети. Сторона сервера будет читать, они блокируют сеть, и запишите им в файл на диске сервера.

Прямо сейчас я пытаюсь решить который транспорт использовать. Опциями является необработанный TCP и HTTP.

Я действительно, ДЕЙСТВИТЕЛЬНО хотите смочь использовать HTTP. HttpListener (или WCF, если я хочу пойти тем путем) помогают включить к Серверу HTTP API (http.sys), и я могу получить вещи как аутентификация и SSL бесплатно. Проблемой прямо сейчас является производительность.

Я записал простую тестовую обвязку, которая отправляет 128K блоки ПУСТЫХ байтов с помощью асинхронной идиомы ввода-вывода BeginWrite/EndWrite с асинхронным BeginRead/EndRead на стороне сервера. Я изменил эту тестовую обвязку, таким образом, я могу сделать, это с любым HTTP ПОМЕСТИЛО операции через HttpWebRequest/HttpListener, или простое использование записей сокета TcpClient/TcpListener. Для исключения проблем с сетевыми платами или сетевыми трассами оба, клиент и сервер находится на одной машине и связывается по localhost.

На моем тестовом сервере Windows 2008 R2 с 12 ядрами версия TCP этой тестовой обвязки может продвинуть байты в 450MB/s с минимальным использованием ЦП. На том же поле версия HTTP тестовой обвязки работает между 130MB/s и 200MB/s в зависимости от того, как я настраиваю его.

В обоих случаях использование ЦП является низким, и подавляющее большинство какой использование ЦП, там, время ядра, таким образом, я вполне уверен, мое использование C# и времени выполнения.NET не является узким местом. Поле имеет два процессора Xeon X5650 с 6 ядрами, 24 ГБ единственно оцениваемого DDR3 RAM, и используется исключительно мной для моего собственного тестирования производительности.

Я уже знаю о клиентских тонких настройках HTTP как ServicePointManager.MaxServicePointIdleTime, ServicePointManager.DefaultConnectionLimit, ServicePointManager.Expect100Continue, и HttpWebRequest.AllowWriteStreamBuffering.

У кого-либо есть какие-либо идеи для того, как я могу получить производительность HTTP.sys вне 200MB/s? Кто-либо видел, что он выполняет это хорошо на какой-либо среде?

ОБНОВЛЕНИЕ:

Вот немного больше детали о производительности, с которой я вижу TcpListener по сравнению с HttpListener:

Во-первых, я записал тест TcpClient/TcpListener. На моем тестовом поле, которое смогло продвинуть 450MB/s.

Затем с помощью отражателя я выяснил, как получить объект неструктурированного сокета базовый HttpWebRequest и изменил мой клиентский тест HTTP для использования этого. Все еще никакая радость; едва 200MB/s.

Моя текущая теория состоит в том, что http.sys оптимизирован для типичного варианта использования IIS, который является большим количеством параллельных маленьких запросов и большим количеством параллельных и возможно больших ответов. Я выдвигаю гипотезу, что для достижения этой оптимизации, MSFT должен был сделать так за счет того, что я пытаюсь выполнить, который является очень высокой пропускной способностью по единственному очень большому запросу с очень маленьким ответом.

Если это имеет значение я также попробовал ПОМЕЩЕННЫЕ операции до 32 параллельных HTTP, чтобы видеть, могло ли это масштабировать горизонтально, но не было все еще никакой радости; о 200MB/s.

Интересно, на моей рабочей станции разработки, которая является четырехъядерным Xeon Precision T7400, запускающим 64-разрядный Windows 7, моя реализация TcpClient о 200MB/s, и версия HTTP также о 200MB/s. После того как я беру его к Серверу выполнения машины класса сервера более высокого качества 2 008 R2, код TcpClient занимается 450MB/s, в то время как код HTTP.sys остается приблизительно 200.

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

15
задан anelson 15 May 2010 в 15:46
поделиться

2 ответа

Я не вижу особого интереса, кроме этой Технической заметки . Возможно, стоит поиграть с MaxBytesPerSend

2
ответ дан 1 December 2019 в 05:31
поделиться

Если вы собираетесь пересылать файлы по локальной сети, то лучше всего использовать UDP, потому что в этом случае накладные расходы TCP являются пустой тратой. TCP обеспечивает ограничение скорости , чтобы избежать слишком большого количества потерянных пакетов, тогда как с UDP приложение должно разбираться с этим само. NFS справился бы с этой задачей, если бы вы не застряли в окнах; но я уверен, что должен быть готовый UDP-материал. Также используйте инструмент «iperf» (доступный в Linux, возможно, также в Windows) для тестирования сетевого соединения независимо от протокола. Некоторые сетевые карты - просто дерьмо и слишком сильно зависят от процессора, что ограничивает вашу скорость до 200 Мбит. Вам нужна настоящая сетевая карта с собственными процессорами (не знаю точных терминов, чтобы выразить это).

0
ответ дан 1 December 2019 в 05:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: