Mastering clearing Cache in Optimizely CMS with ISynchronizedObjectInstanceCache & MemoryCache
In the fast-paced world of web development, efficient memory management is essential for optimizing application performance and enhancing user experience. Among the many optimization techniques available, clearing memory cache using a cache key is a fundamental approach. When storing objects in cache, developers often set an expiration policy, such as an absolute or sliding cache eviction policy, to control how long the data remains. While cache clearing is manageable in lower CMS environments, production environments can be challenging, especially when sliding cache policies make it nearly impossible to expire cached items in real time.
In Optimizely, most cache management is handled by ISynchronizedObjectInstanceCache
. However, Optimizely doesn’t offer a straightforward method to retrieve all cache items in memory.
Understanding Memory Cache and Cache Keys
-
Memory Cache: This is where your web application stores data that can be accessed more quickly than if it were stored in a database or on a disk. It's a portion of RAM reserved for temporarily holding data.
-
Cache Key: This is a unique identifier used to store and retrieve specific data from the cache. Using cache keys ensures you're managing the right data.
Why Clear the Cache?
-
Performance: Over time, the cache can become cluttered with outdated data, slowing down access speeds.
-
Data Integrity: Clearing cache ensures your application uses the latest data, vital for dynamic content.
-
Memory Management: Freeing up memory can prevent memory leaks and improve overall performance.
Implementation Steps in Optimizely CMS
Step 1: Identify Your Cache System
First, identify the caching system your application uses. In Optimizely CMS, the common choice is ISynchronizedObjectInstanceCache
, which relies on MemoryCache
internally.
Step 2: Determine the Cache Key
- Static Keys: For fixed data, like user profile information, a static key pattern like
"user_" + userID
can be effective. In Optimizely CMS and Commerce, most caches utilize static keys, making cache management straightforward. - Dynamic Keys: For frequently changing data (e.g., session-based), keys might incorporate timestamps or session IDs.
Step 3: Clearing the Cache
With ISynchronizedObjectInstanceCache
, you can only clear individual items by specifying their cache key. However, if dynamic values such as user IDs, class names, content IDs, or language IDs are used, determining the exact key can be challenging.
To overcome this, you can retrieve the private property containing all cached items in MemoryCache
using BindingFlags
. This allows you to access cached entries, making it possible to locate and manage items based on a keyword search within the cache keys.
Here’s an example approach to find all cache keys matching a keyword (e.g., "cacheKey"
) and then remove them from the cache using ISynchronizedObjectInstanceCache
.
var field = typeof(MemoryCache).GetProperty("StringKeyEntriesCollection", BindingFlags.NonPublic | BindingFlags.Instance);
//_memoryCache is an instance of IMemoryCache
var collection = field?.GetValue(_memoryCache) as ICollection;
var items = new List<string>();
if (collection != null)
{
foreach (var item in collection)
{
var methodInfo = item.GetType().GetProperty("Key");
var val = methodInfo?.GetValue(item);
if (val != null)
items.Add(val.ToString());
}
}
var cacheKeysTobeCleaned =
items.Where(key => key.StartsWith(cacheKey, StringComparison.OrdinalIgnoreCase)).ToList(); //cacheKey is the keyword we are searching for in cacheKey
if (!cacheKeysTobeCleaned.Any())
return NotFound();
foreach (string cacheKeyToBeCleaned in cacheKeysTobeCleaned)
{
//_cache is an instance of ISynchronizedObjectInstanceCache
this._cache.RemoveLocal(cacheKeyToBeCleaned);
this._cache.RemoveRemote(cacheKeyToBeCleaned);
}
nice, this might become handy for my plugin. +1
Really nice article and helpful for me.