Running a PHP Cluster on AWS

Running a cluster of PHP servers on AWS can be a complex task to say the least, and in this article we will look into the various tasks involved in managing a PHP clustered environment. We will look into why it can be a complex and tricky task and how Zend Server help alleviate the pain involved.

Introducing the challenge

The basic scheme of a cluster of PHP nodes usually looks as follows:

php_cluster_on_aws

Deploying an initial cluster of PHP nodes is a relatively simple task compared to the management required later.

A few complex but frequent tasks related to such a cluster are (this list is not complete):

  • Upgrading the PHP code simultaneously on all the nodes in the cluster with minimal downtime
  • Propagation of changes in PHP configuration (php.ini) to all the nodes in the cluster
  • Monitoring of PHP logs and events on all nodes
  • PHP sessions sharing

Of course, none of these tasks is too complex. But let’s compare how these tasks can be solved using PHP and the utilities supplied by Linux distributions (RHEL/Ubuntu and derivatives) and Zend Server.

Before we start, a few words about Zend Server.

Zend Server is an application server for PHP that can be deployed as a cluster solution. Zend Server requires a separate MySQL database when running in cluster mode to store its internal data. On AWS, you can use RDS as a MySQL server. Zend Server greatly simplifies the management of a cluster of PHP servers and can be controlled via a web based user interface or Web API (simple API that works on top of HTTP protocol).

Upgrading and synchronizing PHP code

One of most common tasks involved in managing a PHP cluster is maintaining an updated PHP stack across all the nodes in the cluster. Linux (RHEL/Ubuntu) with Apache and PHP installed from packages supplied with the distribution do not provide any special means to solve this task. Of course, one can use rsync (or similar file synchronization tool) to synchronize files from a source host. You could even go further and spend time adding crons for rsync tasks and automate PHP code synchronization to run every few minutes. But to support and manage this solution is time consuming and complicated, and later requires even more management (especially when there are scripts that have to be run on every node before/after code synchronization because of a software version upgrade).

Another option is to use an NFS server to store all the PHP code on a single server and mount that NFS to all the PHP servers. But the performance of such a solution is very poor. Additionally, this automatically creates a single point of failure – the NFS server.

Zend Server solves this by providing the Zend Deployment component. Zend Deployment allows developers to pack their software in single a .ZPK file (zip based) and allows supplying scripts to run during the deployment stages: before/after staging, activating, rolling back, deactivating, unstaging. You can use a tool called zdpack to pack your application along with all the scripts (entirely optional). Each application deployed on Zend Server can later be upgraded and there is even an option to roll back.

This greatly simplifies the management of the cluster. You do not have to write and manage scripts that synchronize and deploy files and keep everything in sync. You can focus on developing your application and only manage the scripts related to upgrading the application.

manage_apps

Propagation of changes in PHP configuration

Since PHP itself does not work as a cluster, the php.ini file, which holds PHP’s internal configurations, along with all the .ini files related to different PHP extensions, is not synced between PHP servers. Therefore, to keep configurations consistent between PHP servers, one has to find a way to sync .ini files and restart Apache as needed.

Again, there are a few ways to do this – from rsync running in cron, to NFS sharing .ini files between all nodes. There is also an additional solution using puppet or chef or a similar IT automation software, and managing the servers’ configurations centrally. If you already have puppet or chef deployed, then this solution will be most effective.

When deploying a Zend Server Cluster, you do not have to deal with this issue. Zend Server provides you with an easy way to configure all the PHP settings via a friendly and easy-to-use user interface, and every node entering the cluster is adjusted to match the existing PHP configuration. If that’s not enough, you also have a way to configure PHP in a cluster using Zend Server’s Web API.

php_extensions

Monitoring of PHP log and events

PHP can store its log either in a file locally or send it to syslog. This complicates log analysis in case of a cluster. To examine PHP logs you either have to go through log files on each of the PHP servers, sync them to some central server or setup syslog to aggregate all the logs on a central server.

Using a Zend Server Cluster, you can centrally examine log files from all the nodes in the cluster, again using the user interface. Zend Server saves the log files locally on each node and fetches them from relevant nodes as needed.

Additionally, Zend Server’s Monitor component allows events to be shown in the Zend Server user interface based on event rules which represent certain configurable thresholds monitored during code execution. Events are shown for the entire cluster and not per cluster node, and are split by application.

events

PHP sessions sharing

In the most basic PHP cluster architecture, one of most important issues is how to share PHP sessions across PHP servers. There are a few ways to solve this issue:

  1. Sticky sessions on ELB
  2. NFS
  3. Database
  4. Memcached
  5. Redis
  6. Zend Server Session Clustering

Let’s go through each of these solutions with a quick comparison.

Sticky sessions on ELB

