Showing posts with label Architecture. Show all posts
Showing posts with label Architecture. Show all posts

Friday, March 6, 2009

Designing for Performance

 

bB-2StealthBomber Do you think performance is tuned after the code has been written or is it one of those obvious quality attributes that has to be considered as part of the functional requirements of the system? Considering performance as an afterthought and deciding to tune your software towards the end of the development can only help so much. You really need to consider performance at every stage of software development life cycle. The system's responsiveness needs to be measured and calibrated at every iteration of your product design and development.

One can definitely design systems with that performance as an afterthought notion but I'm not sure whether they would be widely used. Would Google or Amazon have been that popular if they had taken minutes to search for content or books? I bet not. Would Porsche, Ferrari or Stealth Bomber have been possible with the performance-as- afterthought process? I bet not. They were built ground up for performance and speed and they live up to those standards. Why should you believe me? I've driven every single one of them. In my dreams. Every night. Seriously.

So, how does one approach thinking about performance at the design phase? Does one need to employ different design principles for different delivery channels? Though there are specialized patterns which cater to a specific delivery channel like Web, Mobile or desktop based solution but there are some which are overarching and can be applied regardless the delivery channel. IMHO, one needs to consider the following -

  • Caching - Caching of data can dramatically increase the responsiveness of any application though certain considerations need to be made before finalizing the strategy. One could follow W3 of Caching - What, When and Where.
    • What to Cache - It really depends on the application context but anything that would take inordinate amount of time to retrieve and doesn't change that frequently is a good candidate for caching. I also always think about the memory footprint of the cache. I would look at the size of the every object that needs to be cached by enumerating over its properties and computing the actual memory it is going to consume. This helps in the Where part of the puzzle.
    • When to Cache - One really has two options around it - Proactive or Reactive. Proactive Caching is generally employed for datasets(Not the ADO.NET DataSet) that get used in the application in most of the scenarios. It is a technique by which one loads the dataset at the start of the application. Reactive Caching is used when one is not sure when a dataset would get used thus it gets cached it after its first retrieval.
    • Where to Cache - It depends upon how fast the cached dataset needs to be accessed and how big it is? If the cached data doesn't need to be loaded in fractions of milliseconds and is huge then it makes sense to use an Out of Process Cache. But, if the size of the dataset is not that big then one can think about caching the data in the same process. In-process caching gets a little tricky for the web delivery channel when one has a cluster of web servers. As the cache needs to be identical in all the webservers, one has to either develop something in house or use sophisticated products like NCache to replicate the cache state among the clusters.

 

  • Data Structures - Poor selection of data structures can lead to lot of memory wastage and denegenration of performance. Would you really use a LinkedList for storing all your Customers? Would you use an Array for dataset that is always changing? Probably not. I think one needs to decide early the data structures which would get used in the domain model of the product. 

 

  • Algorithms - One not only needs to use the right data structures to store the data but also use the right algorithms to insert/retrieve the data from them. They are tightly coupled and both of them have to be selected in tandem. If you were to sort your dataset, would you use BubbleSort or QuickSort? You wouldn't care if the dataset is too small but using BubbleSort in large datasets could be an extreme wastage of CPU cycles. The selection of the right algorithm plays a huge part in the responsiveness of your application and it makes sense to give a lot of thought to it.

 

  • Asynchronous Behavior - I'm not sure whether asynchronous behavior can  increase the response times of your application but they can tremendously increase the responsivess of your application. In the world of short attention spans and even smaller patience levels, responsiveness means performance. One can use variety of techniques to break the long running transactions and execute them in a step manner while engaging the user. Do you have order processing which runs through a myriad business instructions? Do you have your users see a fascinating marvel called rotating hourglass and twiddle their thumbs after they submit an order? Wouldn't it make sense to break the transaction, put it on a order processing queue and let users know they would be informed when their order is processed? One can easily use some sort of queuing mechanism like MSMQ to decouple the component that submits the order from the service that actually processes the order. In the web scenario, one could use AJAX rather than having the user reload the entire web page again.

 

  • Interface Design - It makes sense to design coarse grained interfaces a.k.a Chunky Interfaces to reduce the chatter among the software layers. It's best to have calls to retrieve and insert data in chunks rathen than invoking multiple method calls to achieve the same logical unit of work. For example, let's say you had an Order class, which had details about the Order, its LineItems and the details about the Customer. Would you have 3 separate calls to create Order, OrderLineItems and Customer or just have one call to create Order, which would execute a transaction to create the Customer if it doesn't exist and then save the Order and its LineItems. It would be prudent to have only one call rather than making 3 independent service calls to achieve this logical unit of work as it reduces the chatter between service layers and help boost performance.

 

  • Data Partitioning - As the slowest moving piece of any application is I/O, it makes sense to give a lot of thought to the database design and how the data would be partitioned in it, if needed.  There are times when certain datasets get used a lot, think of million of hits per day. In those scenarios, it makes sense to partition these datasets with the help of a partition key. The partition key decides how the data would be split physcially. For example, if you are building a social network and you get equal number of english, french and german speaking users then should you divide the users in different databases? It depends upon the context but one should think about the layout of the data persistence. MetaDatabaseIn MS SQL Server 2005, one could even partition a table without having the application ever to know about that the data is distributed in different filegroups. 

 

 

