These forums are read-only!
Software As A Service Infrastructure Setup
  • Hello,

    So I wanted to post this question here, because I know a lot of you guys have technical backgrounds and probably would be able to provide good insight into the proper strategy of using Slicehost to host a software as a service business application. I want to use Slicehost to host my PHP+MySQL software as a service application. Clearly, my product and hosting are critical because my customers are paying on a monthly basis, and expect the application to be running and functional. I need a setup which allows me to expand quickly and fluidly to influxes of new customers. Here is what I was thinking off the top of my head. I was hoping everybody could assist and analyze the setup and provide suggestions and comments.

    DATABASE SLICES

    To start, a simple a 1 GIG slice running CentOS 5.2 and MySQL 5. Not sure if this matters, but my design puts each new customer on their own new database, I.E. there isn't one huge database for all customers. I was expecting I should be able to get at least 500 customers on this one slice, but it would be nice to get as many customers as possible. In fact, would be awesome to be able to fit thousands of customers on a single database server, it makes management easier and less headaches . Just depends on the load, but I know I can always scale up to a 8 GIG slice. Probably down the line though, I will need to look into a load balanced cluster of MySQL slices though.

    WEB/EMAIL/DNS/FTP SLICES

    This is the tricky part. As I scale and get new customers do I simply scale horizontally and keep adding new slices that point to the single database slice, or somehow should I use a centralized slice that proxies to other slices? The plan is to use CentOS, lighttpd, php5, bind, postfix setup.

    Here is a ASCII diagram of what I was thinking:

    web1 web2 web3 web4 web...
    | | | | |
    ------------------------------------------
    |
    db1

    Thanks for the help.
  • Regarding the database, I think one big server is the best way to start. You can upgrade if need be, but I think you're on the right track looking at a cluster or employing mysql proxy.

    For the other stuff, would probably need more information about the app to determine if you can share some more services. Adding individual slices is a safe bet, you could upgrade specific customers if need be.
  • Matt,

    Thanks for the reply. The application is basically pure PHP+MySQL, with a heavy amount of AJAX calls, so the MySQL database is going to get hit hard and often. I need postfix to send out basic e-mails and notifications to customers via php mail(). Does it make sense maybe to port the email services to a dedicated seperate slice from the web/dns/ftp slices?

    Thanks.
  • Sharding/partitioning your data set is one common way to scale to many users. So you'd separate your database into distinct partitions of users and their data, and then you could run multiple independent databases quite easily. Of course this requires application support for accessing the disparate data sets.

    Having said that, I would recommend not worrying about scaling too much too early. It's a common mistake in startups to spend all of your time worrying about having millions of users before you even have hundreds.
  • What do you think about separating the PHP part on its own server(s). If you're using fastcgi, you could do that right? Would that be efficient or would network latency cause a problem?

    So in essence you would have a a couple web servers a couple "processing" servers (PHP) and a database server (which you could cluster later). Just a wild idea.
  • alphagears,

    Yeah its an interesting idea, but yeah I can't image sending php traffic over 100mbps (even local ip traffic) would be faster then just running the web and php processing on the same slice. I could be completely wrong though.

    One thing I woud like to do, is break apart the dns (bind) from the web servers, but is that even possible? Does lighttpd have to be aware of the domains? It would be nice to have one slice running centos and bind, running my all my domains, and thousands of subdomains.
  • I agree with the previous comments on premature optimization, but 1 DB server is not going to cut it. You need a redundant setup and relying on 1 server is a mistake. If it goes, so does your app. I would look into creating a master-master with mysql proxy. Also, depending on what kind of queries you are going to be running, you may want to add a memcached server to increase performance - especially if your DB is going to be hit 'hard and often.'
  • Attached is a rough diagram.

    The two blue lines coming in represent public internet requests, inbound and outbound. All the nodes in gray are publicly accessible. All lines in black represent public connections using external ips. The blue nodes and blue lines represent private nodes, and private/local ips.

    http://99.175.237.110/crm/server_diagram.jpg

    Thanks for the feedback.
  • Guys so thinking about this a bit more, is it possible to have multiple lighttpd web servers taking requests for a single domain? I was thinking each client would get their own subdomain, so A record.


    Example: Lets say my domain is: my-software-as-a-service.com

    When a client signs up, they get a subdomain and A record: client1.my-software-as-a-service.com

    Then in DNS I can simply point the A record for client1 to the proper web server, and perhaps alternate new clients between the web servers in a round robin fashion, thus creating a basic load balanced setup.

    What do you all think? Make sense? Better way to do this?
  • Well you can have multiple A records for a single FQDN. So you could have 4 A records for www.my-software-as-a-service.com and then it will round robin.

    But that's not a guarantee you will equally load balance the servers. You could put a load balancer in front of all of the web servers to act as the traffic cop. It can query the load of each server and route the request to the lowest loaded server.

    I only understand web load balancing as a concept, I've never implemented it, so other will have more application knowledge on the topic.

    A quick google search points to Ultra Monkey (http://www.ultramonkey.org/) as a pretty popular load balancer.
  • alphagears,

    The only problem is, each client has their own files, for example each client has a uploads folder, and a custom setting.php file, so while the main application, meaning the php files can be centralized as a single copy, each client needs their own storage. How is that accomplished using web server load balancing?

    It was my impression that load balancing a web server involves all web servers having the exact same content, and then request simply get pushed to the least 'loaded' web server. With my setup, each client needs access to their own custom uploads folder and settings.php file which obviously will reside on a single server.

    The other big question is session management across multiple web servers.
  • Ok. In the case of storage, that is normally handled through a central storage server via NFS or SAN (though a SAN isn't really possible with slices). So you would store these files on one server (possibly dedicated server) and NFS the the share point to the rest of the servers. So really the files are just kept on one server but shared out over the network connection.

    Sessions should probably be kept in your database and when you out grow one database you start to cluster them.

    You can see how you can end up with a pretty big server farm.
  • My suggestions would be to run a cluster of slices with lighttpd/apache + php + pound for load balancing www requests, a seperate cluster of multiple mysql master-master pairs for your user's dbs (just add pairs each time the user base grows beyond a certain threshold), a highly available NFS cluster for all your user's files (basically two NFS slice's performing real time mirroring of each other) and finally another highly available NFS cluster that holds all your static www files (*.php, *.jpg, *.css etc.). Of course on top of this you'll need some slices to act as NS servers (I'd strongly recommend djb's tinydns over bind)and also at least one slice for mail functionality (nothing beats qmail for performance imho). Don't forget a SVN repository as well (can use the same NFS file store as the static www files).

    The only other thing to consider is that even with the above setup you still have single points of failure: all your slices are located in the same physical datacentre and use the same uplinks to the internet. Finally, don't forget offiste backup - I've used rsync.net in the past and would recommend them.

    See:
    http://www.apsis.ch/pound/
    http://www.howtoforge.com/high_availability_nfs_drbd_heartbeat
    http://meta.slashdot.org/article.pl?sid=07/10/22/145209

    Good luck!
  • gpuk,

    Thanks for the comments. Wow, looks like I have a lot of work ahead of me. :) I think to start I will kep things simple and as needed build out.
  • I think that's probably the best way. The great thing is that you don't need to do everything at once. Just start with something like: 1 slice running lighttpd + php + pound, 1 slice running mysql, 1 slice acting as a NFS file store and 1 slice acting as a general purpose mail/primary ns/svn box. Then, as your user base grows, you can just add www or mysql slices or a backup nfs slice without making major infrastructure changes.

    It all depends how big your budget is, how many users you've got and how many more you hope to have in the future. The only golden rule is try and get your core infrastructure right from the start - this way you wont saddle your existing users with unnecessary downtime or degraded performance when you're scrambling to add extra capacity due to a surge in popularity. Oh and off site backup. I can't stress this enough. For what it costs, there's no excuse not to have it!
  • I second gpuk's opinion. Make sure that when you start out, you are laying a scalable foundation so that you're not having to redo everything when you're slices start to feel the pressure of heavy load. I would set up your core infrastructure and maybe get an extra slice to practice scaling each aspect of the farm, so that you have the knowledge of how to do it when the time comes.