AWS Elastic Load Balancer can be configured to route requests from the same user to the same server. This allows saving PHP sessions locally on a PHP Server, but then there is problem with High Availability because each session is saved only on one single server.

  • Pros:
    • Uses default PHP session handler
      (session.session_handler = files)
    • Very fast because sessions are saved locally on a PHP Server
  • Cons:
    • No High Availability
    • In case server goes down, the session is lost
    • Scaling is very hard to implement without losing PHP sessions

NFS

NFS allows saving all the PHP sessions centrally on one server. But this complicates our setup by adding NFS server and also means that the NFS server is single point of failure. So it is also hard to implement High Availability here. There is also a chance of sessions being corrupted because it is used on different servers simultaneously and multiple simultaneous requests. And NFS performance is not particularly good.

  • Pros:
    • Use default PHP session handler
      (session.session_handler = files)
    • You can use AWS EFS when it is out
  • Cons:
    • UntilAWS EFS is out, you have to manage the NFS server by yourself
    • Highly inefficient (writing to NFS is slow)
    • Not designed for high read/write ratio
    • Frequent PHP session corruption

Database

There are a lot of best practices involving saving PHP sessions to a DB. You can use MySQL, MS SQL, PostgreSQL, etc. Since you’re running on AWS, it would be wise to choose a DB that is supported by AWS RDS. Then you do not have to manage the DB by yourself and you have an option to simply scale your RDS server as needed.

  • Pros:
    • You can use AWS RDS as a DB
    • Extremely  scalable solution
    • A lot of best practices available
    • You have an option of High Availability on AWS RDS
  • Cons:
    • Sessions have an almost 1:1 read/write ratio
    • DB connection overhead
    • May be a performance bottleneck
    • When scaling AWS RDS, there is a downtime involved

Memcached

Memcached memory object caching system can be used to store PHP sessions in RAM. Its performance is very good because all the data is stored in memory. And although it can be clustered, it lacks an option for High Availability. In case memory allocated to memcached gets full, data is overwritten (because memcached uses cyclic memory).

  • Pros:
    • Native PHP session handler
    • Very fast (sessions stored in RAM)
    • Can be clustered
  • Cons:
    • No High Availability
    • No data persistency (after server restart, all data is lost)
    • Data can be overwritten if memory is full
    • Scaling can only be done by replacing server (involving loss of data)

Redis

Redis is an in-memory data structure store. It is similar to memcached, but it’s state can be saved between restarts. Since Redis stores it’s data in memory, it’s performance is very high too.

  • Pros:
    • Very fast (data stored in RAM)
    • Reliable (data can be replicated)
  • Cons:
    • Still no High Availability (limitation of master-slave replication)
    • Scaling can only be done by replacing a server (involving either loss of data or downtime)
    • No native PHP session handler

Zend Server Session Clustering

Session Clustering is an integral part of Zend Server and can be easily enabled on Zend Server Cluster in one click. It was designed to provide High Availability while maintaining good performance. PHP sessions are stored both on disk and in memory. To improve performance and lower resource consumption, it uses Peer-to-Peer protocol to communicate between nodes.

  • Pros:
    • Very fast
    • Reliable (each session has backup stored on other node in cluster)
    • High Availability
    • Scalable (sessions are stored on all nodes in cluster)
    • Native PHP session handler
  • Cons:
    • You need Zend Server Cluster

session_clustering

Conclusion

To sum it all up, a Zend Server Cluster simplifies the management of a cluster of PHP servers. It provides a solution to most of the common tasks out-of-the-box and without additional writing and managing scripts.

In addition, Zend Server comes with bundled with a variety of tools not covered in this article (like Zend Data Cache – a component providing caching layer in PHP, Zend Debugger – a component that allows debugging PHP code, Zend Page Cache – a component that improves performance by caching output of PHP script, and plenty more).

Zend Server on AWS Marketplace also comes with support and SLA,  and to simplify Zend Server Cluster deployment on AWS there is also an AWS Cloudformation template generator

The following two tabs change content below.

    Dima Zbarski

    Cloud Integration Engineer at Zend Technologies
    • Jerem

      Hi, thanks for comaring these solution to handle php session in the cloud.
      Does Zend Server Session Clustering support session locking ?

      • Dima Zbarski

        Session Clustering does not have locks because it is not needed.
        When request arrives to node that does not have needed session, it will access seamlessly session on another node using Session Clustering protocol. Since all nodes access the same session on same node, no locks are needed.

        • Jerem

          I mean the defaut php session locking to preserve data consistency among concurent http requests.
          A->sessionRead->phpProcessing->sessionWrite
          —– B->sessionRead->phpProcessing->sessionWrite (overwirtes session write A)

          • Dima Zbarski

            There a session locking mechanism, but it’s totally automatic.
            In your flow, request B will be blocked on sessionRead until request A finishes with the session.