Skip to content
NickLarsen edited this page Nov 17, 2014 · 4 revisions

Dache is distributed wrapper for the .NET framework MemoryCache object (reference source). MemoryCache only works on a single machine and only for the app that initializes it; when the app is closed, the cache is destroyed. Dache addresses these issues with:

  • support for shared caching across your entire application (in particular multiple consuming machines)
  • support for a cache lifetime longer than a single instance of the application
  • support for scaling larger applications with a much larger memory pool by allowing multiple hosts

Caching

Caching is the process of storing data for later retrieval. In order to retrieve specific data later on, a unique key is specified at the time of storing, and that key is later used to retrieve the stored value.

All caching functionality in Dache is accessed through the CacheClient class. As a general abstraction, a Dache cache can be represented by IDictionary<string, object>.

Coming up with hash keys

Dache hash keys are just arbitrary strings. They can be anything you want, but there are things to keep in mind when deciding on your hash key creation algorithm.

  • Make sure you are using unique values for each cached item.

    It might be easy to just serialize the user id of the viewing user, however you can only store a single value for each key. If you store the some widget from the user page in Dache with their user id as the key, and then you also use that same key to store their recent history for another page, you have overwritten the data needed by the user page. These kinds of errors tend to be very difficult to debug and remember with caching enabled, it's solid practice to run all of your tests multiple times to ensure the cache is hot.

  • Keep your cache keys short.

    In many applications you end up storing a ton of small values. It's easy to forget that the cache keys are stored in memory without any kind of compression and those cache keys can end up using the majority of your available cache memory. If you have 1,000,000 users and you store 10 values for each of them with cache keys that are 30-50 characters in length, just your key space will brush up close to a gigabyte. Ideally you want to keep your keys to around 10-15 characters at a maximum but keep in mind that readability might be an issue if your application ever needs to retrieve keys from the cache.

Storing values

Storing values with Dache is done by calling the ICacheClient.AddOrUpdate method using a cache key generated by your application and the value you want to store.

Serialization

The Dache protocol requires that objects be transferred as base 64 encoded bytes. By default Dache uses the BinaryFormatter class to accomplish this, which requires that your cachable objects are marked as serializable. The easiest way to mark a class as serializable is to simply add the [SerializationAttribute] to the class.

Interning values

Interning is the process by which you only store a single value one time and point multiple keys at it. This can be very useful if you have a few values that get generated over and over but need to reference them through different cache keys.

A brief blog post on the benefits and pitfalls of interning values can be found here. In short, interning values can save a lot of time and space if you are sure there are going to be repeated values. If there are not going to be repeated values, it's just a waste of time and space.

In Dache, interning can be turned on for individual keys by specifying the isInterned argument for the ICacheClient.AddOrUpdate functions at storage time.

Retrieving values

throw NotImplementedException();

Removing values

throw NotImplementedException();

Retrieving cache keys

throw NotImplementedException();

Index Management

throw NotImplementedException();

General idea

throw NotImplementedException();

Using multiple hosts

throw NotImplementedException();

Tagging

throw NotImplementedException();

Locking behavior

throw NotImplementedException();

The Dache Protocol

throw NotImplementedException();