locked
Plugins Caching Strategy RRS feed

  • Question

  • I've developed a few plugins in Dyanmics CRM running in both synchronous and asynchronous modes. I need to cache some frequently accessed information such as configuration information etc. This solution will be deployed in a Load Balanced environment.

    I've tried caching in-memory, where it invalidates the cache based on various triggers on an entity, but that works for only for the node that picks up the job and leaves the rest of the nodes out-of-sync.

    What kind of caching strategy would you recommend for keeping the data consistent between the various nodes/processes?
    Wednesday, May 26, 2010 2:26 PM

Answers

  • Hi Shane,

     

    Create a new enity in your MS CRM organisation called say "xRMCacheEntity" which has 2 attributes key & value. This keeps the cache in one place i.e. the database that all nodes can access. Then create a class xRMCache which has methods for Add, Remove, Exists, etc which accesses the underlying entity. You can now call these methods from any node and get back consistent results.

    If you need very fast read perf. on this I'd recommend adding a dictionary object on the xRMCache class so the first time a value is read or written you update the dictionary & database record & all subsequent reads are from the local dictionary object. For this you also need a pre-create  \ pre-update  plug-in on xRMCacheEntity to send a message to all the nodes to invalidate the cache for updates , inserts, deletes on xRMCacheEntity.

     

    Two other options I'd look at are below.

     

    (a) Use a distribute caching solution, the main ones here for are NCache & AppFabric Cache.

     

    (b) Use a single external source to cache the data that all nodes can reach. This would see you developing say a windows service that had an in-memory dictionary object to cache the items with a WCF interface for communications. So just have Add, Remove, Exists methods exposed. This is one of the options that Microsoft provide out of the box for load balanced ASP.NET servers which you might actually be able to leverage.

    Its the StateServer option in this article, http://msdn.microsoft.com/en-us/library/aa479041.aspx

     

    John

     

     

     

    Wednesday, May 26, 2010 6:18 PM

All replies

  • Hi Shane,

     

    Create a new enity in your MS CRM organisation called say "xRMCacheEntity" which has 2 attributes key & value. This keeps the cache in one place i.e. the database that all nodes can access. Then create a class xRMCache which has methods for Add, Remove, Exists, etc which accesses the underlying entity. You can now call these methods from any node and get back consistent results.

    If you need very fast read perf. on this I'd recommend adding a dictionary object on the xRMCache class so the first time a value is read or written you update the dictionary & database record & all subsequent reads are from the local dictionary object. For this you also need a pre-create  \ pre-update  plug-in on xRMCacheEntity to send a message to all the nodes to invalidate the cache for updates , inserts, deletes on xRMCacheEntity.

     

    Two other options I'd look at are below.

     

    (a) Use a distribute caching solution, the main ones here for are NCache & AppFabric Cache.

     

    (b) Use a single external source to cache the data that all nodes can reach. This would see you developing say a windows service that had an in-memory dictionary object to cache the items with a WCF interface for communications. So just have Add, Remove, Exists methods exposed. This is one of the options that Microsoft provide out of the box for load balanced ASP.NET servers which you might actually be able to leverage.

    Its the StateServer option in this article, http://msdn.microsoft.com/en-us/library/aa479041.aspx

     

    John

     

     

     

    Wednesday, May 26, 2010 6:18 PM
  • If you need very fast read perf. on this I'd recommend adding a dictionary object on the xRMCache class so the first time a value is read or written you update the dictionary & database record & all subsequent reads are from the local dictionary object. For this you also need a pre-create  \ pre-update  plug-in on xRMCacheEntity to send a message to all the nodes to invalidate the cache for updates , inserts, deletes on xRMCacheEntity.

    This was actually my intial implementation of the cache, but unfortunately the process (async service) that actually handles the trigger is the only one that gets its cache invalidated. I have no way of communicating the cache invalidation to the other nodes.

    I'm liking the single external cache service approach, I guess that's the best solution for me.

    Thank you for your suggestions.

    Thanks
    Shane

    Wednesday, May 26, 2010 8:35 PM