6

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 :/

Community
  • 1
  • 1
Adam Hey
  • 1,512
  • 1
  • 20
  • 24
  • Are you totally sure that the cache is the slow component? Dow did you determine that? – usr Jun 05 '14 at 12:50
  • Yeah - I ran speed tests before, during and after implementing the Azure Cache. And then again after implementing MemCache. As stated, I also remote debugged to be sure it was getting data from cache and not the DB. The only variable that changed was the cache. It's possible the problem is down to a configuration error, but I double checked my config against MS's examples – Adam Hey Jun 06 '14 at 06:27
  • I'd profile the site to find out where the time is spent in the internals of the cache. The stack often gives important clues to what is going on just by the function names. Just pause the debugger 10 times while there is load on the site. It will very likely stop in the slow component most of the time. Look at the stack (including external code). – usr Jun 06 '14 at 11:05
  • Your right, that this isnt the performance you should expect. Can you confirm that your cache/sqldb/website are all in the exact same region. – Isuru Fonseka Jul 17 '14 at 00:39
  • Yeah, they're all in the same region (West Europe). I haven't had any similar issues since switching to MemCache. Microsoft have since advised that I try RedisCache, but I haven't yet had the time (or the inclination!). Thanks again for everyone's input – Adam Hey Jul 23 '14 at 14:33

1 Answers1

0

Looks like you've arrived at the correct conclusion, which is don't use Azure Managed Cache. About 6 months ago, Microsoft started recommending all new development be done against their Redis-based cache offering in Azure.

We recommend all new developments use Azure Redis Cache.

Strangely, they don't show the option to create a Redis cache in the 'old' Azure management site (manage.windowsazure.com), but they do have it in the "preview" Azure management portal.

Dusty
  • 3,946
  • 2
  • 27
  • 41