Depending on the complexity of your setup and the frequency with which the content changes, there are a number of options you could pursue.
Rsync is an good choice for synchronizing nodes, but you do run into a bit of an issue when nodes may be up or down. A common setup might run a cron job on each node to pull the data from a 'master' node, but if that master node goes down, you need to choose a new 'leader' and go from there. If you are manually assigning a master node, with the presumption that no changes will occur when it is down, you can have your cron job only on that node, and synchronize to each of the other nodes. Cron will always experience a bit of a delay, since you are running the task periodically.
A slightly better version of the above - which still suffers from the problems of dealing with node failures, but is more 'instant' is to use incron. This can be setup to trigger your rsync script when the content of a directory changes, and will therefore, greatly reduce the time that nodes are out of sync.
If you are only concerned about your code being in sync, your version control software should allow you to setup a post-commit hook. For subversion the process would essential entail:
- Create a repository on your server
- Import your files into the respository
- Check out a working copy to the master node
- Setup a post-commit hook that will update the nodes (e.g. via rsync)
- Check out a working copy to your local machine
Make your changes and commit them to the repository (svn commit) - the hook will automatically run the script and update the remote nodes.
The most versatile option, although, perhaps excessive if you are simply trying to keep code in sync, would be a distributed file system. For instance, using GlusterFS, you can setup replication between multiple nodes - and the failure of any given node will be handled transparently. The downside is an increase in write times, because a write to any node must be synchronized across all nodes. It is however, the option most resistant to failure of a single node (of those above), and allows for considerable scalability. It would also let you setup your nodes so that the files are distributed and replicated (i.e. if you have 10 nodes, you may not want 10 copies of the data - perhaps 5 copies of the data spread between the 10 nodes is enough - that would allow just about half the nodes to fail, and your data to still be readable.)