In-Depth

Multitiered architectures and application partitioning

Organizations continually implement new business processes, discard flawed ones, or extend and modify current practices to better reflect the workings of the organization. The goal: to extend the business and improve the bottom line.

Business systems automate these business processes, and hence business systems, like business processes, are continually in a state of flux. Until quite recently, systems that automated business processes (strategic systems), unlike systems that simply report on the business (tactical systems), ran on centralized, host-based architectures. Today it is commonplace for organizations to build new strategic systems to run in heterogeneous, distributed environments. These "enterprise class" systems are built as standalone systems, but it is common for these new systems to integrate with legacy data sources and processing.

Multitiered execution architectures are professed by many to be a key requirement for building next generation enterprise-class business systems. Such multitiered designs are usually manifested as three tiers with the interface (GUIs and browsers), data-access layers and procedural code logically split and then physically distributed among clients and a variety of servers. The term "partitioning" has been applied to the process of distributing the back-end procedural code among multiple servers.

The tools market is filled with products that span the capabilities spectrum and profess support for multitiered design and application partitioning. Product reviews and a host of other sources are available that compare and contrast the technical capabilities of the various products. What is lacking is any discussion of why multitiered systems and application partitioning are preferable to other designs and techniques. More to the point: "Why should I partition applications and what are my options?"

Limitations of two-tiered client/server

The approaches for creating strategic client/server systems differ as much as the organizations that are trying to implement them. Organizations make use of 3GL environments, as well as tactical and strategic client/server development tools. Many tactical client/server tools create applications that target the classical two-tier client/server execution architecture.

Under this model, all application logic and GUI processing executes on the client, while all DBMS processing executes on the server (SQL is passed from the client to the server). With this approach, first-generation tactical client/server tools were successful at the rapid production of basic data access applications. The limitations of the two-tier model, and the tools architected for building two-tier applications, become obvious as organizations tried using them to build larger, more complex systems.

The major shortcomings of two-tier client/server tools for building enterprise systems are performance, maintainability and security. Enterprise-scale business systems tend to be long-lived and critical to the workings of a business. Therefore, newly developed distributed systems must be secure and maintainable over a long period of time. It is not effective from a maintenance and a security standpoint to locate business rules in the form of application logic on every desktop.

Developers of departmental client/server systems have found that maintaining "desktop heavy" first-generation, client/server applications is extremely burdensome and time consuming.

Furthermore, the lack of performance keeps the two-tier model from becoming an optimal solution. First, sending large blocks of SQL from the client to the DBMS server for processing is inefficient. Implementing complex application logic on each client in a large client/server implementation also reduces overall system performance.

The advantage of server-side logic

Many of the architectural limitations of the two-tier client/server model can be mitigated by placing some types of application logic on the server.

The primary benefits of server-side logic -- increased system performance and increased maintainability -- are the direct result of locating key pieces of application logic on central servers. These servers are typically highly optimized, either utilizing the latest generation of processors or employing other high-performance technology and techniques such as symmetric multiprocessing (SMP), parallel computing architectures or clustering.

By employing server-side application logic, clients can lessen the need for sending large blocks of SQL code for DBMS processing, thus decreasing the overhead on client applications and diminishing network traffic and effectively increasing the performance of all networked systems. If computationally complex application logic is transferred from client systems to an optimized server, the performance of all impacted clients is increased.

It is easier to update a single piece of application code on a central server than to make changes to every client workstation in a local-area network (LAN) or to make a single change and distribute that change to all effected clients.

Utilizing a single code base for multiple clients also increases the quality and integrity of the overall system during the production of bug fixes, enhancements and upgrades. Security is also enhanced by locating application code on a dedicated server. It is a much simpler to secure a single server than to control access to critical business logic on multiple networked clients in a distributed client/server implementation.

It should be noted that utilizing server side logic is not workable for all application types. Whole classes of applications exist that simply do not require access to organizationwide application logic. Also, there might be instances where some type of application code should exist at the client GUI level, such as constantly accessed pieces of logic such as input validation. Locating such pieces of code on the server could actually reduce performance.

Nonetheless, if a certain piece of logic is used companywide and is not accessed continually, that code should be located on the server side of the client/server equation. At that point, the remaining questions are where to locate and how to access the logic.

Triggers and stored procedures

A method of splitting application logic between clients and servers -- promulgated by relational DBMS suppliers -- is to attach pieces of application logic to the database in the form of triggers and stored procedures. Using triggers and stored procedures, business rules are directly bound to data structures on the database, rather than located in each client workstation.

A trigger is database-resident (and database-specific) code that automatically performs basic database maintenance functions, such as preserving relationships between entities when rows are inserted, modified or deleted. Triggers require little code to perform basic database updates and checks, thereby increasing application performance. Triggers can fire other triggers, prompting some developers to try and use that capability to extend the simple functionality of triggers to support more complex processing. This exercise is ill advised as a development practice, as cascading hierarchies of trigger dependent triggers can become difficult to debug and maintain.

