March 6, 2007
One of the first few questions an architect would pose when designing an application would be: what are the availability needs of the system?
The answer would not only influence the overall architecture but would trickle all the way down to application design, choice of technologies and of course the physical deployment.
Clustering solutions help to address availability needs by aiding deployment of redundant servers that fail-over in real-time.
There is a cost to redundancy though, and often a high one. While at it, be prepared to spend a few hundred thousand dollars on software licenses if you use commercial J2EE app servers and RDBMS that are priced on per CPU basis. Now, as an architect you need to fight another battle – that of justifying deployment and ownership costs.
Sharing infrastructure between applications helps to ease this burden. Is it not nice if three applications can be “co-located/co-deployed” on the same set of boxes and thereby only incur one-third the cost that would have been the case otherwise?
The rest of this post is about recommendations, challenges and potential pitfalls in creating and using a shared infrastructure.
I have chosen the term shared “infrastructure” instead of shared hardware intentionally. It is because co-deploying applications often needs more than just computing boxes. It requires a holistic view of your applications – from development to final deployment.
- Firstly have a broad technology blueprint that applies to all your applications. Decisions here include technology stack – Operating System, RDBMS vendor & version, Application server, tiering of applications, hardware configuration – scale up vs. scale out.
- Consider a common boiler-plate structure for your code repository. The structure is prescriptive on what goes where(Html,images, JSP, EJB, DAO, SQL Scripts, deployment descriptors) but does not dictate package hierarchy say.
- Create a unified build and release process. This includes build scripts, final packaged binaries(exe, rpm, so files) and the supporting artifacts that enable the release & continuous integration.
- Identify and build/buy/wrap common services & components across the applications. They may be across the various tiers – data access, security, scheduling, pagination, internationalization.
- Establish clear guidelines on resource usage and communicate to all project teams. Indicative ones can be on : connection usage & release, JVM heap – stateful vs. stateless behavior, synchronous vs. asynchronous modes, Transaction demarcation in applications and with common components/services.
- Design the tiers and common components/services in such a way that they may be remotely deployed. Can help to isolate heavy use components and move them to dedicated servers – batch jobs run by the scheduling component for e.g
The challenges arise largely around the recommendations themselves.
- Governance – ensuring the guidelines are adhered to. Peer reviews work great here.
- Uptime of the infrastructure – a downtime can affect not just one but all of the applications.
- Monitoring and administration process, tools – Monitor the infrastructure for signs of distress – over use of CPU, memory, resource pools.
- Personnel skills and training – The overall infrastructure in a shared setup is mostly more sophisticated than that of one dedicated to a single application, at least initially when setup. Specialized skills around clustering solutions – OS onwards, shared data storage(NAS, SAN), physical security would require good in-house skills or the services of consultants.
- Smooth roll-out and compartmentalized releases that have minimum downtime of the shared infrastructure. For e.g, the ability to turn off individual silos, deploy the release and bring them back on.
- Rogue applications : All applications that reside and benefit from the shared MUST adhere to the established guidelines for development. Non compliance affects all.
- Overloading : Every infrastructure has its limits. The application portfolio cannot simply grow. Application sizing must be done and the infrastructure augmented if required.
- Trouble shooting : Application logs, databases, concurrency, tool mix e.t.c tends to grow with co-deployment. Issues arise out of sheer size. This can be suitably mitigated by : log analysis tools, partitioning, tool standardization and avoiding shared data between threads.
Of course it may appear less painful to have dedicated infrastructure. It is not true because you end up addressing most of the above anyway, though maybe on a smaller scale :)