« Why you benefit from using UTF-8 Unicode everywhere in your web applications | Main | Content Delivery Networks - Are they for you, how they work and providers »
November 3, 2010
Why is scaling a web application hard ?
In the grand scheme of things, there will be one of three roads you'll take to address performance and scalability problems in web applications: performance tuning, vertical scaling or horizontal scaling.
- Performance tuning.- This step would consist of refactoring a web application's source code, analyzing a web application's configuration settings, attempting to further parallelize a web application's logic, implementing caching strategies, detecting hot spots and another series of often invasive -- code wise that is -- procedures throughout a web application's tiers.
- Vertical scaling.- This step would consist of migrating a web application or individual tiers to nodes with greater resources.
- Horizontal scaling.- This step would consist of decoupling a tier from a web application or decoupling a tier in itself to run on multiple nodes. In this scenario, instead of adding more resources which is the case of vertical scaling, a web application or its tiers are decoupled so that demand is spread out among multiple nodes.
| [Entry continues to the left and below ad ] |
Which of these last steps you undertake depends on a series of factors, including the particularities of your web application, a development team's experience, a web application's initial technology choices, as well as what is more attainable given your resources. The following figure illustrates a decision tree applied to either an entire web application or its individual tiers.
[ Click on figure to enlarge ] Figure 1 - Decision tree for performance tuning, horizontal and vertical scaling.
As this last figure illustrates, if a development team has very little experience making performance tuning changes, it can be easier to simply skip to the next step of vertically scaling an application or vertically scaling its different tiers. By the same token, if your service provider or data center has difficulties provisioning vertical scaling, it can be easier to simply skip to the next step of horizontally scaling an application's tiers or horizontally scaling tiers in themselves. If neither scaling scenario is plausible and you have an experienced development team, sticking to performance tuning may be the best alternative.
What is 'too expensive' for either of these phases depends on your circumstances. In addition, as a web application matures you will notice that it becomes more and more difficult to achieve any order of performance and scalability in the phases you invest more time in.
The hard part: Horizontally scaling individual tiers
Horizontally scaling a web application's individual tiers can become complex on account of both the technology and design choices made at the outset. However, there are two particular design choices that increase complexity when attempting to horizontally scale each tier: Decoupling and sessions.
Decoupling parts of a web application is critical to facilitating horizontal scaling. For certain cases, applying horizontal scaling to a web application can be simple on account of the clearly defined tier structure. A web application's permanent storage system can easily be transferred to its own node, allowing the remainder of an application to live on a separate node. However, decoupling a web application's individual tier is difficult if it has a monolithic design.
For example, take the permanent storage tier which may consist of a RDBMS. If the data managed by a RDBMS grows large enough, there will be a pressing need to do horizontal scaling once you exhaust both performance and scalability techniques, as well as reach the limits of vertical scaling (e.g. limits of an operating system). Since the tables in a RDBMS have relationships among one another, problems can arise because their data is tightly coupled. In other words, it's not possible to move tables arbitrarily between nodes or split one large table into several nodes to accommodate horizontal scaling, since it could break executing CRUD operations (e.g. On what node is 'table x' ? Is record 999999 located on node 1 which has part of 'table y' or node 2 containing the other part of 'table y' ?).
The same can occur in the business logic tier. If the demands increase exponentially -- due to increased users or elaborate business logic processing -- there will be a pressing need to do horizontal scaling. Problems can arise if business logic is tightly coupled, since you can't arbitrarily place part of your application's business logic in one node, that might be required by business logic present in a another node. Therefore it also becomes necessary to devise strategies to split up business logic to work across various nodes.
In addition to decoupling, sessions are another factor that will weigh heavily on executing horizontal scaling. Sessions hold data for users, with the business logic tier holding short-term data (e.g. for minutes or hours) and the permanent storage tier holding longer term data (e.g. for days or years). Expanding each tier into various nodes creates an affinity problem. Which node holds session data for a particular user ? Figure 2 illustrates this problem.
[ Click on figure to enlarge ] Figure 2 - Node affinity problem – Which node holds a user's session data ?
The scenario presented in this last figure can occur in both an application's business logic tier -- where data is processed temporarily -- as well as an application's permanent storage tier -- where data is stored for posterity.Under such circumstances, it's necessary to ensure consistency by either replicating & synchronizing data across nodes or using 'server affinity'. Figure 3 illustrates both approaches.
[ Click on figure to enlarge ] Figure 3 - Node affinity solution – Replication & synchronization or server affinity
Both approaches in this last figure constitute the most common techniques used to horizontally scale each tier of an application. In addition, they also represent the most common approaches used in clusters and distributed computing applications. Clusters or the more general purpose distributed computing model, allow resource pooling beyond that of the largest individual systems or nodes to achieve a common goal. And it's in this pooling process, clusters and distributed computing applications also achieve consistency among its member nodes, through a software layer that either replicates & synchronizes data among nodes or enforces 'server affinity'.
This fundamental premise of a consistent (i.e.'single and unified') view for each of an application's tiers is key to horizontal scaling. Though a consistent view of a tier made up of several nodes can vary in complexity depending on the tier and nature of an application, as an application designer, this is what will allow you to concentrate on a tier's specific requirements. It won't matter if a particular tier is two or dozens of nodes, a horizontal scaling strategy for an individual tier has to take care of this consistency problem for you.
In fact, one of the biggest advantages of relying on cloud computing services is their built-in ability to scale. This built-in ability is so advanced in some providers that you'll often not even realize if its vertical scaling being done (i.e. adding more resources to a node) or horizontal scaling (i.e. replication & synchronization of data among nodes or 'server affinity' enforcement).
This is an excerpt from a book I'm writing on web application performance and scalability. You can find the entire book's contents at http://www.webforefront.com/performance/
Posted by Daniel at November 3, 2010 6:49 PM







