8

I've developed a REST WebAPI using the Services module. It works fine. I have a client of that API with projected usage requiring I horizontally scale my Drupal instance. Note that due to the nature of my API, requiring significant CPU and GPU resources, I can not use cloud servers. Also, due to the nature of my API, the Drupal instances have to run on Windows OS. (My application requires software only available on Win64.) I have a fairly beefy server in a co-location now, and for this ambitious client I am planning to horizontally scale my hardware in the following manner:

  • One CentOS server running HaProxy as the front end load balancer,
  • Two to start, with more added as needed, Windows Server 2008 R2 servers hosting Drupal,
  • One CentOS database server providing a single database for the multiple Drupal instances,
  • One CentOS database server running in replication mode in case DB server 1 dies.

My questions have to do with how the HaProxy load balancer works. I'm assuming that the sessionIds created by the Drupal instances will be unique from one another. Does the load balancer look at the sessionId and route all requests to the same server that produced that sessionId? How would a REST WebAPI communication work if load balancing caused each API request to go to a different server? Does any and all data referenced by the WebAPI have to be stored in the database because I can't insure that multiple API requests for the same resource will be routed to the same Drupal instance?

  • Very interesting question. I can't help feeling that it's more of a general question than one strictly about Drupal though (it could apply to any PHP-based REST API that uses session authentication if I'm reading it right); if that's the case you might benefit from flagging for it to be migrated to the main SO site. Just a thought :) – Clive Aug 31 '12 at 17:11
  • +1 for finding more info elsewhere. You can use most of the advice for scaling any PHP application with Drupal. As my comment was just a tad too long, I posted an answer that may help you find what you need. – rocketeerbkw Aug 31 '12 at 18:05
  • Thanks rocketeerbkw and Berdir for your insights. In my ongoing research into this, I've learned that HaProxy does not handle SSL with sticky sessions, and I need to use something like stunnel for SSL, since all my API communications are over SSL. Looks like more research is needed to fully understand my next move here. – Blake Senftner Aug 31 '12 at 21:29
  • And more research seems to indicate my configuration needs to look like tier1: firewall server & stunnel, tier2: load balancer, tier3: multiple drupal web servers, tier4: shared database server, tier5: replicating database server. And possibly along with tier4 a SAN for shared file storage for the multiple Drupal instances. Any insight, bread crumbs, or web articles describing people setting up something like this are welcome. – Blake Senftner Aug 31 '12 at 22:45
12

Having multiple webservers behind a load balancer/reverse proxy is quite common for Drupal and well supported. Varnish is typically used in the Linux world because that thing is just insanely fast when being able to actually use it, meaning anonymous visitors. Which is obviously not the case for your site.

Sessions are stored in the database by default, so that's not a problem. The only other thing that needs to be shared across all servers is the public files directory and any other like the private files if you're using something like that). In most cases, a shared/distributed file system like NFS is used for this although there are some more advanced approaches. On one site where I'm involved is the file system provided by yet another server that is an NFS-mount on the Drupal servers (so access there is slow) and is being distributed under a different domain by Lighthttpd. But again, that is probably not so relevant for you as you're not going to server lots of images and css files, I guess.

As mentioned by rocketeerbkw, there are cache backends for Memcache, Redis and others. So far, Ive only used Memcache but I recently started to look into Redis and it looks very promising but I'm not sure if it is available for Windows. However, it would be possible to set up a separate Linux server to be used for the cache. Drupal 7 relies heavily on caches, being able to get them off the database is very important for two reasons:

  1. Tools like Redis and Memcache are designed for fast key based lookups and they keep their data always in memory to make the lookup as fast as possible. They have also built in support for automatically cleaning up old cache data if the configured limit gets closer.

  2. Maybe even more important, it helps to get database load down. Once you have the basic setup in place, adding additional webservers is easy. Once you start reaching the limits of a single database server, things get much more complicated and you need to look into things like master/master replication (Drupal 7 doesn't really gain much from master/slave environments).

So, it's basically just your own API that you need to take care of. If possibly, you need to make sure that everything is always available from all servers. You can use either the databse, the file system or something else (Drupal can also use MongoDB to store certain data, e.g. fields). If that is not an option, then you will need to use sticky sessions so that users always end up on the same instance. You should however really try to avoid that because if one of the server fails then all users which were on that server need to re-connect to another server, possibly losing data.

0

By default PHP stores sessions on disk. If a user logs into Server 1, then hits Server 2 they will be logged out. There are a few options for fixing this:

  1. Don't store sessions on disk
  2. Ensure users always hit the same server
  3. Mount a shared filesystem on all servers

To implement #2 and answer your questions about HAProxy; In the most basic setup you can run it in TCP Mode and use the "source" balancing algorithm (http://cbonte.github.com/haproxy-dconv/configuration-1.4.html#4-balance) to make sure users hit the same server. You should read the docs to determine if there are any downsides for you using that approach.

For #1 you can use a key/value store like Redis or Memecached that all your servers would connect to and retrieve sessions. This makes sessions load/save very quickly and you could use either as a shared Drupal cache as well.

  • 6
    Drupal by defaults stores the sessions in the database and not in the file system. – Berdir Aug 31 '12 at 18:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.