Scaling PHP applications, or any application for that matter, can be a complex topic. The first step in scaling a PHP application is understanding what your needs and goals are. Before getting into specific details, I want to first make sure we are on the same page.
The difference between scaling and performance
You can think of performance as the ability to meet your needs right now. Do pages load fast enough? Do queries return in a reasonable amount of time? Do you have enough resources for all of your users? These questions relate to the performance of your application.
Scaling an application, scalability, is the ability to meet your future needs. If you add 1000 new users, will your hardware scale to meet that? If your data grows by 500% (and trust me that happens), can your database scale to accommodate that?
When you read or hear people talking about web application performance, they are usually speaking about how fast a page loads. A faster load is equivalent to better performance. Scaling, however, means that you can load the page in the same amount of time for your 50 users today that you can for your 50,000 users tomorrow. That is, the ability to get same non degrading response time, but with more concurrent users.
When thinking about the scalability of an application, we also need to think about scaling well. If it is very expensive to scale your application, or very difficult and time consuming, then you do not scale well. How easy or difficult your application is to scale is dependent on many things. Below I will talk about several design issues and considerations for scaling PHP applications. The first step to scaling is deciding whether to scale up or scale out.
Scaling out vs scaling up
Scaling up is also called multi-core scaling or monolithic scaling. The idea behind scale up is that if a particular function or application will perform well on a server with one CPU, then it should perform twice as fast on a server with two CPUs, three times as fast on a server with three CPUs, etc. The truth is that while certain applications can scale well on monolithic hardware (a single “box”), it is generally not a linear increase and it gets very expensive very fast. Bigger servers just cost more. It’s also true that applications that have wait states for particular activities (serialization) do not scale up very well. Why? Because threads block other threads.
Scale out has become the general standard for scaling web, and web scale, applications. Scale out is also called distributed scaling and distributed computing. The idea behind distributed computing is to add low cost hardware and send processing out to the new nodes to do work.
Both scaling out and scaling up allow the application to parallelize the work and take advantage of the additional hardware. The design of your application can greatly impact its ability to scale and whether you should scale up or out.
If you scale up, you have a hard limit on the amount of parallelization that you can do. Any machine will only have so much available memory and so many CPUs. If you buy a new machine with more memory and more CPUs, you will pay a premium for that scale and you still have finite resources. For scale up, your application should be prepared to run simultaneous threads and share a memory space. Java and C++, when coded correctly, are well suited for this kind of scalability, PHP and most databases, not so much.
When you scale out, you can add new nodes as you need them. You don’t have to over buy to make sure you have capacity later. Just purchase new nodes and add them as needed. An additional benefit to scale out is that is builds in certain amount of high availability by allowing redundancy in processing and data storage. Because it is distributed, in many cases it will allow for a geographical distribution allowing for some disaster recovery.
The downside to scale out can exist if you do scale out yourself, manually and without ScaleBase, because you will need to reprogram app logic to address the additional nodes. In a database scenario, you may need to redistribute data between nodes. Making your application of aware of that new distribution can be painful. That’s where Scalebase comes into the picture. ScaleBase specifically addresses this and removes a key pain point by centrally managing data distribution and removing any need to recode the application. I’ll address that later in a entry on PHP and database scaling.
It’s also possible to combine scale up and scale out when discussing a PHP application. You could very well have a monolithic application server and a distributed database, or you could have a distributed application server farm and a monolithic database.
When a particular method of scaling is required, the remainder of this post (and the related posts coming soon) will address scale out, not scale up. Some of the topics I discuss below are relevant regardless of the method of scaling. Some make more sense, or are only viable, via scale out.
Stateful vs Stateless
The final topic that I will talk about in this post is the difference between stateful and stateless applications.
A stateful application keeps information about the application session between calls to the application. A stateless application is more of a black box; no information is kept between calls and any setup information is passed as part of the call.
In a service oriented architecture, SOA, a stateless environment is the sought after ideal. HTTP itself, the protocol governing the web, is a stateless protocol. Each HTTP call stands alone. Cookies, when added into the mix, mimic a stateful process. Information about the sessions is stored temporarily in a small file between calls. Client state can be kept on the client (i.e. the browser) and server state is kept on the server.
While individual SOA services are ideally stateless, most user applications, PHP included, are stateful. Information about the user, open transactions, etc. are kept available between calls. In a distributed environment, server side state information cannot be simply kept in a file. A session may use any of several servers to respond to any particular request. Keeping server state on the client raises serious security concerns. Where, and how, to control server state raises serialization and parallelization concerns.
It’s worth specifically noting that stateful apps can be harder to scale. That’s because the state information that is preserved between calls requires each call to return to the same server not realistic for scalability reasons) or the session must be cached (in some kind of a shared file system, keystore or database) and that causes serialization issues. A database is the holy grail for session information (because of the rich data types and ease of use) but if manually configured, maintenance can be difficult. There is software written specifically to address this.
I will end the post here today. Future posts will cover items to keep in mind when scaling PHP applications. The following posts will cover access via the network, the application itself, session state management and I will end with scaling the database.