Are there any special design considerations that you know of, which can help boost the performance?

Wednesday, March 12, 2008

ASP.NET MVC vs. WCSF

I've been thinking about the best way of building enterprise web applications after creating few sample applications with both ASP.NET MVC framework and WCSF and if I was to look at from a holistic perspective, both the frameworks provide excellent separation of concerns thus enhancing the modularity and testability of the application yet there are differences in their approaches.

ASP.NET MVC provides a new ground-up framework for building web applications that doesn't uses the core ASP.NET framework concepts like PostBacks, ViewState, Code Behind etc. It really enforces the discipline of creating simiplistic views, which are dependent on a controller to handle user events and pass the model to it. It forces one to think of Views as a pure rendering mechanism and doesn't allow the developer to pollute the .aspx files with all the gobbledygook of interactions with services to build a page. It provides a very clean way of handling all the HTTP verbs and provides a pluggable architecture to inject components to handle those requests. All the HTTP calls are routed to a controller which decides the action i.e. method to invoke, gets the right model and passes it to View to render the data. One can build very clean REST based solutions by using ASP.NET MVC framework. To learn more about the framework, I would recommend reading Scott Guthrie's blog and viewing these videos.

WCSF on the other hand builds uses the existing ASP.NET Forms based framework and provides a pattern based approach of building applications. It has guidance bundles which provides the right solution and project structure, code generation recipes, out of the box integration with various application blocks like Security, Exception Handling and Logging. It also provides good separation of concerns by following the MVP design pattern. Thus, a developer doesn't have to learn new patterns of building web applications and can utilize all the core concepts of PostBack,ViewState etc. and on top of it is given pre-configured access to the Logging, Exception Handling and Authorization features.

IMHO, WCSF is a better option if one was looking at capitalizing on ASP.NET strengths and, standardizing web development practices. ASP.NET MVC framework provides utmost flexbiity in creating web solutions but it's a 180 degree change in the way we have been building ASP.NET web applications and I'm not even sure how would it pan out while building enteprise applications. In the coming days, I would publish a detailed comparison of both the technologies.

Monday, March 10, 2008

Starting out with Web Client Software Factory a.k.a WCSF

Lately, I've been completely submerged in Software Factories - WCSF and WSSF(Web Service Software Factory) and have come to like one of them, WCSF. I'm bit surprised about the fact that it hasn't caught on to lot of people's imagination albeit having lots of features to create ASP.NET web applications in a standardized way. 

What it is?

It is designed to help one quickly and consistently create web applications that adhere to well known architecture and design principles and patterns. It is an integrated collection of VS.NET solution and project templates, various code recipes, design patterns and prescriptive guidance about creating large scale modular web sites. It synthesizes ASP.NET, ASP.NET AJAX, MVP Design Pattern, Application Blocks of Enterprise Library, Windows Workflow Foundation and VS.NET Solution templates and wizards to create these modular web sites.

Why should one care about it?

There are various reasons why one should care about the Client Software Factory but there are few that stand out -

  • It provides a sound baseline for creating web applications which provides a mature web solution structure, out of the box integration with various application blocks like Security, Exception Handling and Logging and, good separation of concerns between layers(through Dependency Injection) thus improving the testability of the application.
  • The Factory allows an organization to customize and extend the code recipes and templates to suit their architectural style.

