PHP File Upload in Sharded Server Configuration
Asked Answered
T

2

5

We use multiple servers to handle incoming web requests which are load-balanced in a round-robin fashion. I've run into an issue that I'm not sure how to solve.

Using AJAX (qqFileUploader), I am uploading a file. By default it goes into the /tmp folder which is fine. The problem is when I try to retrieve that file, that retrieval request gets handled by the next server in line which does not have the file I uploaded. If I keep repeating the request over and over again, it will eventually reach the original server (via round robin load balancing) where the file was stored and then I can open it. Obviously that is not a good solution.

Here is essentially the code: http://jsfiddle.net/Ap27Z/. I removed some of it for brevity. You will see that the uploader object makes a call to a PHP file to do the file upload and then after the file upload is complete, another AJAX call is made to a script to process the .csv file. This is where the process is getting lost in the round-robin.

I read a few questions here on SO relating to uploading files to memory and it seems that it is essentially not currently feasible. Is there another option I can use to upload a file and handle it all within the same request?

Thyroiditis answered 18/7, 2012 at 14:16 Comment(8)
Why does the web page have to tell the server to process it? Can you make the file into a BLOB in your database?Coverall
You need to be able to reference each server with an absolute name (i.e. each server has it's own A record), and you need to return the name of the individual server in the response to the POST request where the file is uploaded to the client - e.g. with a cookie - so the client can reference the correct server with it's absolute name when it tries to retrieve the file.Glebe
Out of interest, is this a DNS round-robin or a reverse proxy?Glebe
@Glebe I'm not exactly sure what type, the Sys Admins handle that. I like your suggestion on passing the server name. I'll look into that.Thyroiditis
@DaveRandom, if it's a reverse proxy, is it possible to use sessions to get around this issue?Marengo
@Adnan Depends what type of sessions you mean. PHP sessions no (they are local to the individual server), sticky sessions in the proxy yes.Glebe
@DaveRandom, oh yes, sorry. what I meant was proxy's sticky sessions. thanks.Marengo
here is nice explanation about LoadbalancerNarcotism
C
6

The classic solution to this type of problem is to use sticky sessions on your load balancer. That may not be a good solution for you as it would be modifying your whole setup to fix a small problem.

I would suggest adding a sub-domain prefix for each machine e.g. upload goes to www.example.com and then each server is allocated an additional subdomain www1.example.com, www2.example.com which are always passed directly to that server, rather than round robin DNS.

As part of the success result, you could pass back the server name that points to the exact server, rather than the load-balanced name, and then all subsequent Ajax calls that reference the uploaded data use that server specific domain name, rather than the generic load balanced domain name.

Is there another option I can use to upload a file and handle it all within the same request?

Sure, why not? The code that handles the POSTing of the data can do whatever you want it to do.

Crawler answered 18/7, 2012 at 14:28 Comment(1)
LOL, sometimes simple things are the ones that are overlooked the most. I hadn't considered just handling the file processing inside of the code that uploads the file.Thyroiditis
B
2

There are (at least) 2 solutions to your problem:

  1. You change the load-balancing.

There are several load balancing proxies out there which support session affinity a.k.a. "sticky sessions". That means that a user always gets the same server within a session.

Two programs that can act in this way are HAProxy (related question here on SO) and nginx with a custon module (tutorial here).

  1. You chance the files' location.

The other choice would be to change the location of your stored files to some place that all of your servers can access via the same location. This could be, for example, an NFS mount or a database (with the files stored as BLOBS). This way, it doesn't matter which server processes the request, as all of them have access to the file.

Bulk answered 18/7, 2012 at 14:31 Comment(2)
I don't have the option of changing load balancing, but like the idea of a static location for storing temp files.Thyroiditis
But don't just mount /tmp via NFS. Other process are probably using that folder (for example, PHP sessions in default configuration), and sending all that via NFS could slow everything down. Rather, use a separate folder for your uploaded files.Bulk

© 2022 - 2024 — McMap. All rights reserved.