I'm building an EF6 web app in Azure and I'm using Azure Cache. I'm testing calls to my WCF service and I'm getting wildly erratic response times - between 300ms and 15sec!
I configured my code according to the this example and it runs fine locally
I've debugged remotely and I can see that the cache key is being found and the data is getting called from cache, so I'm struggling to understand why there is sych a huge variation in response times. Most of the time it's 5+sec which is obviously waaay too long.
The example I've been testing is as follows:
WCF service GET request to: http://feniksdev-staging.azurewebsites.net/EkckoNewsService.svc/getFriends
// Cache client configured by settings in application configuration file.
public DataCacheFactory cacheFactory = new DataCacheFactory();
public DataCache _cache;
public DataCache cache
{
get
{
if (_cache == null)
_cache = cacheFactory.GetDefaultCache();
return _cache;
}
set { }
}
...
...
[OperationContract]
[System.ServiceModel.Web.WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "/getFriends")]
public string getFriends()
{
string cachekey = "getFriends/{" + user.Id + "}";
object result = cache.Get(cachekey);
if (result == null)
{
using (EkckoContext entities = new EkckoContext())
{
var frnds = entities.UserConnections.Where(uc => uc.UserId == user.Id).Select(uc => new { Name = uc.Friend.Username }).ToList();
JsonSerializerSettings jsonSettings = new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects };
string json = JsonConvert.SerializeObject(frnds, jsonSettings);
cache.Add(cachekey, json);
return json;
}
}
else
{
return (string)result;
}
}
UserConnection is a simple table in my db and currently has no data, so the call returns an empty JSON array. user
is a Session object and currently defaults to 1 for user.Id
When remote-debugging this, the object is found in cache and the cached object is returned. So all good, except the response time still varies by a factor of 20 (300ms - 6sec).
When remote debugging one of the other web service methods, I got the following error when attempting to access the cached object using the corresponding key (object result = cache.Get(cachekey);
):
{"ErrorCode:SubStatus:There is a temporary failure. Please retry later. (One or more specified cache servers are unavailable, which could be caused by busy network or servers. For on-premises cache clusters, also verify the following conditions. Ensure that security permission has been granted for this client account, and check that the AppFabric Caching Service is allowed through the firewall on all cache hosts. Also the MaxBufferSize on the server must be greater than or equal to the serialized object size sent from the client.). Additional Information : The client was trying to communicate with the server: net.tcp://ekckodev.cache.windows.net:22238."}
I then set the maxBufferSize in my config as follows:
<configSections>
<section name="dataCacheClients" type="Microsoft.ApplicationServer.Caching.DataCacheClientsSection, Microsoft.ApplicationServer.Caching.Core" allowLocation="true" allowDefinition="Everywhere" />
<section name="cacheDiagnostics" type="Microsoft.ApplicationServer.Caching.AzureCommon.DiagnosticsConfigurationSection, Microsoft.ApplicationServer.Caching.AzureCommon" allowLocation="true" allowDefinition="Everywhere" />
</configSections>
...
...
<system.web>
...
...
<caching>
<outputCache defaultProvider="AFCacheOutputCacheProvider">
<providers>
<add name="AFCacheOutputCacheProvider" type="Microsoft.Web.DistributedCache.DistributedCacheOutputCacheProvider, Microsoft.Web.DistributedCache" cacheName="default" dataCacheClientName="default" applicationName="AFCacheOutputCache" />
</providers>
</outputCache>
</caching>
</system.web>
....
....
...
<dataCacheClients>
<dataCacheClient name="default">
<autoDiscover isEnabled="true" identifier="ekckodev.cache.windows.net" />
<localCache isEnabled="true" sync="TimeoutBased" objectCount="100000" ttlValue="300" />
<securityProperties mode="Message" sslEnabled="false">
<messageSecurity authorizationInfo="xxxxxxxxxxxxxxxxxxxxxxx" />
</securityProperties>
<transportProperties connectionBufferSize="131072" maxBufferPoolSize="268435456"
maxBufferSize="8388608" maxOutputDelay="2" channelInitializationTimeout="60000"
receiveTimeout="600000"/>
</dataCacheClient>
</dataCacheClients>
But I still get such erratic response times - particularly when hitting the same service call repeatedly.
After adding the maxbuffersize config, the cache calls are still hit-and-miss. some fetch the object; other times I get the same exception, however the port is different
"... The client was trying to communicate with the server: net.tcp://ekckodev.cache.windows.net:22233."}"
Could this be a firewall issue? If so, how do I open the appropriate ports?
I also just got the following exception when instantiating the DataCache object:
_cache = cacheFactory.GetDefaultCache();
ErrorCode:SubStatus:There is a temporary failure. Please retry later. (One or more specified cache servers are unavailable, which could be caused by busy network or servers. For on-premises cache clusters, also verify the following conditions. Ensure that security permission has been granted for this client account, and check that the AppFabric Caching Service is allowed through the firewall on all cache hosts. Also the MaxBufferSize on the server must be greater than or equal to the serialized object size sent from the client.)
Any thoughts on why I'm getting such results? it's certainly no quicker WITH the cache than WIHTOUT it, so it appears there is some sort of latency in the cache which doesn't seem right...
Thanks in advance for any help!
UPDATE: After doing some more searching, it seems I'm not the only one with this issue: poor performance with azure cache
I find it hard to believe that this is the performance I should expect
UPDATE 2 I have commented out all cache-related code from my service and ran the same tests again. The response times are appreciably lower WITHOUT the cache! the "getFriends" callaverages about 250ms wihtout the cache, but peaks at over 5sec WITH the cache. My other method that fetches about 4kb of data, was peaking at 20+ seconds with cache and now averages about 2sec WITHOUT the cache.
Again: I find it hard to believe that this is the performance I should expect
UPDATE 3 I have now scrapped Azure Cache in favour of MemoryCache. Nice example here My service calls are now consistently taking approx 300ms in the browser.
I've opened a ticket with Microsoft Azure support regarding Azure Cache, so I'll update this post when they get in touch and I've asked them why their cache is so rubbish. Just when my faith in Microsoft was climbing :/