Shaun Xu

The Sheep-Pen of the Shaun


News

logo

Shaun, the author of this blog is a semi-geek, clumsy developer, passionate speaker and incapable architect with about 10 years’ experience in .NET and JavaScript. He hopes to prove that software development is art rather than manufacturing. He's into cloud computing platform and technologies (Windows Azure, Amazon and Aliyun) and right now, Shaun is being attracted by JavaScript (Angular.js and Node.js) and he likes it.

Shaun is working at Worktile Inc. as the chief architect for overall design and develop worktile, a web-based collaboration and task management tool, and lesschat, a real-time communication aggregation tool.

MVP

My Stats

  • Posts - 122
  • Comments - 546
  • Trackbacks - 0

Tag Cloud


Recent Comments


Recent Posts


Archives


Post Categories


.NET



To be honest I have not been very interested in the caching before I’m going to a project which would be using the multi-site deployment and high connection and concurrency and very sensitive to the user experience. That means we must cache the output data for better performance.

After looked for the Internet I finally focused on the Memcached. What’s the Memcached? I think the description on its main site gives us a very good and simple explanation.

Free & open source, high-performance, distributed memory object caching system, generic in nature, but intended for use in speeding up dynamic web applications by alleviating database load.

Memcached is an in-memory key-value store for small chunks of arbitrary data (strings, objects) from results of database calls, API calls, or page rendering.

Memcached is simple yet powerful. Its simple design promotes quick deployment, ease of development, and solves many problems facing large data caches. Its API is available for most popular languages.

