On Tuesday 10th July I did a talk for the UKWAUG on using the new co-located cache. Since we’ve been working caching into our HPC implementation successfully I’ve become a dabhand on the dos and donts which I wanted to publish.

In my previous post I spoke about the problem with AppFabric Server but there are a few more problems which rear their head and rather than let you sit there scratching your heads for days I thought I’d write down the gotchas I presented to help you on your merry way. So if you want to read about the AppFabric server issues go to the earlier post here. One thing that has stupidly caught me out is a manifested issue which I created myself. It took me hours to realise what I was doing wrong and it happened because I am a hack! When the cache starts up it leaves four marker files in the storage account you set up in your configuration at compile time. The files have names like this f83f8073469549e1ba858d719238700f__Elastaweb__ConfigBlob and the four present means that cache configuration is complete and it now has an awareness of where the nodes in the cache cluster are. These blobs are in a well-known storage container called cacheclusterconfig. The cache will reference the latest files in this container which are order dependent by time so if the settings are overwritten by something else then don’t expect the health of your cache to be good! Each node has Base64 config data associated with it in this file so the cluster won’t effectively exist you’re using the same account for multiple cache clusters from different deployments. Be aware, don’t reuse in this way for staging, production and as in my case the devfabric! A small factor you should be aware of is the time it takes to install the cache. I’ve run several hundred tests now and generally it takes an additional 9 minutes to install the cache services when you include the plugin. Be aware of this because if you have time dependent deployments it will impact them. Using diagnostics with the cache is not that clearcut. In the spirit of including some code in this blogpost here is my RoleEntryPoint.OnStart method.

        public override bool OnStart()
        {
            CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>
                {
                    // Provide the configSetter with the initial value
                    configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));

                    RoleEnvironment.Changed += (sender, arg) =>
                        {
                            if (arg.Changes.OfType().Any((change) =>
                                                                                                    (change.ConfigurationSettingName ==
                                                                                                     configName)))
                            {
                                // The corresponding configuration setting has changed, so propagate the value
                                if (!configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)))
                                {
                                    // In this case, the change to the storage account credentials in the
                                    // service configuration is significant enough that the role needs to be
                                    // recycled in order to use the latest settings (for example, the 
                                    // endpoint may have changed)
                                    RoleEnvironment.RequestRecycle();
                                }
                            }
                        };
                });

            // tracing for the caching provider
            DiagnosticMonitorConfiguration diagConfig = DiagnosticMonitor.GetDefaultInitialConfiguration();
            diagConfig = CacheDiagnostics.ConfigureDiagnostics(diagConfig);
            //// tracing for asp.net caching diagnosticssink
            diagConfig.Logs.ScheduledTransferLogLevelFilter = LogLevel.Warning;
            diagConfig.Logs.ScheduledTransferPeriod = TimeSpan.FromMinutes(2);
            // performance counters for caching
            diagConfig.PerformanceCounters.ScheduledTransferPeriod = TimeSpan.FromMinutes(2);
            diagConfig.PerformanceCounters.BufferQuotaInMB = 100;
            TimeSpan perfSampleRate = TimeSpan.FromSeconds(30);
            diagConfig.PerformanceCounters.DataSources.Add(new PerformanceCounterConfiguration()
            {
                CounterSpecifier = @"\AppFabric Caching:Cache(azurecoder)\Total Object Count",
                SampleRate = perfSampleRate
            });
            diagConfig.PerformanceCounters.DataSources.Add(new PerformanceCounterConfiguration()
            {
                CounterSpecifier = @"\AppFabric Caching:Cache(default)\Total Object Count",
                SampleRate = perfSampleRate
            });
            DiagnosticMonitor.Start("Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString", diagConfig);

            return base.OnStart();
        }

The first important line here is this:

CacheDiagnostics.ConfigureDiagnostics(diagConfig);

You'll want to configure diagnostics for the cache to find out what's going on. Unfortunately with the default settings in place this will fail with a quota exception. There is a default size of 4000 MB set on the log limit and this call violates it by 200MB. Unfortunately the quota property cannot be increased, only decreased, so the fix for this is to change the default setting in the ServiceDefinition.csdef from:

<LocalResources>
      <LocalStorage name="Microsoft.WindowsAzure.Plugins.Caching.FileStore" sizeInMB="1000" cleanOnRoleRecycle="false" />
</LocalResources>

to:

<LocalResources>
      <LocalStorage name="Microsoft.WindowsAzure.Plugins.Caching.FileStore" sizeInMB="10000" cleanOnRoleRecycle="false" />
</LocalResources>

Notice also the addition of the performance counters. There are 3 sets but I've illustrated the most basic but also most important metrics for us which show the numbers of cache objects. The counters are well-documented on MSDN. Anyway, hope yo found this helpful. I'll be publishing something else on memcache interop shortly based on testing I've done in Java and .NET.

About these ads