What is the best way to get started?

The best way to get started on WCSF is to install it and go through the hands-on lab on codeplex. One needs the following before installing the client factory -

Though there are lot of how-to articles and help on codeplex for WCSF but I've found David Hayden's Screencasts an invaluable resource in understanding WCSF. He has brief presentations covering various aspects of WCSF and I would highly recommend viewing all his screencasts before starting out.

Wednesday, November 7, 2007

Marriage of WCF and ASMX

I never imagined that writing a simple POX based application with correct interface semantics in the current release of WCF would be such a pain. Wait. It is impossible.

The intent was to expose a WCF service that can return POX when invoked through a regular well-formed URL with Query strings or submit HTML form data to it while doing a HTTP-POST -- Just like we used to do in the good ol' ASMX days. Guess what, this feature is not natively built into the current release of WCF.

Well, the WCF geek would be shrugging his head right now, itching to show me the way to build WCF services that can be consumed by HTTP-GET/POST verbs and can return POX. Not so fast, boy. I'm cognizant that one can build services which can return POX but they are loosely typed i.e. they have to declare methods which can only take Message type as an input. What does one do when one has to define operation contracts that need to define native data types as input parameters in the method signature?

Okay, I lied.

I know there is yet a better way -- To build a router, basically a message inspector, that can route the messages to the right operation contracts by inspecting the kind of action that is desired by the user. But, can you imagine how much code one would have to write to build this router in the context of a gigantic enterprise class application? I think you already know the answer. At least, I don't want to. As a matter of fact, I cringe imagining someone writing that kind of code as it would not be maintainable in the long run.

The good news is that WCF in .NET 3.5 would support the desired feature set out of the box but the bad news is that the upcoming framework is still in beta and to make matters worst, there isn't any confirmed release date. We have to roll out the system in production by January thus couldn't bet on the beta release. Thus, I ended up choosing ASMX to build our service delivery platform. But, I really wanted to harness the power of WCF to build the service delivery platform as it provides options galore to configure and host services.

So, what did I end up doing? Married both the technologies. Our service interfaces have both the WebService and ServiceContract Attributes, the methods have both the WebMethod and OperationContract Attributes. We ended up created ASP.NET Web Services project and decorated the WCF tags on the services which would allow us to switch to the new framework when it comes out without compiling the code. Of course, we would have to provide the right configuration to host it as a WCF service but still we wouldn't have to touch the code. Here is how a service interface looks like --


This way we de-risk ourselves by not adopting a beta product but still be ready to embrace the new framework. Have you grappled with this problem and have a better solution? I would appreciate if you can take the time out to share your thought process.

Thursday, July 12, 2007

Designing Windows Folder Structure

For the first time, I was let down by my esteemed GSP(Google Search Professional) credentials when I couldn't search for a single white paper or article about data segmentation techniques for storing large number of files on a disk. Thus, I had to spend couple of hours to create a test harness and gather results to figure out the optimal number of files in a folder.

The Context

We have tens of millions of files to be served from our media server and we were looking for optimally arranging them in a folder structure so that it doesn't impact performance. The options were either stuffing files on a single folder or creating a hierarchial structure of folders to store these files. If we were to opt for the latter then we had to solve another problem -- the optimal number of folders in a given folder? (It turns out that this really is not a problem as the performance level for files and directories are very comparable)

The Approach

I decided to write a simple program which would create N number of files in a folder and would then try to locate a particular file by its name. It turned out to be very simple program to write but I had lot of "doh" moments while running the program. For creating the files, I just created a simple method to copy an image file and paste it with a unique name --

   private static void CreateFiles(int numberOfFiles)
{
Stopwatch stopWatch = Stopwatch.StartNew();
for (int i = 0; i < numberOfFiles; i++)
File.Copy(sourceFile, path + "thermometer" + i + ".jpg");
stopWatch.Stop();

Console.WriteLine("It took {0} seconds to create {1} files", stopWatch.ElapsedMilliseconds/1000, numberOfFiles);
Console.Read();
}




