- Microsoft

advertisement
Enterprise Library
Caching Application Block
Brian Button
Software Design Engineer
Ron Jacobs
Product Manager
Scott Densmore
Software Design Engineer
Agenda
Caching architectural guidance from
patterns & practices
Describe implementation of caching
scenarios and guidance using the
Caching Application Block
Demonstration
Questions
Sound familiar?
Users are complaining about application
performance
You have already spent the next year’s IT
budget scaling out your database servers to
handle the amount of requests for data
Your application cannot perform, or is
severely degraded, without a live
connection to the backend data source
Why Cache?
Performance
Storing relevant data as close as possible to the data
consumer avoids repetitive data creation, processing, and
transportation
Scalability
Avoid wasting resources processing the same data, business
functionality, and user interface fragments required by
multiple users and processes
Reduce database requests, allowing more users to be served
Availability
Storing that data in another place, your application may be
able to survive system failures such as network latency, Web
service problems, or hardware failures
Sample Application Caching
Scenarios
You are creating a smart client application that
uses locally cached reference data to create
requests and support offline operations
You are creating a Windows Service or Console
application which needs a cache to improve
performance
Caching Application Block
Provides a flexible and extensible caching
mechanism that can be used at all layers of an
application
Supports backing stores that persist cache data
into a database or isolated storage, so the data
can survive app restarts
Easy to use
Easy to configure, using the Enterprise Library
Configuration Tool
Thread-safe
Ensures that the states of the in-memory cache and the
backing store remain synchronized.
Exploring the Caching
Application Block
Creating the Caching Application Block
configuration
Selecting a backing store
Creating the cache
Adding an item to the cache
Setting the expiration policy
Retrieving an item from the cache
Implementing cache loading strategies
Removing an item from the cache
Flushing the cache
Key extensibility points
Creating Configuration
Add the Caching Application Block to your
application configuration
Create a cache manager for each set of data to be
cached
Designate one as the default cache manager
Cache Storage Guidance
Memory resident cache. Memory-based caching
is usually used when:
An application is frequently using the same data
An application often needs to reacquire the data
Disk resident cache. Disk based caching is
useful when:
You are handling large amounts of data
Data in the application services (for example, a
database) may not always be available for
reacquisition (for example, in offline scenarios)
Cached data lifetime must survive process recycles
and computer reboots
Caching Architecture Guide for .NET Framework Applications
Caching Application Block
Storage
Cache always exists in memory
Cache always has a backing store
Null backing store (in-memory only, not persistent)
Persistent storage
Persistent backing stores
Useful when cached data lifetime must survive
process recycles and computer reboots
Isolated storage, Data Access Application Block
Contents always match in-memory cache
In-memory cache is loaded from backing store during
cache initialization
Backing Store Configuration
Isolated Storage
Segregated by user and assembly
Caching Application Block provides partition
to segregate multiple cache managers within
an application
Backing Store Configuration
Data Access Application Block
Segregated by database instance and named
partition
Require configuring the Data Access Application
Block
Backing Store Configuration
Encrypting cache data in the backing
store
Requires Cryptography Application Block
Select Symmetric provider to use
Creating the Cache in Code
Create the default cache manager
CacheManager myCache = CacheManager.GetCacheManager();
Create the cache manager named “Products”
CacheManager productsCache =
CacheManager.GetCacheManager(“Products”);
Adding an Item to the Cache
Add an item to the cache with defaults
productsCache.Add(“ProductID123”, productObject);
Defaults
Scavenging priority: Normal
No expiration
Notes
Adding a second item with the same key as an
existing item replaces the existing item
When configured to use a persistent backing
store, objects added to the cache must be
serializable
Determining an Expiration
Policy
Time-based expirations
Invalidate data based on either relative or
absolute time periods
For use when volatile cache items—such as
those that have regular data refreshes or those
that are valid for only a set amount of time—are
stored in a cache.
Notification-based expirations
Validity of a cached item based on the
properties of an application resource, such as a
file, a folder, or any other type of data source.
Time-Based Expirations
Absolute. Allows you to define the lifetime of an
item by specifying the absolute time for an item to
expire.
Simple—You define the lifetime of an item by setting a
specific date and time for the item to expire.
Extended—You define the lifetime of an item by
specifying expressions such as every minute, every
Sunday, expire at 5:15 AM on the 15th of every month,
and so on.
Sliding. Allows you to define the lifetime of an item
by specifying the interval between the item being
accessed and the policy defining it as expired.
Time-Based Expirations
Requires using extended overload of Add method
Caching Application Block classes support timebased expirations
AbsoluteTime
SlidingTime
ExtendedFormatTime
Absolute time example: expire at 2:00 AM on
3/21/05
DateTime refreshTime = new DateTime(2005, 3, 21, 2, 0, 0);
AbsoluteTime expireTime = new AbsoluteTime(refreshTime);
primitivesCache.Add("Key1", "Cache Item1", CacheItemPriority.Normal,
null, expireTime);
Sliding Time Expirations
Sliding time example: expire if item has
not been accessed for 5 minutes
TimeSpan refreshTime = new TimeSpan(0, 5, 0);
SlidingTime expireTime = new SlidingTime(refreshTime);
primitivesCache.Add("Key1", "Cache Item1", CacheItemPriority.Normal,
null, expireTime);
Extended Time Format
Expirations
Extended time format
“<Minute> <Hour> <Day of month> <Month> <Day of
week>”
* means run every period
Examples
“* * * * *”
“5 * * * *”
“* 21 * * *”
every day
“31 15 * * *”
“7 4 * * 6”
“15 21 4 7 *”
expires every minute
expire 5th minute of every hour
expire every minute of the 21st hour of
expire 3:31 PM every day
expire Saturday 4:07 AM
expire 9:15 PM on 4 July
Extended Time Format
Expirations
Extended format example: expire at midnight
every Saturday
ExtendedFormatTime expireTime =
new ExtendedFormatTime("0 0 * * 6");
primitivesCache.Add("Key1", "Cache Item1", CacheItemPriority.Normal,
null, expireTime);
Notification-Based
Expirations
File dependency example: expire if the file
Trigger.txt is changed
FileDependency expireNotice = new FileDependency(“Trigger.txt”);
productsCache.Add("Key1", "Cache Item1", CacheItemPriority.Normal,
null, expireNotice);
You can create custom expirations by
creating classes that implement
ICacheItemExpiration
Configuring Expiration Poll
Frequency
Removal of expired items occurs on a
background thread
You can set the frequency of how often this
thread will run looking for expired items
Item Removal Notifications
Caching Application Block provides
notification when an item is removed from
cache
Item has expired
Item was removed explicitly through code
Item was scavenged
Provide an object that implements
ICacheItemRefreshAction when item is added
to cache
productsCache.Add("Key1", "Cache Item1", CacheItemPriority.Normal,
new ProductCacheRefreshAction(),
expireNotice);
Item Removal Notifications
Class implementing
ICacheItemRefreshAction must be marked
as Serializable (for persistent backing
store)
[Serializable]
public class ProductCacheRefreshAction : ICacheItemRefreshAction
{
public void Refresh(string key, object expiredValue,
CacheItemRemovedReason removalReason)
{
// Item has been removed from cache.
// Perform desired actions here,
// based upon the removal reason (e.g. refresh the cache with the
// item).
}
}
Retrieving an Item from the
Cache
Cast returned object to correct type
Check for null (item not found in cache)
public Product ReadProductByID(string productID)
{
Product product = (Product)cache.GetData(productID);
if (product == null)
{
// Item not in cache
}
}
Loading the Cache
Proactive loading
Cache is preloaded with items on application startup
Application response time improves, as all items are in cache
Application startup time increases, as all items are loaded
May cache items that are never requested, using unnecessary
resources
Loading typically done on a separate thread, increasing complexity
Reactive loading
Cache an item after it is retrieved from the data source
Only caches items truly needed (uses less resources)
Response times slower during application execution if an item is not
yet cached
Loading the Cache
Proactively
Create cache manager
CacheManager productsCache = CacheManager.GetCacheManager();
Add items during component initialization
// Retrieve the data from the source
ArrayList list = dataProvider.GetProductList();
// Add all the items to the cache
for (int i = 0; i < list.Count; i++)
{
Product product = (Product) list[i];
productsCache.Add( product.ProductID, product );
}
Loading the Cache Reactively
Create cache manager
CacheManager productsCache = CacheManager.GetCacheManager();
Add items when retrieved from data source
Product product = (Product) productsCache.GetData(productID);
if (product == null)
{
// Retrieve it from the data provider
// and cache it for more requests.
product = dataProvider.GetProductByID(productID);
if (product != null)
{
productsCache.Add(productID, product);
}
}
Loading the Cache
Proactive caching is recommended in situations that have
one or more of the following characteristics:
You are using static or semistatic state that has known update
periods. If you use it in other scenarios, the state might expire before
it is used.
You are using state with a known lifetime.
You are using state of a known size. If you use proactive cache data
loading when you do not know the size of the data, you might exhaust
system resources. You must try to not use resources that you do not
have.
You have problematic resources, such as a slow database, a slow
network, or unreliable Web services. You can use this technique to
retrieve all the state proactively, cache it, and work against the cache
as much as it can.
Loading the Cache
Reactive caching is recommended in situations that
have one or more of the following characteristics:
You are using lots of state and you do not have sufficient
resources to cache all state for the entire application.
You are using reliable and responsive resources, such as
a database, network, or Web service that will not impede
application stability and performance.
You are interested in caching data that is not available
during the initialization of an application. For example,
this data might be affected by user input such as
common search queries or user-specific data such as a
user's profile.
Removing an Item from the
Cache
Remove item with specified key
productsCache.Remove(“Product101Key”)
No error occurs if key is not found
Flushing the Cache
Use to manage storage, memory and other
resources efficiently
Explicit flushing
Initiated by application code
Removes all items from the cache
productsCache.Flush()
Scavenging
Initiated by application block
Based upon priority and last access time
Configuration settings control size of cache and number
removed
Flushing the Cache with Scavenging
Scavenging configuration
Maximum elements in cache
Number of items removed when scavenging
occurs
Flushing the Cache with Scavenging
Priority is established when an item is added
to the cache
productsCache.Add("Key1", "Cache Item1", CacheItemPriority.High,
new ProductCacheRefreshAction(), expireNotice)
Priority values
Low
Normal
High
NotRemovable
The scavenging algorithm is not an extension
point
View/Application Share:
Demonstration
[Live Meeting View/Application Share. Use Live Meeting > Edit Slide
Properties... to edit.]
Key Extensibility Points
Custom backing store provider
Implement IBackingStore (derive from BaseBackingStore)
Use Configuration Console to select custom provider
Custom expiration policy
Implement ICacheItemExpiration
Specify object on call to Add method of CacheManager object
Plus…
Anything and everything – you have the source code!
Please post extensions and suggestions to the community
Enterprise Library v1
Caching
Exceptions
Legend
Security
Data
Access
Logging
Dependency
Plug-in
Crypto
Configuration
Config
Tool
Announcing: Enterprise Library 1.0
http://www.microsoft.com/practices
patterns & practices Live!
3/14 Enterprise Library Logging & Instrumentation
Application Block
3/17 Enterprise Library Exception Handling
Application Block
3/22 Enterprise Library Cryptography Application
Block
3/24 Enterprise Library Security Application Block
http://www.pnplive.com
http://www.microsoft.com/practices
Enterprise Library Community
http://go.microsoft.com/fwlink/?linkid=39209&clcid=0x09
Download