2

Is there an ftp server that behaves as a 'distribution front end' to multiple other servers? So that when I upload a file, it accepts the contents, puts them on all of a list of other ftp servers and (importantly) does not confirm success of the upload until it's on all of the other servers?

Alternatively, if it could wait until (say) rsync had replicated the uploaded file to all the other servers before returning success (or, more generically, wait for some external command to complete before returning success).

Background:

We have an app that uploads files to a repository (using ftp or sftp), then immediately instructs a device to download the file (via http).

We need the repository to be load-balanced/highly-available/resilient. Our corporate hosting standards do not permit shared storage.

What we do with other related apps is have several ftp/http servers, and manually upload files to all of them before telling the app (and then the device) to use them. A load balancer distrbutes download requests. This works becasue those apps do not do the uploading, instead we configure them to use the URL of the previously uploaded files. The problem app doesn't do this, it does the upload itself.

We could use rsync or similar to replicate the files uploaded by the problem app to the multiple servers, but the use of these files is immediate, so they may not have replicated to the other servers when a request for them is received. The app cannot be configured to have a delay here.

But if the ftp server didn't return until the file had been replicated (either by the server itself doing all the replication/upload to other servers, or by it waiting for an external command to complete), then the app wouldn't tell the device to use the files until we knew they were everywhere. And it would all work.

Any pointers to suitable servers? Other ideas for solving the problem? (altering the app isn't possible in the timescales, unfortunately)

2 Answers2

2

If you need to use FTP, you could write a script (perhaps a Python program, or in any language that offers a convenient FTP library) that your upload program runs immediately after completing the upload to the 'master' server. This script would scan the FTP sites that are supposed to be replicated to, and won't exit until it sees those files. On the master server, you would have another script that monitors the filesystem (such as using Linux's inotify) and when it sees new or modified files, it uploads them to the slave servers.

Alternately, you could use a replicated filesystem. This moves the problem from a homebrewed set of scripts at the application layer to a layer designed to deal with replicating files. Check out Tahoe-LAFS. I quote the relevant sentence:

Users do rely on storage servers for availability. The ciphertext is erasure-coded into N shares distributed across at least H distinct storage servers (the default value for N is 10 and for H is 7) so that it can be recovered from any K of these servers (the default value of K is 3). Therefore only the failure of H-K+1 (with the defaults, 5) servers can make the data unavailable.

Philip
  • 781
  • 5
  • 10
  • I thought the replicated filesystem approach was much the best, provided the FS didn't return confirmation on the write until the replication had happened. Nice approach! – MadHatter Oct 10 '12 at 14:13
  • Running a script after the upload isn't good enough. That's the same (in effect) as rsync. The file may well get used/retrieved from one of the slave servers before that script has completed running. The replicated file system might be interesting, but "In the period after the close but before the upload has finished, the closed file may not appear in directory listings, or may appear with an incorrect modification time. " seems to suggest it does not guaranteee the ftp session will finish only when the file is properly available. It's not very clear from the site what really happens here. – The Archetypal Paul Oct 10 '12 at 16:20
0

I think the true answer is "no". You're asking for more than the FTP protocol provides. If the client sends a TCP segment and the server says "I got it", the client sends the next one. When all of them are received, the transfer is done. There's no hook in the existing protocol for the server to say "Please wait while I fiddle around."

If you modified the FTP server so that it slowed down the TCP ACKs until it had written the bytes everywhere else, you might get what you want, but I worry that you might also turn your transfers into even more of a crawl than needed, due to TCP sliding window.

You're essentially asking for a two-phase commit for a file transfer operation inside FTP, and that doesn't exist.

Perhaps you could look at a virtualized/replicated storage system instead, as suggested above.

mfinni
  • 35,711
  • 3
  • 50
  • 86
  • I only need it consistent after the file is closed, so I don't think it us necessarily more than the protocol provides. The server could upload the file locallly (or to one of the underying servers), then copy it on close. This seems pretty much what Tahoe-LAFS does for ftp front-ends, for instance. I ran across DRBD (www.drbd.org) which is another alternative approach – The Archetypal Paul Oct 11 '12 at 19:49
  • Those are fixing this at the file-storage layer, which is what I am getting at with my last sentence. – mfinni Oct 11 '12 at 20:34