Design – How to architecture the big files download

Architecturedesign

I have a website where new requirement came up where user can download a zip file of 500MB from the server. I am expecting max 10 concurrent users(CU) will be performing this activity . Webservers contains the files on same server.

Current stats : Currently server 60 request per sescond with 99 percentile served with in 1 second . CPU/Memory stats are under utilized.Though I will get the performance benchmarking done here. But before development would like to know what factors I should consider to know below points

  1. What max extra memory and CPU these 10 Concurrent Request(CR) may use ?
  2. Can I serve it from existing web server only ? Or Ideally this should be catered through separate webservers ?
  3. what impact this use case can create on my existing traffic ?

My understanding theoritically is

  1. Considering 100 Mbps network speed average scenario at server side , it will take 40 sec just to transfer the bytes.
  2. Conidering HDD read spead i.e. 2 MB per sec on an average , it will take 250 secs(approx 5 minutes ) just to read the data from disk.
    Which means that 10 concurrent http thread will be continously working(primarily doing disk IOPS) for 5 mins . Is n't it ?
  3. CPU load may be fine as it is primarily disk io intensive ops. Extra memory load of 5 GB may be there for 10 CR . Right ?
  4. In case of more than 10 CR, I will take them in queue and process later.
  5. My final understanding is : If I store the files on separate server I can reduce the IOPS from current webserver , I may be good considering I get 5 GB
    of extra memory

Just to want to get the solution/thoughts to design it correctly .

Best Answer

I believe you are overthinking this. The slowest link in the chain, whether it's disk or network is going to be the only real limiting factor. You have a choice, you can delegate downloads to another service, or you can serve it yourself. If possible, I would stage your files on SSD drives, which have bandwidth that exceeds your network speeds. Either that, or have another service host it, and simply redirect to the file location.

Offload the problem

For example, AWS S3 buckets can serve large files to millions of concurrent users without breaking a sweat. If you simply have that serve your downloads, then you don't have to do anything fancy.

Do it yourself

The main thing you have to do is to stream the data. When you look at the braindead examples on most tutorials, they have you read the entire image into memory and copy it to the output. That requires you to have at least 500MB of free RAM for each concurrent request.

By streaming data, you only need a couple megabytes for each concurrent request for buffering. You would use a StreamingResponseBody to send the data back. Here is another article to help you out.

The concept is to read a few bytes and serialize that, read a few more bytes, and serialize that. With a small buffer, you can easily max out the Tomcat server hosting your Spring application with roughly 1 GB of memory usage. That makes your service a whole lot more economical to host, and scaling is also easy.

Related Topic