Welcome!

If everyone is thinking the same, someone isn't thinking

Lori MacVittie

Subscribe to Lori MacVittie: eMailAlertsEmail Alerts
Get Lori MacVittie via: homepageHomepage mobileMobile rssRSS facebookFacebook twitterTwitter linkedinLinkedIn


Related Topics: Cloud Computing, Virtualization Magazine, Infrastructure 2.0 Journal, SOA & WOA Magazine, F5 Networks, DevOps Journal

DevOpsJournal: Blog Feed Post

Infrastructure Scalability Pattern: Partition by Function or Type

A deeper dive on how to apply scalability patterns at the infrastructure layer

A deeper dive on how to apply scalability patterns at the infrastructure layer.

So it’s all well and good to say that you can apply scalability patterns to infrastructure and provide a high-level overview of the theory but it’s always much nicer to provide more detail so someone can actually execute on such a strategy. Thus, today we’re going to dig a bit deeper into applying a scalability pattern – vertical partitioning, to be exact – to an application infrastructure as a means to scale out an application in a way that’s efficient and supports growth and that leverages infrastructure, i.e. the operational domain.

This is the reason for the focus on “devops”; this is certainly an architectural exercise that requires an understanding of both operations and the applications it is supporting, because in order to achieve a truly scalable partitioning-based architecture it’s going to have to take into consideration the functional aspects of the application. There is a less efficient but still inherently more scalable implementation that relies on content-type and generation, and we’ll briefly examine that, but the more efficient method of scalable requires some application awareness on the part of not only the infrastructure but the implementers as well.

OPTION ONE: PARTITION by TYPE

This vertical partitioning pattern requires no changes to the application and very little knowledge of its functional aspects or performance characteristics. A simple vertical partitioning pattern leverages the difference in delivery characteristics across content types as the basis for partitioning at the infrastructure layer.

image

In this configuration the Application Delivery Controller (ADC) becomes the “endpoint” as far as the client is concerned. The ADC virtualizes the application and mediates all requests through it. This gives it the opportunity to apply all sorts of policies – security, acceleration, etc… – including application-layer switching. Application-layer switching allows the ADC to inspect every request and, based on its Content-Type HTTP header, direct it to an appropriate pool of resources.

Generally this type of logic is encoded in the ADC either by configuring a mapping of content-types to the appropriate pool of resources, or by leveraging the ADC’s innate network-side scripting capability.

PSEUDO-LOGIC for APPLICATION SWITCHING SCENARIO
 
if ( HTTP_HEADER["Content-Type"] is one of ["JPG", "BMP", "PNG", "JPEG", "GIF"] ) then
    use the IMAGE_POOL 
else
if ( HTTP_HEADER["Content-Type"] is one of ["TXT", "HTML", "HTM"] ) then
    use the STATIC_POOL 
else
    use the DYNAMIC_POOL

The logic is fairly simple, but the resulting improvement in performance and scalability options is tremendous. The former is due to the ability to fine-tune web and application servers in each pool “type” based on the assumption that they will be serving up a specific type of content. Time out values, number of requests per connection, etc… can all be very finely tuned based on content type. Understanding the application from a compositional viewpoint will be a tremendous help here, as it can be used to further tune those values. If every page contains X images, then X or a value just above X is likely the most optimal value for the maximum number of requests per connection for the servers in the image_pool (assuming the offloading capability of TCP multiplexing is not leveraged). Closing out connections as soon as possible and not leaving them idle has a direct, positive impact on scalability as the capacity of web and application servers is directly related to concurrent connections.

Partition by Type is a simple scalability pattern that can be applied to just about any application without modification, which means you will likely be able to apply it to third-party or closed-source applications for which you do not have the source and cannot easily modify to apply other scalability solutions.

OPTION TWO: PARTITION by FUNCTION