Stored procedures are the other type of database resident logic. A stored procedure is a piece of complex database code, usually written in a DBMS vendors proprietary SQL dialect with additional procedural constructs (although for some DBMSs, they can be coded in a 3GL with embedded SQL), which is accessed by users of the database. Since stored procedures are located in the database, they are often used as central stores for shared database logic. In most DBMSs, stored procedures are precompiled for increased performance.

Due to the technical advantages and to heavy promotion by DBMS vendors, the use of database triggers and stored procedures have found acceptance in the I/S community. Some developers of distributed systems have gone so far as to locate centralized business logic in the form of stored procedures on the database. For these developers, logic dictates that it is appropriate to use databases, traditionally the central store of business data, to be the central store of business logic as well. Maintaining a single code base in a central location appeals to the intuition of both developers and development managers.

Problems with stored procedures and triggers

There are a number of factors that militate against using database resident triggers and stored procedures as the source for centralized business rules.

First, stored procedure code can be difficult to write, and there are few tools available for easing the job. (However, some of the tools that do exist are excellent.) Although SQL is well-suited for database access, it is not as strong as some other languages for specifying computationally complex application logic and communicating directly with hardware or operating system primitives.

Second, using the database as the nexus for shared business logic flies in the face of the current industry dynamic for open systems. Triggers and stored procedures are database dependent, and typically limited to a single server. Therefore, as a method of specifying enterprisewide business logic, triggers and stored procedures have little applicability in today's heterogeneous, distributed computing environments. In addition, overburdening the database with complex procedural logic can decrease response time and throughput levels.

Like simple data access client/server applications, triggers and stored procedures can be effective techniques if used correctly. Triggers are effective in automatically performing basic database maintenance functions. Similarly, stored procedures are an appropriate means of accessing the extended functionality of a given database.

Locating triggers and stored procedures on a central server can increase the consistency and reliability of DBMS applications. Locating DBMS logic on the server reduces network traffic, thereby increasing application performance.

Multitiered architectures

Virtually all organizations have created small client/server pilot projects and departmental systems. However, as organizations extended the client/server adoption curve to build enterprise-scale, strategic systems, it was found that the client/server architectures that had initially served them well, simply could not get the larger job done.

The increasing use of multitiered computing architectures is the natural consequence of the inadequacy of the two-tiered system. In addition, development tools, interapplication communication middleware, database access middleware and other infrastructure software, have all evolved to support a multitiered computing model in heterogeneous environments.

Perhaps most important, the knowledge gained creating the first generation of simple data access client/server systems have given developers and development managers the experience base needed to begin creating strategic, distribute systems.

Multitiered designs are usually manifested as three logical tiers with the interface, database, and procedural code physically split among servers and clients. The three-tiered approach is inherently superior to the two-tiered model from both a technical and business standpoint. By separating the interface, the data structures and the application logic, changes can be made to any component without affecting another.

The design eases the maintenance burden, results in applications of higher quality and stability and has a direct and positive impact on the business. By isolating application components, organizations can quickly modify business systems to respond more rapidly to competitive challenges and to improve services to the customer (or the end user).

To achieve the benefits of a multitiered software architecture, application components must communicate in the distributed environment. A concern for implementers of three-tiered application architectures is the required communication between the client, database and logic components is complex to code and may reduce application performance.

The hand coding of the interapplication communication software necessary to implement a three-tiered system is time-consuming and difficult. To overcome the barrier, developers must use tools that can automatically generate all interapplication communication code.

Remote procedure calls (RPCs), messaging systems, object request brokers (ORBs) or combinations of the above are commonly employed as the interapplication communication middleware among the various tiers in multitier environments. Of course, the communication middleware that is used to connect the various software tiers impacts the performance attributes of three-tiered system.

Increased interapplication communication can also lead to decreased performance. The addition of servers to a networked environment will increase network transaction loads, thereby negatively affecting overall system performance.

However, while a three-tier application architecture demands that the various software tiers be separated logically, the tiers could be physically located on the same server. In many instances application logic should be placed on the same physical server as the database, although not in the form of stored procedures. This will minimize network traffic, increase application throughput and reduce network costs.

Application servers

Many tool suppliers understand the inadequacies of the simple, two-tier approach to client/server. Thus, they modified existing toolsets, or created new ones, that support the concept of application partitioning.

Tools that support application partitioning allow developers to specify applications logically without describing where the pieces of the application will run. After the application is fully specified, it can be split into separate processes that can be allocated to different clients and servers in the network, thereby creating a multitiered application architecture. (See Fig. 1.)

Common sense usually dictates that application code be split along the lines of a typical three-tiered application architecture with the interface, data structures and procedural logic located on the client, the database and a central server, respectively.

