PHP Session Clustering and Load Balancing in the Cloud

| February 19, 2013

It's often necessary to extend a PHP application across multiple servers. This is particularly crucial when your business depends on the availability of the application. High availability is necessary to prevent failed transactions, error-filled shopping carts and lost work of your users. Extending the app across multiple servers provides redundancy. This ensures that when one server fails, it doesn't bring down the entire app. Thus no server will be a single point of failure for the app.

But it's also important to have a scalable solution. If your application is running on different servers, you want to be able to handle session failover. Redundancy ensures that if one server dies, the remaining servers can take over the work of the dead one. But you also need to be able to add more servers as necessary to avoid overloading those remaining ones. Scalability ensures that this can happen.

Thus ensuring high availability for your app requires the related strengths of redundancy and scalability. And there is only one way to make sure this happens: a solution that adds cluster to cloud. The cluster ensures that no server can be a single point of failure. The cloud ensures that one server failure doesn't overload the other servers.

Today we will show you how to implement such a setup. In our example, we will use memcached, two Apache servers, and an NGINX load balancer. The main use of memcached is as a distributed caching engine in a multinode environment. But for our purposes, imagine a Web session with sticky sessions running on several app servers. If one server fails, the sessions are stored for backup on a memcached node. Other servers can fetch the sessions from memcached and serve the session from then on.


Here is how it works: In normal operation, after each session request is completed, the session is sent to a memcached node for backup. When the next request has to be served, the session is still available on the original application server and can be used. After the second request is finished, the session is updated in the memcached node. But if the original server dies, the next request is routed to another application server. The new server is asked for a session it doesn't know.

When that happens, the new server will look up the session in the memcached node. It knows where to look based on an ID that was appended to sessionID when the session was created. It can then fetch the session from the memcached node. After the server answers the request, it also updates the session in the memcached node. Thus the original server's failure causes no interruption of the app, and the failover is successfully handled. During this time, an NGINX load balancer is distributing traffic across the cluster containing HTTP resources. You can see load balancing in Jelastic using various load balancing tools. Here's a detailed tutorial on how to do so. And here is how to use memcached to successfully handle application server failover:

Create an environment

1. Log into the Jelastic Manager.

2. Click the Create environment button:

3. In the Environment topology window choose two or more servers you want to use (for example, two instances of Apache) and Memcached node. Type the name of the environment and click Create.


In a minute your environment will be created.


Configure application servers

1. Click Config button for Apache.

2. In the opened tab go to etc > php.ini

3. Activation of the php memcached module is very simple, just add the following line to the Dynamic Extensions:

4. Memcached provides a custom session handler that can be used to store user sessions in memcached. A completely separate memcached instance is used for that internally, so you can use a different server pool if necessary. The session keys are stored under the prefix memc.sess.key., so be aware of this if you use the same server pool for sessions and generic caching.

Make these changes in the Session block of php.ini to enable sessions support:

session.save_handler = memcached
session.save_path = "< server >:11211"
Note: < server > is the memcached IP or URL which you can find by clicking Info button for the memcached node in your environment.

5.Save the changes, restart the Apache node, and your app will start using memcached to store the PHP sessions.

This was just a simple example. Actually such scenario is not a silver bullet, but it’s definitely worth knowing about. If one of the instances fails, the users who were on that instance get automatically switched to the other instance in this cluster. Thanks to memcached, end users never notice any change. So forget about all these long manual configurations – now you can get a high availability PHP cluster in a few minutes. Enjoy all the advantages of the cloud!

Feel free to ask any questions!