And, to locate a file --

    private static void LocateFile(string filePath)
{
Stopwatch stopper = Stopwatch.StartNew();
bool isFound = File.Exists(filePath);
Console.WriteLine(isFound);
stopper.Stop();

Console.WriteLine("It took {0} milliseconds to find the file", stopper.ElapsedMilliseconds);
Console.Read();
}




I ran the program for the following configurations --


  • 1,000 files in a folder
  • 10,000 files in a folder
  • 15,000 files in a folder
  • 18,000 files in a folder
  • 1,000 files residing in their own unique folders. Thus, it had 1,000 folders.
  • 10,000 files residing in their own unique folders. Thus, it had 10,000 folders.

The Results

I ran the tests in a single user mode on WindowsXP with 1.6 GHz single core, 1 Gb of RAM laptop having a 5400 RPM disk. I've taken out the results for configuration #5 and #6 as they were identical to #1 and #2 respectively.


Our overall SLA to serve an image is 500ms thus we want the image retrieval cost to be within 40-50ms as the application has to fire business rules before serving an image. According to the test results, I've come to the conclusion that the ideal size for our case is really 10K files in folder as the OS was able to serve an image in 37ms at the first invocation and 6ms in the subsequent invocations. The overall strategy that has been devised is --


  • Create a Hash function which can take the name of the image file and output the folder name. The folder name will not be more than 4 digits so that it can support maximum of 10k entries.
  • Create folders underneath the hashed folder with the unique ids(For our case, it would never be more than 10K at this level)

Next Steps


  • Create an ASP.NET site which would serve the images.
  • Run the ASP.NET site in a program like JMeter to check the results in a multi user mode.

Please feel free to comment on the above approach and share your experiences in case you have designed for such a scenario.

Attribute Driven Architecture

I think it's an Architect's primary responsibility to come up with the most bizzare and ambiguous terms to define very simple constructs - We somehow have to show that we exist for a reason :). I was recently asked to take a session on Arch. 101 to share the things that we consider before creating architecture. Thus sprung the idea of discussing all the "abilities" and how they act as a conduit to come up with the complete technology roadmap. Here is my perspective on all the design principles that can be followed to promote one ability over another --

Thou shalt not make architecture without having an ability in mind

What are these so-called abilities and how do they come in play while crafting the blueprint of an application?

  • Maintainability
  • Performability(is that even a word?) a.k.a Performance
  • Scalability
  • Reliability
  • Flexibility

By the way, there are plethora of abilities but I will cover the important ones which come in play often enough.

Maintainability -- It is defined as an ability of a system to undergo repair and evolution. Following principles can help one achieve this ability – 

  • Modularization

  • Single Responsibility Principle – One should design classes in such a way that there is only a single focus for change.

  • Open-Closed Principle – One should design frameworks which are open for extension but closed for modification

  • Liskov Substitution Principle – One should design sub-types which are substitutable for their base types.

  • Guidelines for Writing Good and Readable Code -- I'm cognizant that this is really not a design principle but helps tremendously in creating maintainable applications.

Performance – It is defined as the responsiveness of the system. Keeping the following principles in mind can help build a high performance application -- 

  • Caching – One can follow the W3 principle of Caching – What to cache, When to Cache and Where to Cache.

  • Asynchronous Behavior

  • Coarse Grained Interfaces – Chunky interfaces always perform better than the Chatty ones.

  • Data Partitioning

  • Efficient Resource Management

Scalability – It is defined as the ability to maintain performance while system demand increases. Following design principles can help build a scalable application -- 

  • Layering

  • Loose Coupling

  • Data Partitioning

Reliability – It is defined as the ability of the system to keep operating over a period of time. Designing the system while keeping the following things in mind promote reliability –

  • Robustness

  • Clustering

Flexibility – It is defined as the ease with which a system can be modified for use in applications or environments other than those for which it were specifically designed. Following principles promote flexibility of a system -- 

  • Layering

  • Loose Coupling

  • Single Responsibility Principle

  • Open-Closed Principle

  • Code To Interface

  • Interface Segregation Principle

Of course, there are always trade-offs one need to consider when thinking of one ability over another. For example, if one is designing for flexibility that one should be ready to let go of some performance constraints.

ReferencesImplemeting System Quality Attributes by Gabriel Morgan