2

I'm looking for a simple way to implement a local memory store which can be used on an Azure .NET instance

I've been looking at Azure Co-located Caching and it seems to support all of my requirements:

  1. Work on both web roles and worker roles

  2. Implement a simple LRU

  3. Keep cached objects in memory (RAM)

  4. Allow me to define the cache size as a percentage of the machine's total RAM

  5. Keep the cache on the same machine of the web/worker role (co-located mode)

  6. Allow me to access the same cache from multiple AppDomains running on the same machine (Web Roles may split my handlers into different AppDomains)

The only problem I have with Azure Co-located caching is that different instances communicate and try to share their caches - and I don't really need all that.

I want every machine to have its own separate in-memory cache. When I query this cache, I don't want to waste any time on making a network request to other instances' caches.

Local Cache config?

I've seen a configuration setting in Azure Caching to enable a Local Cache - but it still seems like machines may communicate with each other (ie. during cache miss). This config also requires a ttlValue and objectCount and I want TTL to be "forever" and the object count to be "until you fill the entire cache". It feels like specifying maxInt in both cases seems wrong.

What about a simple static variable?

When I really think about it, all this Azure caching seems like a bit of an overkill for what I need. I basically just need a static variable in the application/role level.. except that doesn't work for requirement #6 (different AppDomains). Requirement #4 is also a bit harder to implement in this case.

Memcached

I think good old memcached seems to do exactly what I want. Problem is I'm using Azure as a PaaS and I don't really want to administer my own VM's. I don't think I can install memcached on my roles.. [UPDATE] It seems it is possible to run memcached locally on my roles. Is there a more elegant "native" solution without using memcached itself?

talkol
  • 12,564
  • 11
  • 54
  • 64
  • What kind of things are you caching? Keep in mind that only strings and a few special objects (threads, appdomains) are really shared across appdomains, all other stuff is serialized and deserialized when crossing appdomain boundaries. Then there is MarshalByRefObject — which is not exactly shared, but calls from different appdomains are marshaled to its native appdomain. You can create a MarshalByRef dictionary, put it in a static and use it across appdomains. – Anton Tykhyy Aug 19 '13 at 08:29
  • @AntonTykhyy I want to cache simple JSON objects (a flat dictionary of about 8 strings, each one being about 100-200 bytes). Can you point me somewhere with an example implementation of your idea, it sounds perfect – talkol Aug 19 '13 at 08:57
  • I couldn't find any. However do you really need this? The role entry point runs in a different process than the web role [(1)](http://blogs.msdn.com/b/windowsazure/archive/2010/12/02/new-full-iis-capabilities-differences-from-hosted-web-core.aspx), but if your web role has just one site it runs in one appdomain. Just put your static cache in Global.asax and you should be all set. – Anton Tykhyy Aug 19 '13 at 11:33
  • @AntonTykhyy My web role has several handlers (ashx files) and I'm not sure whether they run on different AppDomains or not. I prefer not to risk it and make assumptions – talkol Aug 19 '13 at 12:04

2 Answers2

1

You can certainly install memcached on Web and Worker roles. Steve Marx blogged getting memcached running on Azure Cloud Service several years ago before the Virtual Machine features were present. This is an older post, so you may run into other ways of dealing with this, such as using start up tasks instead of the OnStart method in RoleEntryPoint, etc.

MikeWo
  • 10,887
  • 1
  • 38
  • 44
  • Thanks, I wasn't aware memcached was possible. Are you aware of a more "native" solution besides memcached for this purpose? – talkol Aug 18 '13 at 16:38
  • Nothing out of the box. The co-located Windows Azure Caching feature you mentioned already is the closest. You could write your own service that starts up locally and is a memory cache using the .NET Framework caching namespace that could be accessed cross app domain, but that seems overkill if you could use a cache framework that was already created. I didn't ask why you didn't really want a distributed cache because I assume you have your reasons. I'd at least test the latency if that is what you are concerned about. – MikeWo Aug 18 '13 at 16:54
0

I have used the "free" versions of SQL Server for local caching and they have worked great. It depends on what you are doing, but I have ran both SQL Server Express/Compact for storing entire small static data sets for a fantasy football site I wrote that included 5 years of statistics. They worked really well even on a small/medium Azure instances, because of the small footprint.

http://blogs.msdn.com/b/jerrynixon/archive/2012/02/26/sql-express-v-localdb-v-sql-compact-edition.aspx

Best part is you can use t-sql. Your cache requirements might be more complex or not scale to this.

Bart Czernicki
  • 3,663
  • 1
  • 21
  • 19