When delivering an enterprise solution to hundreds of thousands of customers, one of the main goals that you should be constantly delivering is good user experience (UX). A big chunk of that is being able to deliver the service in a timely manner, therefore, looking after performance is a key part of the goals.
What can contribute to slow performance?
There are quite a few factors that can affect the performance of your Drupal instance when delivering the service to your customers. For example…
- Network Connectivity
- Code performance
- Infrastructure Optimisation
With network connectivity, it can be a bit tricky because there are aspects of the connection that you will not have control over as part of the users connecting to your infrastructure.
What this will do is decrease the amount of data sent and help with decreasing the amount of bandwidth required.
Improving your code performance isn’t really a one-off exercise but instead should be something you should continually improve in your product releases. To get the most out of figuring out how to improve the performance of your code, you should make sure you have a tool that monitors how your code is behaving. An example would be New Relic which does Application Performance Monitoring, amongst other things, and has a Drupal feature which is somewhat aware of the Drupal code structure and the general flow of code.
With a tool like New Relic, you can drill down to the functions causing bottlenecks, or flag whenever there are a high amount of calls made in a page request to see if that is expected or if that can be done a separate way. Once you have identified some sort of issue with the behaviour of your code in New Relic, you can then go back to your code and optimise accordingly.
Also, looking after your code is key, doing a periodic code review would be beneficial as your codebase grows over time and it could be performing in ways that you wouldn’t expect. With a good code review, you might find that you will need to refactor your code as well as getting rid of a big chunk of it as part of this.
If you have multiple developers working on the same code base, having good coding principles applied will help to keep the maintenance of your code at a minimum as you might see that the codebase is too big and they would rather create a new function to do the same job as an already existing function developed elsewhere. To expand on this, if you have badly structured code, it will make it more difficult to be able to figure out what some of the code is doing when you are using New Relic to review.
A typical Drupal site can be hosted within the LAMP stack (Linux, Apache, MySQL, PHP). This can even be hosted on one server if you’re going to have minimal traffic and not a lot of modules installed which could add to the slow delivery of web pages. However, realistically this won’t suffice if your Drupal site needs to deliver loads of functionality to hundreds of thousands of users. Therefore, a Lamp stack would be the core of your setup, but you will need to expand on the resources that would make up your infrastructure. Below would be a good place to start:
Typically you would have the following:
- Front end cache Server
- Memcache Server
- Database Cluster
- Search Server(s)
- Web server
Front end cache Server
The front end caching server is the first point of contact in your infrastructure which delivers cached items to the end user and is reusable. Varnish would be a good option for your front end cache, especially for unauthenticated traffic. Varnish does not normally cache anything that has a session, so authenticated traffic would not have cached pages. However, authenticated traffic can be cached when using the authcache module.
The web server is when PHP and your actual Drupal code would live and work from this server and you would communicate to the different backends that work together to deliver your Drupal page. These backends would be your Database Cluster, Memcache and Search Engine.
The Memcache server caches data objects, produced by PHP, in RAM. As the objects are cached in memory, there are no disk reads, which means the results will be returned quickly, greatly improving the performance of your Drupal site.
To aid in resilience, you should have a database cluster that is split between multiple data centres that replicates queries as they come in. If one data centre becomes unavailable, the remaining data centres will pick up the traffic while the other data centre is recovering. Further optimisation can then be done to better accommodate the various queries. Having Memcache in the infrastructure also removes strain on the database cluster as the results that would normally go to the database would instead be retrieved from Memcache.
With high traffic Drupal sites with a high number of searches, it is best not to use the native Drupal search but instead use an external search engine. Typically it would be Solr or ElasticSearch. There are Drupal contrib modules available that integrate with these search engines. Within the search engines, you are able to update the configuration to better handle the search queries in terms of performance as well as configure the results set to match your customer needs.
The key takeaway from this is to use Drupal for what its best for and use other applications to handle operations that they’re built to handle. Having an expanded infrastructure split into different layers ensures each type of server is focusing on the operations it needs to focus on, spreading the load efficiently. With Drupal 8 you will see the architecture/infrastructure changing drastically as you will benefit from adopting a microservices concept. This will be covered in a future blog.