📜 ⬆️ ⬇️

Windows Azure: In-Memory Distributed Cache

Most recently, Microsoft presented a large package of updates for the Windows Azure platform. The list of innovations included the long-awaited update of Windows Azure Caching. Previously, the developer faced some difficulties when working with a distributed caching system - the cache worked very slowly. Since Windows Azure stored cache data on separate servers, it took about 30-100 ms to request a data sample, which is not permissible for the system, which accelerates data access.
So, what has changed in the caching system?
Microsoft decided to keep up with its competitors and added support for In-Memory Caching. Now the data is not stored on a separate server, but in the server’s RAM and, accordingly, data access occurs instantly. Let's try to implement a new cache and compare the speed of work with the old using the example of ASP.NET MVC 3 (C #).

Caching provider

To access the cache, we need a provider. To implement a provider, create an interface for it with the necessary methods:
public interface ICacheProvider { void RemoveFromCache(string key); T GetFromMethod<T>(string cacheKey, TimeSpan cacheDuration, Func<T> method); T GetFromMethod<T>(string cacheKey, Func<T> method); } 

The first method, obviously, removes an object from the cache by key, the rest receive (add in case of absence in the cache) data with the key and period set.

The next step is implementing the provider itself. It does not describe the process of installing Windows Azure SDK 1.7, it implies that the developer has all the necessary libraries and components for developing for Windows Azure
')
We note a few key points to consider when implementing an provider:

The provider itself will look like this:

 public class AzureCacheProvider : ICacheProvider { //        private readonly string _prefix = StaticHelper.GetCurrentVersion(); private readonly object _locker = new object(); private readonly DataCache _cache; public AzureCacheProvider() { lock (_locker) { { var factory = new DataCacheFactory(); _cache = factory.GetDefaultCache(); } } } private void RemoveFromCache(string key, DataCache cache) { lock (_locker) { cache.Remove(_prefix + key); HttpContext.Current.Items.Remove(_prefix + key); } } private T GetFromCache<T>(string key, TimeSpan expiration, Func<T> method, DataCache cache) { object cacheItem = HttpContext.Current.Items[_prefix + key]; if (cacheItem == null) { cacheItem = cache.Get(_prefix + key); if (cacheItem != null) HttpContext.Current.Items[_prefix + key] = cacheItem; } if (cacheItem == null) { lock (_locker) { cacheItem = cache.Get(_prefix + key); if (cacheItem == null) { cacheItem = method(); if (cacheItem != null) { HttpContext.Current.Items[_prefix + key] = cacheItem; cache.Put(_prefix + key, cacheItem, expiration); } } } } return (T)cacheItem; } public void RemoveFromCache(string key) { RemoveFromCache(key, _cache); } public T GetFromMethod<T>(string cacheKey, TimeSpan expirationSeconds, Func<T> method) { return GetFromCache(cacheKey, expirationSeconds, method, _cache); } public T GetFromMethod<T>(string cacheKey, Func<T> method) { return GetFromMethod(cacheKey, TimeSpan.FromMinutes(15), method); } } 


HttpContext.Current.Items here is used to store in memory already received in the current query objects from the cache, in case of repeated access to data.

Role configuration

After writing the provider, you need to configure the cache. In the SDK version 1.7, a new Caching tab has appeared in the properties of the role.

image

On this tab, you need to enable cache support (Enable Caching) and set the amount of allocated memory for our data (for example: Co-located Role: Cache Size 30%)

Web.config

The latest preparation will be the addition of new sections to Web.config. If at the very beginning of the file there is no section configSections , then it must be added. Then put the following code inside:

 <section name="dataCacheClients" type="Microsoft.ApplicationServer.Caching.DataCacheClientsSection, Microsoft.ApplicationServer.Caching.Core" allowLocation="true" allowDefinition="Everywhere"/> 

At the end of the Web.config we add the description of the dataCacheClients section:

 <dataCacheClients> <tracing sinkType="DiagnosticSink" traceLevel="Error" /> <dataCacheClient name="default"> <autoDiscover isEnabled="true" identifier="   Web-,       " /> </dataCacheClient> </dataCacheClients> 

This completes the configuration of Windows Azure Caching. Let us turn to the performance test.

Cache testing


To test the cache, create a simple page that will cache the current time:

 <h1>Cache test</h1> Before: <%=DateTime.Now.Millisecond%> ms<br/> <%=Facade.Instance.Cache.GetFromMethod("currentTime", () => DateTime.Now)%><br/> After: <%=DateTime.Now.Millisecond%> ms<br/> <%using(Html.BeginForm("ClearCache","Admin"))%> <%{%> <input type="submit" value="Clear Cache"/> <%}%> 

Facade.Instance.Cache in the code above is an instance of an AzureCacheProvider object obtained using IoC.
The ClearCache action looks quite simple:

 public ActionResult ClearCache() { Facade.Instance.Cache.RemoveFromCache("currentTime"); return View("admin"); } 

results


After compiling the project and launching the page in the cloud, we see the following result:

Cache test
Before: 553 ms
6/10/2012 11:09:40 AM
After: 569 ms


When you first open the page, an entry is added to the cache, which in this example takes about 16 ms. With a subsequent page refresh, the result is as follows:

Cache test
Before: 508 ms
6/10/2012 11:09:40 AM
After: 508 ms


Sampling data from the new In-Memory Distributed Cache takes less than 1 ms. In terms of speed, this cache is not inferior to InProc cache.

As it was before?


To find out how it was before, you need to roll back the SDK to version 1.6 and make a small modification of Web.config. Replace the dataCacheClients section with:

 <dataCacheClients> <dataCacheClient name="default"> <hosts> <host name="[ ID].cache.windows.net" cachePort="22233" /> </hosts> <securityProperties mode="Message"> <messageSecurity authorizationInfo="[ ]"></messageSecurity> </securityProperties> </dataCacheClient> </dataCacheClients> 

After compiling the project and opening the test page, we see the following results:

Cache test
Before: 521 ms
6/10/2012 11:09:40 AM
After: 550 ms


Those. 29 ms to add a cache entry and after updating the page:

Cache test
Before: 501 ms
6/10/2012 11:09:40 AM
After: 533 ms


32 ms to retrieve a cache entry.

Total


The latest innovation Microsoft has solved one of the main problems of Windows Azure - the problem of distributed caching. Now you can use distributed cache without fear of degrading application performance, and those who used other tools for this within the Azure cloud can return to the functionality provided by the Windows Azure API.

Source: https://habr.com/ru/post/145800/


All Articles