The original Memcached was built on *nix system are is being widely used in the PHP world. Although it’s not a problem to use the Memcached installed on *nix system there are some windows version available fortunately. Since we are WISC (Windows – IIS – SQL Server – C#, which on the opposite of LAMP) it would be much easier for us to use the Memcached on Windows rather than *nix.

I’m using the Memcached Win X64 version provided by NorthScale. There are also the x86 version and other operation system version.

 

Install Memcached

Unpack the Memcached file to a folder on the machine you want it to be installed, we can see that there are only 3 files and the main file should be the “memcached.exe”. Memcached would be run on the server as a service. To install the service just open a command windows and navigate to the folder which contains the “memcached.exe”, let’s say “C:\Memcached\”, and then type “memcached.exe -d install”.

If you are using Windows Vista and Windows 7 system please be execute the command through the administrator role. Right-click the command item in the start menu and use “Run as Administrator”, otherwise the Memcached would not be able to be installed successfully.

Once installed successful we can type “memcached.exe -d start” to launch the service. Now it’s ready to be used. The default port of Memcached is 11211 but you can change it through the command argument. You can find the help by typing “memcached -h”.

image

 

Using Memcached

Memcahed has many good and ready-to-use providers for vary program language. After compared and reviewed I chose the Memcached Providers. It’s built based on another 3rd party Memcached client named enyim.com Memcached Client. The Memcached Providers is very simple to set/get the cached objects through the Memcached servers and easy to be configured through the application configuration file (aka web.config and app.config).

Let’s create a console application for the demonstration and add the 3 DLL files from the package of the Memcached Providers to the project reference.

image

Then we need to add the configuration for the Memcached server. Create an App.config file and firstly add the section on top of it. Here we need three sections: the section for Memcached Providers, for enyim.com Memcached client and the log4net.

   1: <configSections>
   2:   <section name="cacheProvider" 
   3:            type="MemcachedProviders.Cache.CacheProviderSection,  MemcachedProviders" 
   4:            allowDefinition="MachineToApplication" 
   5:            restartOnExternalChanges="true"/>
   6:   <sectionGroup name="enyim.com">
   7:     <section name="memcached" 
   8:              type="Enyim.Caching.Configuration.MemcachedClientSection, Enyim.Caching"/>
   9:     </sectionGroup>
  10:   <section name="log4net" 
  11:            type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
  12: </configSections>

Then we will add the configuration for 3 of them in the App.config file. The Memcached server information would be defined under the enyim.com section since it will be responsible for connect to the Memcached server. Assuming I installed the Memcached on two servers with the default port, the configuration would be like this.

   1: <enyim.com>
   2:   <memcached>
   3:     <servers>
   4:       <!-- put your own server(s) here-->
   5:       <add address="192.168.0.149" port="11211"/>
   6:       <add address="10.10.20.67" port="11211"/>
   7:     </servers>
   8:     <socketPool minPoolSize="10" maxPoolSize="100" connectionTimeout="00:00:10" deadTimeout="00:02:00"/>
   9:   </memcached>
  10: </enyim.com>

Memcached supports the multi-deployment which means you can install the Memcached on the servers as many as you need. The protocol of the Memcached responsible for routing the cached objects into the proper server. So it’s very easy to scale-out your system by Memcached.

And then define the Memcached Providers configuration. The defaultExpireTime indicates how long the objected cached in the Memcached would be expired, the default value is 2000 ms.

   1: <cacheProvider defaultProvider="MemcachedCacheProvider">
   2:   <providers>
   3:     <add name="MemcachedCacheProvider" 
   4:          type="MemcachedProviders.Cache.MemcachedCacheProvider, MemcachedProviders" 
   5:          keySuffix="_MySuffix_" 
   6:          defaultExpireTime="2000"/>
   7:   </providers>
   8: </cacheProvider>

The last configuration would be the log4net.

   1: <log4net>
   2:   <!-- Define some output appenders -->
   3:   <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
   4:     <layout type="log4net.Layout.PatternLayout">
   5:       <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline"/>
   6:     </layout>
   7:   </appender>
   8:   <!--<threshold value="OFF" />-->
   9:   <!-- Setup the root category, add the appenders and set the default priority -->
  10:   <root>
  11:     <priority value="WARN"/>
  12:     <appender-ref ref="ConsoleAppender">
  13:       <filter type="log4net.Filter.LevelRangeFilter">
  14:         <levelMin value="WARN"/>
  15:         <levelMax value="FATAL"/>
  16:       </filter>
  17:     </appender-ref>
  18:   </root>
  19: </log4net>

 

Get, Set and Remove the Cached Objects

Once we finished the configuration it would be very simple to consume the Memcached servers. The Memcached Providers gives us a static class named DistCache that can be used to operate the Memcached servers.

  • Get<T>: Retrieve the cached object from the Memcached servers. If failed it will return null or the default value.
  • Add: Add an object with a unique key into the Memcached servers.

Assuming that we have an operation that retrieve the email from the name which is time consuming. This is the operation that should be cached. The method would be like this. I utilized Thread.Sleep to simulate the long-time operation.

   1: static string GetEmailByNameSlowly(string name)
   2: {
   3:     Thread.Sleep(2000);
   4:     return name + "@ethos.com.cn";
   5: }

Then in the real retrieving method we will firstly check whether the name, email information had been searched previously and cached. If yes we will just return them from the Memcached, otherwise we will invoke the slowly method to retrieve it and then cached.

   1: static string GetEmailByName(string name)
   2: {
   3:     var email = DistCache.Get<string>(name);
   4:     if (string.IsNullOrEmpty(email))
   5:     {
   6:         Console.WriteLine("==> The name/email not be in memcached so need slow loading. (name = {0})==>", name);
   7:         email = GetEmailByNameSlowly(name);
   8:         DistCache.Add(name, email);
   9:     }
  10:     else
  11:     {
  12:         Console.WriteLine("==> The name/email had been in memcached. (name = {0})==>", name);
  13:     }
  14:     return email;
  15: }

Finally let’s finished the calling method and execute.

   1: static void Main(string[] args)
   2: {
   3:     var name = string.Empty;
   4:     while (name != "q")
   5:     {
   6:         Console.Write("==> Please enter the name to find the email: ");
   7:         name = Console.ReadLine();
   8:  
   9:         var email = GetEmailByName(name);
  10:         Console.WriteLine("==> The email of {0} is {1}.", name, email);
  11:     }
  12: }

The first time I entered “ziyanxu” it takes about 2 seconds to get the email since there’s nothing cached. But the next time I entered “ziyanxu” it returned very quickly from the Memcached.

image

 

Summary

In this post I explained a bit on why we need cache, what’s Memcached and how to use it through the C# application. The example is fairly simple but hopefully demonstrated on how to use it. Memcached is very easy and simple to be used since it gives you the full opportunity to consider what, when and how to cache the objects. And when using Memcached you don’t need to consider the cache servers. The Memcached would be like a huge object pool in front of you.

The next step I’m thinking now are:

  • What kind of data should be cached? And how to determined the key?
  • How to implement the cache as a layer on top of the business layer so that the application will not notice that the cache is there.
  • How to implement the cache by AOP so that the business logic no need to consider the cache.

I will investigate on them in the future and will share my thoughts and results.

 

Hope this helps,

Shaun

All documents and related graphics, codes are provided "AS IS" without warranty of any kind.
Copyright © Shaun Ziyan Xu. This work is licensed under the Creative Commons License.


Comments

Gravatar # re: First round playing with Memcached
Posted by robin on 4/7/2010 11:59 AM
怒顶from China
Gravatar # re: First round playing with Memcached
Posted by anytao on 4/7/2010 12:01 PM
Great. That's what I need.
Gravatar # re: First round playing with Memcached
Posted by dmitry on 5/6/2010 2:54 AM
The great story. Our QA has found a "strange" bug in the same implementation. 1.5 min application works extremely fast but after that time performance fails in 10x times vs version without memcached.
The Front-End CPU is near to 100% utilization with memcached (and 20% without).
I think the cause could be in serilization implementation in .NET Memcached provider.

Gravatar # re: First round playing with Memcached
Posted by Shaun on 5/6/2010 12:27 PM
@dmity
I have not met with your problem. One of my project had being using Memcached with the .NET Memcached provider and it works well. Since I'm not very familiar with Memcached I suggest you to post your problem to the Memcached Provider website and see who can help you.
Gravatar # re: First round playing with Memcached
Posted by Kukuwka on 8/1/2010 7:52 PM
I would like to know what kind of data should be cached.
Gravatar # re: First round playing with Memcached
Posted by Shaun on 8/2/2010 4:44 PM
@Kukuwka
Well this question is out of the content of this blog post a bit. There are many articles you can find on the Internet but basically it's up to you to decide what kind of data should be cached. In theory the data should be cached in the follow 3 scenarios:
1, The data will never be changed after created.
2, The data will be retrieved very frequently and the loading effort is very high (need a long period to load)
3, Need the asynchronous data operations (the data will be updated in cache immediately and then update to the data source asynchronously)
Gravatar # re: First round playing with Memcached
Posted by Suri on 12/30/2010 1:16 PM
Hi,
Thanks for this article.it's very good.
Can you provide me the information regarding Memcached Providers,enyim.I mean how these provider communicates with eynim and cache server.
Is there any tool to see my cahced on server.I mean to start and stop the cache server.


Thanks in advance.

Regards,
Suri
Gravatar # re: First round playing with Memcached
Posted by Shaun on 12/30/2010 5:58 PM

@Suri
The Memcached Provider and Enyim take the responsible for communication with the cache servers. I don't think it's necessary to know to underlying technologies if we just wanted to use them. And unfortunately I'm not pretty familiar with them. But you can read the source code from searching the codeplex.com.

If you just want to start/stop the cache you can simply go to Events and there's Memcached services you can start/stop. But there's no tools available to view the key/value pairs of your cache servers.
Gravatar # re: First round playing with Memcached
Posted by Suri on 12/31/2010 2:53 PM
Here I find the tool to see our memcahed items in sever and also we can configure more than one server to cache.

http://allegiance.chi-town.com/MemCacheDManager.aspx

Gravatar # re: First round playing with Memcached
Posted by Shaun on 1/4/2011 6:04 PM

@Suri
Thanks Suri that should be a good tool for us. But I don't think the Memcached is the best choice for windows platform. The AppFabric should be better than Memcached.
Gravatar # re: First round playing with Memcached
Posted by Suri on 1/19/2011 11:09 PM
if you do not mind,Can you diffrenciate ASP.NET catching Vs Memcache Vs Enterprise library catching also.
Gravatar # re: First round playing with Memcached
Posted by Shaun on 1/20/2011 11:07 AM

@Suri
Well I'm not familiar with EntLib Caching. The ASP.NET Caching is running under the IIS process while the Memcached is a distributed caching. If you are application runs in a web farm ASP.NET Caching may not be suit for you as in different web server the cache are totally separated. In this case you have to use a centralized caching and Memcached is one of them.
Gravatar # re: First round playing with Memcached
Posted by Suri on 1/20/2011 1:23 PM
Good information .Thanks alot.
Gravatar # re: First round playing with Memcached
Posted by Chaitanya on 10/4/2011 2:26 PM
I am new to memcached and found this article very helpful... Now I can start digging more about it.... Thanks Shaun!
Gravatar # re: First round playing with Memcached
Posted by Jose on 12/6/2011 5:13 AM
I'm following your steps but Im developing a Web application. So, the app.config that you are talking is similar to the web.config?
What using that I have to use to access the "DistCache.Add(name, email)"

regards,
Jose
Gravatar # re: First round playing with Memcached
Posted by Justin Durham on 2/10/2012 8:09 AM
For what it is worth, I just replaced AppFabric with a Linux memcache server due to AppFabric failing under heavy loads every couple days. I was running 4 cache servers under AppFabric. I am running 1 linux server and the site is at least twice as fast and is not failing every 2 days. We played with many different configurations with AppFabric over the last year, but we finally gave up since it became easily corrupted.
Gravatar # re: First round playing with Memcached
Posted by Shaun on 2/10/2012 10:45 AM
@Justin

Yes it's known that the performance of AppFabric Cache is lower than memcached. One of the reason is that, AppFabric needs request routing when you consume the service but no need on memcached. But using memcached on the roles you need to configure the cache clusters by yourself.

MS said the performance of AppFabric Cache should be increased a lot in the future.
Gravatar # re: First round playing with Memcached
Posted by James Clarke on 3/27/2012 8:54 PM
Thanks for the tutorial! I've got a problem, I wonder if you could help.

I can't seem to cache any objects apart from instances of system types, any instances of classes as basic as an inheritance of Object with no properties will not be accepted via DistCache.Add("key_1", new MyClass())
This always returns false? Do I need to decorate my class somehow?

Thanks,
James
Gravatar # re: First round playing with Memcached
Posted by Shaun on 3/28/2012 9:24 AM

@James

I suspected that you need to mark those objects as serializable, so that it can be passed over the network.
Gravatar # re: First round playing with Memcached
Posted by Jonny Nilsen on 5/10/2012 2:04 AM
Great article,
but i have a problem, memcached is being flashed all the time, my swap is disabled and i have set memcached to use 6gb of my ram, but it only cache 20mb before it is being flash again :/ whay dos memcached beehive this way? the cache is set to lifetime but it still flushing the cache, i am using ubuntu 10.04 as the server


Gravatar # re: First round playing with Memcached
Posted by Kumar on 6/18/2012 7:50 PM
what changes do i need to make if i use memcached with java on windows xp??
Gravatar # re: First round playing with Memcached
Posted by Shaun Xu on 6/19/2012 9:16 AM
@Kumar I don't know about java but since there's java client for memcached, I think you can use it very easily. Check this http://code.google.com/p/memcached/wiki/Clients
Gravatar # re: First round playing with Memcached
Posted by Shailesh Sahu on 7/7/2012 7:05 PM
I have 32bit Machine .Will It run on it.
Gravatar # re: First round playing with Memcached
Posted by Ziaul on 10/11/2012 7:53 PM
Ver well written and nice information.
Gravatar # Return Null Values
Posted by Shailesh Sahu on 4/18/2013 2:45 PM
Hi ,

I am not able yo get the value of data table using Memcache also i am not getting any run time error

DataTable table = new DataTable();
table.Columns.Add("Dosage", typeof(int));
table.Rows.Add(25);

MemcachedProviders.Cache.DistCache.Add("_123_", table);
DataTable ad = MemcachedProviders.Cache.DistCache.Get<DataTable>("_123_");


Gravatar # Cache and bussines logic
Posted by Greg on 1/30/2014 5:23 PM
So have you found any answer on your question:

How to implement the cache as a layer on top of the business layer so that the application will not notice that the cache is there.

Is there any framework/pattern for asp.net mvc ?
Thanks
Gravatar # How to Implement Memcached Amazon EC2 or Elastic cache
Posted by Shaik Layakuddin on 3/29/2014 8:59 PM
Hello can you help me how to implement my demo using Amazon EC2 server using elastic memcached
Gravatar # re: First round playing with Memcached
Posted by anil on 2/25/2015 8:28 PM
Hi,
I have replicate the same example given here on my windows machine and when i am running my console app, the result is not coming as expected.
I install memcached on my machine and its running in services.
Below is my result
==> Please enter the name to find the email: anil
==> The name/email not be in memcached so need slow loading. (name = anil)==>
==> The email of anil is anil@ethos.com.cn.
==> Please enter the name to find the email: anil
==> The name/email not be in memcached so need slow loading. (name = anil)==>
==> The email of anil is anil@ethos.com.cn.
==> Please enter the name to find the email: anil
==> The name/email not be in memcached so need slow loading. (name = anil)==>
==> The email of anil is anil@ethos.com.cn.
==> Please enter the name to find the email: anu
==> The name/email not be in memcached so need slow loading. (name = anu)==>
==> The email of anu is anu@ethos.com.cn.
==> Please enter the name to find the email: anu
==> The name/email not be in memcached so need slow loading. (name = anu)==>
==> The email of anu is anu@ethos.com.cn.
==> Please enter the name to find the email:

can anyone help me out?

Thanks
Anil
Gravatar # re: First round playing with Memcached
Posted by Milton Macancela on 4/16/2015 11:33 PM
Hi, friend.
I have a issue, when I running the project show a message about "System.NullReferenceException".
I don't know that be.
thanks for your answer.
Post A Comment
Title:
Name:
Email:
Comment:
Verification: