Caching Architecture Guide for .NET Framework Applications
Caching in Distributed Applications
Summary: This chapter maps the caching technologies with the application layers each should be used in.
The previous chapters of this guide have reviewed the available caching technologies that exist in the Microsoft .NET Framework and Microsoft Windows, and has explored their benefits and limitations. The next step is to map them to the application layers and elements that exist in distributed applications. This helps when you are selecting the appropriate caching technique for a specific layer and element.
This chapter contains the following sections:
- "Caching in the Layers of .NET-based Applications"
- "Selecting a Caching Technology"
- "Considering Physical Deployment Recommendations"
Caching in the Layers of .NET-based Applications
This section provides a summarized review of .NET-based application architecture, its common elements, and the roles of those elements. You will find this information useful later in the chapter when identifying which caching technologies are most appropriate for each element in a typical .NET-based distributed application and deployment configuration.
Figure 3.1 shows an abstracted view of .NET-based distributed application architecture containing three logical application layers: user services, business services, and data services. The abstraction of a distributed application into these logical layers provides the means for building an application according to required design goals such as scalability, availability, security, interoperability, and manageability.
Figure 3.1. .NET-based distributed application architecture
For a complete overview of the application layers, see "Application Architecture for .NET: Designing Applications and Services" in the MSDN Library.
Caching in the User Services Layer
The user services layer is responsible for enabling the user to interact with the system. This layer includes rich client-based applications using the .NET Framework Windows Forms user interface and Web-based systems using HTML.
The layer comprises of two types of components: user interface (UI) components and UI process components. The next sections describe these components.
Caching in UI Components
Most solutions need to provide some way for users to interact with the application. User interfaces can be implemented using Windows Forms, ASP.NET pages, controls, or any other technology capable of rendering and formatting data for users and acquiring and validating data from users.
You should use UI components to cache data such as:
- ASP.NET pages
- ASP.NET page fragments
- Windows Forms controls with a long render time (for example, TreeView controls)
Because UI personalization data is relevant to a specific UI technology, you may also decide to cache this in the UI components of your application.
Caching these types of data in UI components can improve the performance of your applications.
Caching in UI Process Components
UI process components are used to separate client-side operations, such as authorization, validation, process management, and state management, from the actual user interface. By using these components instead of hard-coding the logic into the user interface, the same components can be reused for multiple user interfaces and applications.
You should use UI process components to cache data such as:
- User credentials
- Business data
- Configuration data
- Metadata
Caching these types of data in UI process components can improve the performance of your applications.
Caching Data in User Services Layer Elements
If you are caching business data in user services layer elements, it is recommended that you store it in the UI process components (as shown in Figure 3.2) rather than in the UI components.
Figure 3.2. Caching business data in the users services layer
The steps that occur when caching data in user service elements are:
- The UI component elements make a request for data from the UI process components.
- The UI process component checks if a suitable response is present in the cache, and if so, returns it.
- If the requested data is not cached or not valid, the UI process components delegate the request to the business layer elements and, if appropriate, place the response in the cache.
This configuration means that you can reuse the same caching technique for multiple user interfaces.
Caching in the Business Services Layer
Business components are usually designed and built to be deployed in Web farm and application farm environments. Because of this, they are designed to not hold state beyond request/response pairs, and are thus termed stateless components.
You should strive to build your components in this way, especially in transactional applications or applications that have components running in Web farms or application farms. Caching in the business services layer should be used only to hold certain types of state that you have determined are good caching candidates; for example, holding non-transactional reference data that is usable across many activities from different callers. For more details about the sort of data that should be cached, see Chapter 1, "Understanding Caching Concepts."
The business services layer encapsulates the core business logic of an application and provides the delivery channels with an easy interface to interact with. The business services functionality is independent from both the underlying data sources and delivery channels.
Caching in Service Interfaces
To expose business logic as a service, you must create service interfaces that support the communication contract (message-based communication, formats, protocols, security, exceptions, and so on) that are needed by its different consumers.
You should use service interface elements to cache data such as service state representing non-transactional business data.
Caching in Business Workflows
Many business processes involve multiple steps that must be performed in the correct order and orchestrated. For example, a retail system would need to calculate the total value of the order, validate the credit card details, process the credit card payment, and arrange delivery of the goods. This process could take an indeterminate amount of time to complete, so the required tasks and the data required to perform them must be managed. Business workflows define and coordinate long running, multi-step business processes, and they can be implemented using business process management tools such Microsoft BizTalk® Server Orchestration Designer.
You can store the state being used in a business workflow between the workflow steps to make it available throughout the entire business process. The state can be stored in a durable medium, such as a database or a file on a disk, or it can be stored in memory. The decision of which storage type to use is usually based on the size of the state and the durability requirements.
Caching in Business Components
Business components have the responsibility of implementing an application's business activities; they implement business rules and perform business tasks in a request-response fashion.
You should use business components to cache data such as information in different stages of the transformation pipeline.
Caching in Business Entities
Most applications require data to be passed between components. For example, in a retail application, a list of products must be passed from the data access components to the user interface components so that the product list can be displayed to the users. The data is used to represent real world business entities, such as products or orders. The business entities that are used inside the application are usually data structures such as DataSets, DataReaders, or XML streams, but they could also be implemented using custom object-oriented classes that represent the real world entities your application has to deal with, such as a product or an order.
When caching in business entity elements, you need to consider whether to cache the data in its native format or in the format in which it is used. Based on this consideration, there are two main patterns for caching business entities elements.
Figure 3.3 shows the first pattern, where the business entities are stored in their native format in the cache storage and retrieved as necessary. The main advantage of this pattern is that data stored in its original format and does not need to be translated between different formats.
Figure 3.3. Storing business entities in the cache
Figure 3.4 shows the second pattern, where a business entities factory is used to retrieve relevant state. In this pattern, the state is stored in standard formats and translated to its original format when the data is required.
Figure 3.4. Storing data for business entities in the cache
You should store business entities in a cache only when the translation of the data in a business entities factory is expensive.
Caching in the Data Services Layer
The data services layer consists of data access components, data access helpers, and service agents. These elements work together to request and return information from many types of data source to your application. Because of this, they are classic elements in which to cache data.
Caching in Data Access Components
These components are used for centralizing access to data stores. They implement any logic necessary to access data stores thus making the application easier to manage and configure. You should use data access components to cache data such as:
- Raw data returned from queries in a non-transactional context
- Typed dataset schemas
Caching these types of information in data access components can improve the performance of your applications.
Caching in Data Access Helpers
These components are data store specific components used for optimizing access to the underlying data store and to minimize data store related programming errors. For example, a Microsoft SQL Server data access helper should implement the optimized way to connect to the SQL Server, to perform queries, or to execute stored procedures.
You should use data access helpers to cache data such as stored procedure parameters. (For more information, see the SqlHelperParameterCache class in "Data Access Application Block" in the MSDN Library.)
Caching in Service Agents
Service agents are components that function as proxies for other application services. These components implement the functionality required for interacting with the services. Figure 3.5 shows how they work.
Figure 3.5. Caching process in service agents
The steps that occur when caching data in service agents are:
- The application business logic invokes the service agent.
- The service agent checks whether a suitable response (for example, valid data that meets the requested criteria) is present in the cache, and if so, returns it.
- If the requested data is not cached or not valid, the Web service is invoked, and if appropriate, the requested data is also placed in the cache.
You should use service agents to cache data such as:
- State returned from queries in a non-transactional context
- User credentials
Caching these types of data in service agents can improve the performance of your applications.
Caching in the Security Aspects
Security policy is concerned with authentication, authorization, secure communication, auditing, and profile management, as shown in Figure 3.6.
Figure 3.6. Aspects of security
Not all of these aspects are relevant to the subject of caching, and this section describes only profile management.
Caching Profile Information
User profiles consist of information about the user that your application can use to customize its behavior. It may have user interface preferences (for example, background colors) and data about the user (for example, the region he or she is in, credit card details, and so on). You may decide to cache profile information for offline application scenarios and to enhance performance.
If the profile information contains sensitive data, you should consider signing, encrypting, or hashing it to ensure that it can't be read and that isn't been tampered with.
Caching in the Operational Management Aspects
Operational management policy is concerned with the ongoing, day-to-day running of an application, and it includes aspects such as exception management, monitoring, metadata, configuration, and service location, as shown in Figure 3.7. Not all of these are relevant to the subject of caching, and this section describes only the relevant aspects.
Figure 3.7. Aspects of operational management
For more information about operational management in distributed applications, see Chapter 3, "Security, Operational Management, and Communication Policies," of "Application Architecture for .NET: Designing Applications and Services" in the MSDN Library.
Caching Configuration Information
Your applications may require configuration data to function technically. Configuration information is generally maintained in .NET configuration files at the user, computer, and application levels. However, you can also use different storage types, such as XML files, SQL Server databases, Active Directory, COM+, and the Windows registry to store your application configuration data. Not all of these are recommended configuration stores, but they do offer adequate functionality.
Frequently accessing configuration information and metadata can cause a performance hit if the configuration information and the metadata are located in a file on a disk or in a database, especially if it is stored remotely. You can cache application-managed configuration information and metadata in memory to prevent this; however, you should ensure that you are not creating a security hole by exposing sensitive information to the wrong application code.
By using expiration policies (such as absolute time and sliding time windows) and dependencies (such as file dependencies), you can keep your cached configuration data up to date with the master configuration data. A good example of this is the way the .NET Framework handles its configuration files (Web.config and Machine.config), which are loaded into memory as soon as they are updated, causing the application to use the new configuration data as soon as it is available.
For more information about caching configuration files, see Chapter 4, "Caching .NET Framework Elements." For more information about handling cache content, see Chapter 5, "Managing the Contents of a Cache."
Common caching candidates in the configuration category are:
- Location information that is required to reach remote business layer components, external services, message queuing, and so on.
- Connection data such as connection strings and file names.
For more information about caching connection strings see Chapter 4, "Caching .NET Framework Elements."
Caching Metadata
You may design your application so that it knows information about itself to make it more flexible to changing runtime conditions. This type of information is known as metadata. Designing your application using metadata in certain places can make it more maintainable and lets it adapt to common changing requirements without costly redevelopment or deployment.
Metadata can be stored in multiple places, as described in the preceding "Caching Configuration Information" section. For centralized stores, you can use SQL Server databases or Active Directory. If you want your metadata to be distributed with your assemblies, you can implement it in XML files, or even custom .NET attributes.
A summary of good metadata caching candidates follows, while further discussion on the subject can be found in Chapter 3, "Security, Operational Management, and Communication Policies," of "Application Architecture for .NET: Designing Applications and Services" in the MSDN Library.
Common caching candidates in the metadata category are:
- Column headers captions—Instead of hard-coding column header names into your UI components, you can map a data table or a dataset to header captions stored in a cached metadata repository.
- Error messages—By raising error numbers to the UI and translating them into user friendly error messages instead of retrieving them from a database or resource files, you can improve application performance.
- User assistance text—This includes short help messages and ToolTip text.
- Menu hierarchies' structure—This includes XML Schema Definitions (XSDs)
- XML schemas—This includes XSDs, XML Data Reduced Schemas (XDRs), and Document Type Definitions (DTDs).
- Extended metadata—In some situations you may want to provide developers with additional metadata such as:
- Logical naming—In some cases, mapping logical names to physical entities makes programming tasks easier. For example, instead of letting the developer access a certain stored procedure using its physical name (sp_GetCustomersByName), a logical name (Customers) can be provided and translated to the actual name in the data services layer.
- Filter restrictions—Providing information about which fields in a data table can be used for filtering based on the available stored procedures. For example, you may want to enable filtering only on the first and last name fields in a customers form. By providing filter restrictions metadata, a client application can determine whether to enable filtering.
- Sort restrictions—Providing information about which fields in a data table can be used for sorting that table based on the available stored procedures. For example, you may want to enable sorting only on the first and last name fields in a customers form. By providing sorting restrictions metadata a client application can determine whether to enable sorting or not.
Now that you are aware of the layers within an application's architecture, you are ready to start deciding the caching technology that is best to be used in each layer.
Selecting a Caching Technology
The previous chapters explored the available caching technologies and set the general frame for further discussion on the subject; this section describes the actual considerations for selecting a caching technology. The matrix for selecting a technology can be very large and sometimes confusing, and there are a large number of variables that you need to consider. To simplify the selection process, this section focuses on only the major considerations and elements in a common .NET-based distributed application.
This section describes the main elements in a distributed application and maps them to the best caching technology based on different requirements such as state scope, durability attributes, and common scenarios in which they are used. The focus is on the following elements:
- Browser-based clients
- Smart clients (based on the .NET Framework or the .NET Compact Framework)
- User services (ASP.NET server applications)
- Business services and data services (enterprise services or non-enterprise services)
Figure 3.8 shows typical elements that exist in a distributed application. Every application has a UI representation, either thin or rich, and every application has server side logic; for example, ASP.NET for Web applications and business logic, which may or may not use enterprise services.
Figure 3.8. Common elements in a distributed application
Note Although the .NET Framework and the Windows platform provide many caching, design, and deployment options, this section concentrates on the solutions that most closely suit distributed applications.
Caching in Browser-based Clients
Chapter 2 contains an in-depth review of the options available for caching state in browser-based scenarios. The main issues that arise when caching state in browsers are that the technology options available are very limited and the caching functionality varies between different browser types. Also, when caching any information on a client, you need to be sure that security is not compromised.
When you consider whether to cache state in a browser, you should consider the following:
- Does caching state in the client create a security risk?
- Do all of the target browsers support the chosen caching technology?
The following tables compare the scope, durability, and scenario usage of browser-based caching technologies. Table 3.1 compares the scope of different technologies available for caching data for browser-based clients.
Table 3.1: Scope of browser-based caching technologies
Technology | Single page (same window) | Multiple page (same window) | Multiple windows |
---|---|---|---|
ViewState | x | Additional implementation required. | |
Cookies | x | x | x |
Hidden frames | x | x |
Table 3.2 compares the durability of different technologies available for caching data for browser-based clients.
Table 3.2: Durability of browser-based caching technologies
Technology | None | Survives browser shutdown | Survives reboots |
---|---|---|---|
ViewState | x | ||
Cookies | Subject to expiration rules in client. | Subject to expiration rules in client. | Subject to expiration rules in client. |
Hidden frames | x |
Table 3.3 shows commonly used scenarios for each of these technologies.
Table 3.3: Browser-based caching scenarios
Technology | Scenario |
---|---|
ViewState | Small amounts of data used between requests of the same page. |
Cookies | Small amounts of data used between requests of the same application. |
Hidden frames | Relatively large amounts of data accessed only from a client-side script. |
Use the information in the preceding tables to select the appropriate caching technology for your browser-based clients.
Note Caching state in a browser results in the cached information being stored as clear text. When storing sensitive data in this way, you should consider encrypting the data to avoid tampering.
Caching in Smart Clients
The following tables focus on client-side applications based on the .NET Framework Windows Forms technology. Table 3.4 compares the scope of different technologies available for caching data in Windows Forms applications.
Table 3.4: Scope of smart client caching technologies
Technology | Single AppDomain | Computer | Organization |
---|---|---|---|
Static variables | x | ||
Memory-mapped files | x | ||
Remoting singleton | x | ||
SQL Server 2000 / MSDE | x |
Table 3.5 compares the durability of different technologies available for caching data in Windows Forms applications.
Table 3.5: Durability of smart client caching technologies
Technology | None | Survives process recycles | Survives reboots |
---|---|---|---|
Static variables | x | ||
Memory-mapped files | x | ||
Remoting singleton | x | ||
SQL Server 2000 / MSDE | x | x |
Table 3.6 shows commonly used scenarios for each of these technologies.
Table 3.6: Smart client caching scenarios
Technology | Scenario |
---|---|
Static variable | In-process, high performance caching. |
Memory-mapped files | Computer-wide, high performance caching. |
Remoting singleton | Organization-wide caching (not high performance). |
SQL Server 2000 / MSDE | Any application which requires high durability. |
Use the information in the preceding tables to select the appropriate caching technology for your smart clients.
Caching in .NET Compact Framework Clients
Although .NET Compact Framework applications have not been thoroughly described so far in this guide, the caching mechanisms and recommendations for them are simply a subset of those available to other types of applications. This section focuses on client-side applications built using the .NET Compact Framework. Table 3.7 compares the scope of different technologies available for caching data in .NET Compact Framework applications.
Table 3.7: Scope of .NET Compact Framework caching technologies
Technology | Single AppDomain | Computer | Organization |
---|---|---|---|
SQL Server CE | x | Not applicable | |
Static variables | x | ||
File system | x |
Table 3.8 compares the durability of different technologies available for caching data in .NET Compact Framework applications.
Table 3.8: Durability of .NET Compact Framework caching technologies
Technology | None | Survives process recycles | Survives reboots |
---|---|---|---|
SQL Server CE | x | x | |
Static variables | x | ||
File system | x | x |
Table 3.9 shows commonly used scenarios for each of these technologies.
Table 3.9: .NET Compact Framework caching scenarios
Technology | Scenario |
---|---|
SQL Server CE | Any scope (within the device) which requires high durability. |
Static variables | In process, high performance caching. |
File system | Any scope that requires high durability. |
Use the information in the preceding tables to select the appropriate caching technology for your .NET Compact Framework clients.
Caching in ASP.NET Server Applications
This section focuses on ASP.NET server-side applications. Table 3.10 compares the scope of different technologies available for caching data in ASP.NET server applications.
Table 3.10: Scope of ASP.NET server-side caching technologies
Technology | User | Single AppDomain | Computer | Organization |
---|---|---|---|---|
ASP.NET Cache | x | |||
ASP.NET Session object (InProc) | x | Not applicable | Not applicable | Not applicable |
ASP.NET Session object (StateServer) | x | Not applicable | Not applicable | Not applicable |
ASP.NET Session object (SQLServer) | x | Not applicable | Not applicable | Not applicable |
ViewState | x | Not applicable | Not applicable | Not applicable |
Static variables | x | |||
Memory-mapped files | x | |||
Remoting singleton | x | |||
SQL Server 2000 / MSDE | x |
Table 3.11 compares the durability of different technologies available for caching data in ASP.NET server applications.
Table 3.11: Durability of ASP.NET server-side caching technologies
Technology | None | Survives process recycles | Survives reboots |
---|---|---|---|
ASP.NET Cache | x | ||
ASP.NET Session object (InProc) | x | ||
ASP.NET Session object (StateServer) | x (survives aspnet_wp process recycles) | ||
ASP.NET Session object (SQLServer) | x (survives aspnet_wp process recycles) | Possible (for more information, see article Q311209, "HOW TO: Configure ASP.NET for Persistent SQL Server Session State Management," in the Microsoft Knowledge Base). | |
ViewState | Not Applicable | Not Applicable | Not Applicable |
Static variables | x | ||
Memory-mapped files | x | ||
Remoting singleton | Good for surviving the applications process recycle (not the remoting process recycle). | ||
SQL Server 2000 / MSDE | x |
Table 3.12 shows commonly used scenarios for each of these technologies.
Table 3.12: ASP.NET server-side caching scenarios
Technology | Scenario |
---|---|
ASP.NET Cache | In process, high performance caching. Good for scenarios that require specific caching features. |
ASP.NET Session object (InProc) | User session scope cache. Good for small amounts of session data that require high performance. |
ASP.NET Session object (StateServer) | User session scope cache. Good for sharing session data in a Web farm scenario where SQL Server is not available. |
ASP.NET Session object (SQLServer) | User session scope cache. Good for sharing session data in a Web farm scenario where SQL Server is available. |
ViewState | Good for request scope scenarios. |
Static variables | In process, high performance cache. |
Memory-mapped files | Computer-wide, high performance cache. |
Remoting singleton | Organization-wide cache (not high performance). |
SQL Server 2000 / MSDE | Can be used for any scope requirement which demands high durability. |
Use the information in the preceding tables to select the appropriate caching technology for your ASP.NET server-side applications.
Caching in Server Applications
This section focuses on server-side applications, including those that use .NET Enterprise Services and those that do not. Table 3.13 compares the scope of different technologies available for caching data in server applications.
Table 3.13: Scope of server-side caching technologies
Technology | Single AppDomain | Computer | Organization |
---|---|---|---|
ASP.NET Cache | x | ||
Static variables | x | ||
Memory-mapped files | x | ||
Remoting singleton | x | ||
SQL Server 2000 / MSDE | x |
Table 3.14 compares the durability of different technologies available for caching data in server applications.
Table 3.14: Durability of server-side caching technologies
Technology | None | Survives process recycles | Survives reboots |
---|---|---|---|
ASP.NET Cache | x | ||
Static variables | x | ||
Memory-mapped files | x | ||
Remoting singleton | x | ||
SQL Server 2000 / MSDE | x |
Table 3.15 shows commonly used scenarios for each of these technologies.
Table 3.15: Server-side caching scenarios
Technology | Scenario |
---|---|
ASP.NET Cache | In process, high performance caching. Good for scenarios which require specific caching features. |
Static variables | In process, high performance caching. |
Memory-mapped files | Computer-wide high performance caching. |
Remoting singleton | Organization-wide cache (not high performance). |
SQL Server 2000 / MSDE | Can be used for any scope requirement which requires high durability. |
Use the information in the preceding tables to select the appropriate caching technology for your server-side applications.
Considering Physical Deployment Recommendations
You should consider the following guidelines when designing your cache:
- Select a technology without direct association to the current physical deployment environment because this may change during the lifetime of the application.
- If possible, use only one type of cache for the different layers. This way only one caching mechanism requires maintenance.
- Because most of the mechanisms support a key-value storage type, it is recommended that a naming convention is used. For example, cached data in the presentation layer could have the prefix of "UI_", and so on. Using a naming convention makes changing physical deployment easier.
Again, considering the caching policy in the design phase of an application can greatly simplify the physical deployment phase.
Summary
In this chapter, you have learned about the application layers in a .NET-based distributed application, and you have seen how the different caching technologies available best suit different layers.
You are now ready to consider how to cache the many elements of a .NET-based application.