The platform holding the application logic should be a highly optimized, scalable multiprocessor system, running under an operating system, such as Unix, OS/2 or Windows NT, that supports symmetric multiprocessing. If performance of the application engine becomes an issue, additional processors can be added to the server to increase throughput.

Unfortunately many tools that support partitioning automatically convert processes allocated to the server as stored procedures for the installed database management system. The approach overcomes the difficulty of writing triggers and stored procedures by hand. However, users are again left with the problem of having shared business logic tied to a single DBMS.

Other tools supporting partitioning can generate interpreted 4GL code for the client or server or both. This approach requires that a runtime be resident on all impacted clients and servers and can result in performance bottlenecks as applications are scaled up in computational complexity or in the number of supported users.

Still other partitioning tools generate compilable 3GL code (C or C++) for the client(s) and server, as well as the necessary application and database communication middleware. Still other tools supportcompiled and interpreted partitions.

Visual partitioning

Effective application partitioning requires tools that allow developers to quickly and easily move code to any physical location on a network, build and benchmark the running application, and repartition the application logic as necessary. The best partitioning tools handle this task graphically. In tools supporting graphical partitioning, icons representing blocks of code are dragged-and-dropped onto icons representing physical servers. Other partition products use a combination of wizards, form filling and coding to specify the servers that will execute partitions.

A second feature separating partitioning tools from partitioning pretenders is that the former allow developers to work with a single logical model of the application. Partitioning the logical components of an application across the various physical clients and servers is usually accomplished immediately before generation time.

Server failover/load balancing

The primary reason developers partition applications is to increase the execution efficiency of the resultant systems. But this is not the only reason. Partitioning is a key method for load balancing applications -- which is a type of performance enhancement -- and to support server failover. For example, a single logical partition can be replicated across multiple servers. (See Fig. 2). Clearly, applications can be designed so that if Server 1 servicing partition A becomes bogged down, the application can switch to Server 2 (and so on) to service incoming requests for partition A. This is an example of using partition to support dynamic load balancing.The same basic partition architecture can also support server failover. (See Fig. 2.) Applications can be designed so that if partition A on Server 1 becomes unavailable due to server failure, the program switches to Server 2 (and so on) and executes partition A.

Specifically, partitioning can be used to provide server failover due to hardware failure. (See Fig. 2.) Partitions, however, can also become unavailable do to software failure. That is, a partition's image in memory fails -- some other program "steps" on its memory -- yet the physical server (the hardware) continues to run. To overcome this problem, multiple versions of the same partition can be duplicated and running on the same server. (See Fig. 3.) Under this scenario, when a particular partition on a server becomes unavailable, the application automatically fails over to duplicated partitions running on the same server but in their own memory space.

Application development tools supporting application partitioning can be distinguished by the support (or lack thereof) for static and dynamic partitioning.

Static partitioning, the most commonly supported type of application partitioning, demands that developers regenerate and reinitialize applications whenever the physical environment is modified. During the repartitioning phase, different partitions are assigned, then dragged and dropped to specific physical machines where they are generated. The impacted systems must be halted and restarted for the changes to take place.

Dynamic partitioning implies that application partitions can be moved from one server to another without "taking down" the systems. Basically, applications can be "reconfigured" during runtime. As one would expect, implementing this feature is easier if the run-time environment is an interpreted rather than compiled executable.

Dynamic partitioning, however, is possible in compiled environments. For example, complete applications can be duplicated among the various servers running the application.

The complete applications in the form of packages of executable libraries containing all applicable application services are deployed to all platforms. (See Fig. 4.) The link between logical and physical servers is built dynamically, enabling the deployment of smart pointers to multiple servers throughout the network. Developers identify which services should be memory resident using point-and-click and form filling routines.

Conclusion

Developers have a choice among execution architectures when building distributed systems. Two-tier architectures, including those systems employing database stored procedures, are common implementations and meet the need for the majority of system building efforts.

For performance, security and maintenance reasons, enterprise scale distributed systems require multitiered execution architectures. Partitioning tools are available that can ease the building of such systems. Partitioning tools can be differentiated based on any support for graphical and dynamic partitioning, as well as support for server failover and load balancing. The interapplication communication middleware used by the various toolsets further differentiate the products.

Multitiered application architecture

Partitioning tools allow a single logical application to be "partitioned" across various clients and servers.

Fig. 1

Source: SPG's Analyst Services

Partitioning for load balancing and server failover

A single logical partition can be replicated across multiple servers.

Fig. 2

Source: SPG's Analyst Services

Partitioning for software failure

Multiple versions of the same partition can be duplicated and running under the same server.

Fig. 3

Source: SPG's Analyst Services

One approach for dynamic partitioning

Complete applications can be duplicated among the various servers on which an application will run.

Fig. 4

Source: SPG's Analyst Services