DucDigital for ( $girl = 1; $girl < $required; $girl++ ) { echo “I love DucDigital”; }

23Jan/101

Memcached and Asp.net mvc

Today I was hanging around on Google and found a lot of useful stuff about Memcached and .net. Currently, I am using System.Web.Cache to cache objects for my webpage stuff. It's good, but not enough for scalable since it's often remove my object when run on low memory. So I go on with Memcached instead. I found a lot of library which could help us develop faster. Here are some library/solution that I found:

http://ayende.com/Blog/archive/2008/06/06/Scratching-an-itch-NMemcached.aspx
http://www.codeproject.com/KB/aspnet/memcached_aspnet.aspx
http://maxi326.wordpress.com/2009/11/02/use-memcached-in-net-application-with-linq/
http://zvolkov.com/blog/post/2009/06/18/Using-MemCached-with-NHibernate.aspx
http://latebound.blogspot.com/2008/10/using-memcached-from-c.html
http://www.codeplex.com/memcachedproviders
http://code.google.com/p/beitmemcached/
http://sourceforge.net/projects/memcacheddotnet/
http://www.codeplex.com/EnyimMemcached/
and the list go on...

What is MemCached? To put this in simple term, it's a cache store / hash table, where you can store almost everything, like objects, on it. Basically, it's very useful since there are parts where you don't want to cache your whole webpage but you just want to cache your object which you finished process or pulled out from database. It can save you hundreds of ms query time, server loads, and process time, which is very very very useful.

There are some downside if you run Memcached on Windows, the latest update for Memcached for windows that i can found is 1.2.5 I found a latest version here: 1.4.4, and the lates for linux is 1.4.4 (at the time I write this post). There are some solution for this problem. By using another computer/server installed as linux, you can solely run Memcached for cache purpose on multiple server. If you are not having more than 1 server, then just fall back to use System.Web.Cache since it's quite good for production already. You can also try out Velocity, which currently on it's CTP and I am not sure about whether Microsoft going to charge users for this.

I suggest you use MemCached Provider, it's the simplest to implement memcached in asp.net mvc, the following web.config instruction provided by MemCached Provider

Open Web.config file and add the following section to configSections tag

<section name="cacheProvider"
type="MemcachedProviders.Cache.CacheProviderSection, MemcachedProviders"
allowDefinition="MachineToApplication" restartOnExternalChanges="true"/>
<sectiongroup name="enyim.com">
<section name="memcached"
type="Enyim.Caching.Configuration.MemcachedClientSection, Enyim.Caching" />
</sectiongroup>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>

Add the following section to configure Enyim’s client to point to Memcached servers

<enyim .com>
<memcached>
<servers>
<!-- put your own server(s) here-->
<add address="127.0.0.1" port="11211" />
</servers>
<socketpool minPoolSize="10" maxPoolSize="100"
connectionTimeout="00:00:10" deadTimeout="00:02:00" />
</memcached>
</enyim>

Add the following section to configure Memcached Cache Provider. keySuffix attribute allows for adding suffix to cache provider keys in order to simulate namespaces.

<cacheprovider defaultProvider="MemcachedCacheProvider">
<providers>
<add name="MemcachedCacheProvider"
type="MemcachedProviders.Cache.MemcachedCacheProvider, MemcachedProviders"
keySuffix="_MySuffix_" defaultExpireTime="2000"/>
</providers>
</cacheprovider>

Add following section to configure log4net

<log4net>
<!-- Define some output appenders -->
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionpattern value="%date [%thread] %-5level %logger [%property{NDC}]
- %message%newline" />
</layout>
</appender>
<!--<threshold value="OFF" />-->
<!-- Setup the root category, add the appenders and set the default priority -->
<root>
<priority value="WARN"/>
<appender -ref ref="ConsoleAppender">
<filter type="log4net.Filter.LevelRangeFilter">
<levelmin value="WARN"/>
<levelmax value="FATAL"/>
</filter>
</appender>
</root>
</log4net>

Provided you include all the reference libraries, for example, this is my category controller, which will cache the object if it's not existed in the MemCached's memory.

1
2
3
4
5
6
7
8
9
10
11
12
        public ActionResult Category()
        {
            var returnObj = DistCache.Get<list <CategoryObject>>("fullCatListObject");
            if (returnObj == null)
            {
                P015.Modules.Categories.Categories _cat = new P015.Modules.Categories.Categories();
                returnObj = _cat.getCatObject();
                DistCache.Add("fullCatListObject", returnObj, new TimeSpan(29, 0, 0, 0));
            }
            return View(returnObj);
        }
</list>

One thing you need to remember when using this library is to have all your objects that you want to save in memcached serialized. For example, this is my CategoryObject class use for the above example:

CategoryObject.cs

    [Serializable]
    public class CategoryObject
    {
        public string CAT_NAME { get; set; }
        public int CAT_ID { get; set; }
        public int LEVEL { get; set; }
    }

In case you are using Linq, or more specific, linq to sql, you can open your DBML file in design mode, change the Serialize Mode option to Unidirectional.

This works for me, so it should works for you too. Enjoy :)

  • Share/Bookmark
22Dec/090

NVARCHAR(MAX) now…

Recently, I need to write a Trigger to duplicate and save a copy of revision automatically into the database, and at that time, i encoutered an error:

Cannot use text, ntext, or image columns in the ‘inserted’ and ‘deleted’ tables.

This cause me so much trouble since what else should i use if I am not allowed to use text/ntext? This make me wandering around google for a while, and finally there is a solution...

The NTEXT, TEXT, IMAGE is deprecated since 2005 and will be remove in the future release, maybe 2008R2 since MSSQL2008 still work fine with NTEXT, TEXT

  • NTEXT -> replaced by NVARCHAR(MAX)
  • TEXT -> replaced by VARCHAR(MAX)
  • IMAGE -> replaced by VARBINARY(MAX)

And of course, for those who wondering, the maximum limit of VARCHAR is 8000 and NVARCHAR is 4000 (2 bytes for each unicode character) due to SQL Server uses 8KB page to store data to disk. But of course, Varchar(MAX), NVarchar(MAX) and VarBinary(MAX) data types in SQL Server 2005 which allows you to save upto 2GB in a single variable. The best part is that It allows you to use these data types as stored procedure parameters, internal variables etc.

So I suggest you should stop using NTEXT and TEXT and switch to NVARCHAR/VARCHAR soon!

  • Share/Bookmark
20Dec/090

Convert INT to VARCHAR in SQL (MSSQL)

At some point you will need to change INT to VARCHAR for the purpose of manipulation like substring or to display it in the status windows when execute of stored procedure or trigger...

here is the code which you can use to convert / cast the INT to VARCHAR:

CONVERT(TYPE, VALUE)

in this case ( my case ), this was used:

	PRINT 'New revision updated for post id ' + CONVERT(VARCHAR(20), @intPID) + '!'

Good luck

  • Share/Bookmark