Memcached Clients – Which ones best

Firstly, what is Memcached and why would it be better than say using the inbuilt .net cache

If you are running a your .NET website from a single server there is very little point in even considering Memcached. Memcached is “Free & open source, high-performance, distributed memory object caching system” (http://memcached.org/). So if you are running your site from many web servers it may be preferable to have a shared cache. If you have performance draining database calls originating from your web servers you may want the first web server to make the database call to cache the result in the shared cache, so the other web servers don’t need to make the same database call.

How does it work

Memcached is a distributed memory object cache, so how does it actually distribute?
Effectively the Memcached server is simply a key value store so it is up to the client to pick the correct server to put the object on. The way it picks is to hash the key for the item you want to store and compute from that which server that item should be placed on. If you had two servers the split of items between the two should be approximately 50-50.

Choosing a client

There are two popular free clients to choose from BeIT and Enyim. I have quickly evaluated both and here are my findings:

BeIT

Setting up the client

Setting up the client in my app could not be easier. Firstly use that static Setup method on the MemcachedClient to set up the configuration for your Memcached client.

MemcachedClient.Setup("MyCache", new string[] { "127.0.0.1:11211" });

The first parameter is the Identifier for your Memcache client configuration and the string array is the the addresses of the memcached servers. In this example I am using the loopback address because I am running the server on my local box.

Once you have created this you can use the static GetInstance method on the MemcachedClient to retrive an MemcachedClient instance for this configuration.

MemcachedClient cache = MemcachedClient.GetInstance("MyCache");

Alternatively, and probably more useful, you can put the Client settings in a configuration section in the your application configuration file, you can then use then use the MemcachedClient.GetInstance() method to get an MemcachedClient instance for the configuration specified.

Using the client

Once you have set up the client you are free to change the settings and use the methods to interact with you Memcached server.

cache.Set("mystring", "helloMemcached", 4711);
            cache.SetCounter("users", 0);
            cache.Increment("users", 1);

Supported methods

  • Set – store this data
  • Add – store this data, but only if the server doesn’t already
    hold data for this key
  • Cas – Check And Store, store this data but
    only if no one else has updated since I last fetched it.
  • replace – store this data, but only if the server does
    already hold data for this key
  • append – add this data to an existing key after existing data
  • prepend – add this data to an existing key before existing data
  • Get(s) – The the value associated with a particular key. Gets will retrieve many
  • SetCounter – Set a counter that can then be incremented with Increment and Decrement methods
  • Increment – Will increment the value by the specified amount
  • Decrement – Will decrement the the value by the specified amount
  • Delete – Deletes an item
  • FlushAll – Deletes all items on all servers
  • Exists – Check to see if an item exists
  • Stats – Get key/value stats for each server
  • StatsByHost – Get key/value stats for each server

Enyim

Setting up the client

Setting up the client is pretty easy in Enyim also. You can put the settings in the application configuration file saving you having to set up the configuration in code.

Enyim.Caching.Configuration.MemcachedClientConfiguration config = new Enyim.Caching.Configuration.MemcachedClientConfiguration();
config.Servers.Add(new System.Net.IPEndPoint(IPAddress.Loopback,11211));
config.Protocol = Enyim.Caching.Memcached.MemcachedProtocol.Text; //you must set a protocol
Enyim.Caching.MemcachedClient client = new Enyim.Caching.MemcachedClient(config);

Using the client

client.Store(Enyim.Caching.Memcached.StoreMode.Add, "myItem", "myValue"); //The various ways of storing things use a single method and an enum rather than 3 methods
client.Store(Enyim.Caching.Memcached.StoreMode.Replace, "myItem", "myValue");
client.Store(Enyim.Caching.Memcached.StoreMode.Set, "myItem", "myValue");

Supported methods

  • Store – Stores the data specified under the specified key, takes an Enum that dictates if it is an Add/Replace/Set
  • Cas – Check And Store, store this data but
    only if no one else has updated since it was last fetched
  • Append – Add this data to an existing key after existing data
  • Prepend – Add this data to an existing key before existing data
  • Get – Gets the value associated with a particular key.
  • Get<T> – Generic version of Get
  • GetWithCas – Get the value associated with a particular key and will also return check and set value
  • GetWithCas<T> – Get the value associated with a particular key and will also return check and set value
  • TryGet - Tries to get an object from the cache, if it fails the output object is null
  • TryGetWithCas - Tries to get an object from the cache, if it fails the output object is null
  • PerformMultiGet – Gets many thing at once
  • Increment – Will increment the value by the specified amount, you can specify a default if the key doesn’t already exist
  • Decrement- Will decrement the the value by the specified amount, you can specify a default if the key doesn’t already exist
  • Remove- Deletes an item
  • FlushAll- Deletes all items on all servers
  • Exists – Check to see if an item exists
  • Stats – Get key/value stats for each server
  • StatsByHost – Get key/value stats for each server

Feature comparison

Enyim BeIT
Config file configuration yes yes
Persistent connections yes yes
Generic get and set methods yes no
Supports Binary protocol yes no
Supports SASL yes no
Supports all the standard Memcached operations in the protocol yes yes
Uses .NET serialization yes yes
Consistent hashing yes yes
Compression (built-in) no yes
Logging and tracing yes yes

Conclusion

Both work well. Enyim doesn’t have compression, but there is nothing stopping you using the .NET framework compression features. I think overall Enyim does have a richer feature set. Anecdotally I have heard that Enyim is faster, but that is likely to be due in part to it not compressing the objects before it sends them to the server. The support for the Binary protocol doesn’t mean that much to me, yes it will mean that less bytes need to be pushed down the pipe for the commands but I don’t think it will make a significant difference because most of the bytes (to be sent) are likely to be the bytes of the serialized object you wish to store. Both use the standard .NET Binary formatter so you can use the ISerializable interface on your types if you are worried about the shape of the type changing while old objects are still in the cache.

Related Links

About these ads

4 thoughts on “Memcached Clients – Which ones best

  1. Excellent write up, it’s helped me in choosing a client. I think I prefer how the code is more readable when using BeIT, but Enyim has more features.

    What did you choose?

    I think I’ll be going with BeIT for compression – using ElastiCache on AWS makes me think that the compression will be useful there to save on costs.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s