There are five essential pillars of cloudiness. In this recurring blog series, we’ll count down from No. 5 to No. 1. Last time, we looked at scaling horizontally. In this fourth post, we discuss modular design.
Systems have been growing in complexity since we started creating them. Best practices have dictated that we separate logic and break things down into smaller, simpler parts to re-build them back into massive dynamic data movers. All of these connected pieces can lead to a domino style cascade if a component fails. By using a modular design that's loosely coupled we can mitigate these issues.
Traditional applications are tightly bound together. Web services communicate with databases directly with no decentralized communication. Every request made to the web server has to wait for the database to return information before the web server can respond to the user who made the original request.
This tight coupling leads to the aforementioned domino effect. Of course, when a failure occurs in such a system, it's usually easy to troubleshoot and fix as the lack of response from downstream indicates where the problem is likely located. But this can be misleading at times depending on how tightly coupled the application really is.
Breaking applications apart into modular pieces alleviates the problem of catastrophic failure from a chain reaction failure of systems but also can make pinpointing the location of the failure more difficult. The benefit of modularizing and decoupling applications is an increased ability to scale horizontally, as we discussed last time. Another benefit is the improved user experience we provide.
Needing to handle large numbers of asynchronous events, modern operating systems accomplish the speedy response we've all come to expect by handling as little as possible up-front. This separation is known as top-half and bottom-half processing and allows the system to quickly handle the next response if it can only handle one at a time (imagine what can be done if it can handle multiple events) as well as push the heavy lifting, the bulk of the processing, into the background where it can execute at its leisure.
With more modularity, there is more choice in where scaling of the system can occur. In classic applications, we have load-balanced web servers in front of a highly available database system. The database system is probably very hard to scale and the web servers very easy to scale (relatively speaking), but when we have more tiers, due to further modularization, we have more choice. We can scale the message queue, the NoSQL data store, etc.
The other advantage from cloud computing is the dynamic infrastructure that can keep up with fluctuations in the application and can be automated just as easily. This dynamic nature could be leveraged to create an auto-scaling solution that remains efficient with respect to compute usage, load handling and cost due to services utilized. Dynamic modular applications are the product and catalysts of agility.
As we begin developing applications for the cloud, we need to be sure we design these applications in a modular fashion. This lack of interdependency not only makes scaling and processing simpler but also makes the application pieces easier to maintain, which moves us towards the agility we discussed in with pillar of cloudiness four.
Tune in next week when we talk about the first pillar of cloudiness: parallel computing. Need more information about developing on the cloud? Be sure to check out our Rackspace Cloud API documentation and the Rackspace DevOps blog.
Alex Brandt, a Technical Trainer with Rackspace University, contributed to this article.