The second – and ultimately more scalable architecture – requires a better understanding of usage patterns and application resource consumption based on functionality. This can be as broad as “search” and “read forum” and “update forum” or as granular as “add to cart” and “finalize order”. A more broad approach can often be accomplished without application modification or even in-depth understanding of the application, but the latter will often require more work if the application itself was not developed with functional partitioning in mind. In the case of more modern, Web 2.0 applications that are more and more being enabled with an API, the API can also be considered in whole a “functional partition” with more granular partitions based on specific API function within that breakdown as well.

This approach works particularly well with web-based applications because all requests have a URI and even in the case where they use the same URI the query parameters are often used to differentiate functionality – whether those are passed via GET or POST. It is more efficient if the functional partition imagecan be determined from the URI but not so much that one would abandon such an architecture if the differentiation requires data-level inspection.

When partitioning by function you’ll want to identify the partitions by URI, either using a list (less efficient) or a shared, common path (more efficient).

http://www.example.com/search/products

http://www.example.com/search/partner/products

http://www.example.com/search/site

In this example you could use the individual URIs, but a more efficient approach is to use the shared path in the URI, namely the “/search/” string. The ADC, deployed in the same topological manner as described in the Partition by Type scenario, implements a network-side script (or other means of mapping URI to resource pools) and again “switches” requests based on the existence or lack of existence of specific key strings. Each key string maps to a pool of resources that are dedicated to performing that particular task.

PSEUDO-LOGIC for PARTITION by FUNCTION
 
if ( URI contains ("/search/")) then
    use SEARCH_POOL
else
if ( URI contains ("/profile/")) then 
    use PROFILE_POOL
else
    use STATIC_POOL 
This method also works if the function group is passed via a query parameter, e.g. “?option=com_pictures”. The URI can still be queried for the specific parameter, as is also the case with data-level inspection. The latter will require more resources and incur a fraction more latency on the ADC than the former, but the improvements in scalability (and thus availability) will almost certainly make up for those microseconds of delay.
The benefits of this approach are similar to the Partition by Type scenario, though it is more the case that optimization will occur at the resource level. Some functional groupings require more RAM, others more CPU, others perform more disk I/O. Separation of functional groups based on similar resource-type consumptions allow you to individually scale not only the particular function group based on usage patterns, but also lets you individually scale the servers (virtual or physical) based on the resource characteristics for that group of functionality.
Partition by function is particularly useful for APIs, especially in scenarios in which graceful degradation of functionality is warranted as a method of maintaining core availability.

DEVOPS – FOR THE WIN

Both of these vertical partitioning patterns requires an understanding of application delivery infrastructure (load balancing and application switching), web operations administration, and application architecture in general. This is a very broad set of skills to expect from any one individual, but it is the core of what comprises the emerging devops discipline.

Devops is more than just writing scripts and automating deployment processes, it’s about marrying knowledge and skills from operations with application development and architecting broader, more holistic solutions. Whether the goal is better security, faster applications, or higher availability devops should be a discipline every organization is looking to grow.

In our next deep dive we’ll dig into sharding and how to apply it to sessions and the application server layer to achieve higher availability.


Related blogs & articles:

Follow me on Twitter View Lori's profile on SlideShare friendfeed icon_facebook

AddThis Feed Button Bookmark and Share

Read the original blog entry...

More Stories By Lori MacVittie

Lori MacVittie is responsible for education and evangelism of application services available across F5’s entire product suite. Her role includes authorship of technical materials and participation in a number of community-based forums and industry standards organizations, among other efforts. MacVittie has extensive programming experience as an application architect, as well as network and systems development and administration expertise. Prior to joining F5, MacVittie was an award-winning Senior Technology Editor at Network Computing Magazine, where she conducted product research and evaluation focused on integration with application and network architectures, and authored articles on a variety of topics aimed at IT professionals. Her most recent area of focus included SOA-related products and architectures. She holds a B.S. in Information and Computing Science from the University of Wisconsin at Green Bay, and an M.S. in Computer Science from Nova Southeastern University.