Понимание внутреннего заполнения файлов для обеспечения быстрой загрузки клиентов

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

Моя идея реализации проекта:

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

Как мне написать код для такого сервера на бэкенде по аналогии с загруженными менеджерами многопоточности для клиентов на бэкенде?

Как сервер должен заполнять/предоставлять файл клиенту, если клиент отправляет путь только в виде строки на сервер в Java для загрузки?

Или, если я что-то упустил/моя идея совершенно неверна, пожалуйста, просветите меня альтернативным процессом/алгоритмом, который я должен реализовать на стороне сервера. Пожалуйста, помните, что вся цель задать этот вопрос - это алгоритм заполнения внутреннего сервера ИЛИ эквивалентные алгоритмы/методы.


person Am_I_Helpful    schedule 28.10.2014    source источник


Ответы (1)


Я предполагаю, что этот ваш сервер имеет хорошее подключение к Интернету с широким восходящим потоком. Если это так, то ограничивающим фактором, когда только несколько клиентов загружают несколько файлов, является пропускная способность этих клиентов. Таким образом, вы получите максимальную скорость, равную нисходящей полосе пропускания ваших клиентов. Таким образом, просто взять готовую библиотеку HTTP-сервера для обслуживания загрузок должно быть достаточно.

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

  • TCP имеет время запуска. Когда вы впервые открываете соединение, скорость загрузки начинает медленно увеличиваться, пока не достигнет максимума. Чтобы свести к минимуму это время, при загрузке нескольких файлов соединение, открытое для загрузки одного файла, следует повторно использовать для следующего файла.

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

  • Как правило, ваш сервер должен использовать неблокирующую библиотеку ввода-вывода (например, java.nio) и воздержитесь от создания потока для каждого входящего соединения, так как это приводит к перебору что снова резко снижает производительность вашего сервера.

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

  • Лимит восходящего потока вашего провайдера

  • Скорость чтения вашего жесткого диска (насколько мне известно, у SSD ~ 500 МБ/с)

Ваш сервер может попытаться удерживать наиболее часто запрашиваемые файлы в своей памяти и обслуживать содержимое оттуда (ОЗУ DDR3 достигает скорости 17 ГБ/с). Я сомневаюсь, что у вас на сервере так мало файлов, что вы можете кэшировать их все в оперативной памяти вашего сервера.

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

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

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


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

person lSoleyl    schedule 08.11.2014
comment
Пожалуйста, проверьте это и ответьте --- mailinator.blogspot.in/2008/02/ . Если вы удовлетворены, я поддержу ваш ответ, а также позже вознагражу вас за вознаграждение! - person Am_I_Helpful; 09.11.2014
comment
Я не очень уверен в их результатах. Я считаю, что они действительно измерили эти результаты и что они не выдуманы. Но программирование с помощью NIO намного сложнее, чем с использованием ванильного блокирующего ввода-вывода. Поскольку я не разбираюсь в их коде, я не могу убедиться, что эти тесты были честными. Второе, что меня задело, это то, что они сделали измерения только для ровно 1700 одновременных подключений. Я почти уверен, что блокировка ввода-вывода станет проблематичной при дальнейшем повышении, и она пойдет еще выше (следующий комментарий) - person lSoleyl; 09.11.2014
comment
Итак, по вашему мнению, 1700 одновременных подключений не убедительны? Я с ними, как это кажется достаточно законным, и никто бы не попробовал больше связей! - person Am_I_Helpful; 09.11.2014
comment
Их настройка была довольно удобна для демонстрации того, насколько хорошо IO превосходит NIO, ограничивая количество одновременных подключений до 1700 и просто измеряя пропускную способность. Но в вашем случае, если много клиентов будут скачивать одновременно файлы и эти файлы могут быть большими, то каждое соединение будет открываться долго. Как я уже сказал, я не знаю, каких клиентов вы обслуживаете, но средние интернет-пользователи имеют довольно грубое ограничение пропускной способности, и пропускная способность не должна быть вашей главной заботой. Вместо этого вам придется одновременно обслуживать тысячи открытых (медленных) соединений, и такое количество потоков влияет на производительность сервера... - person lSoleyl; 09.11.2014
comment
@shekharsuman относительно вашего комментария: это просто убедительно для этого числа. Мне не нравится, что общее утверждение, блокирующее IO, лучше, чем NIO, возникающее в результате одной конкретной настройки. Если вы стремитесь предоставить сервер, который не ориентирован на одновременное обслуживание тысяч клиентов, тогда блокировка ввода-вывода подойдет в вашем случае. - person lSoleyl; 09.11.2014
comment
Спасибо, позвольте мне попробовать ваше предложение. Ваша награда ждет вас! - person Am_I_Helpful; 13.11.2014
comment
Вас также может заинтересовать: я нашел научную работу 2011 года, которая показывает, как неблокирующее приложение NodeJS превосходит приложения Java и Scala с пропускной способностью в семь раз выше. - person lSoleyl; 17.11.2014